ARM: PCI: implement generic PCI host controller
Subsystems (6)
v3 cover ARM: PCI: implement generic PCI host controller
Hi,
This is version 3 of the patches previously posted here:
v1: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/229679.html
v2: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/232213.html
Changes since v2 include:
- Tightening up of the DT requirements:
* Must have at least a non-prefetchable memory region
* "reg" property now defines a base and size for config space
* bus-range property supported and used in conjunction with "reg"
* device_type must be "pci"
- Fixed bus mapping so we don't sleep in atomic
- Updated compatible strings and file names to get rid of "arm"
- Added a really dumb I/O space allocator
- Moved a bunch of ->probe() into ->setup(). Note that I've not included Arnd's patch to propagate ->setup() failures back to ->probe(), so despite the use of devm_* to manage resource allocations, I still have explicit cleanup code on the failure paths.
All feedback welcome.
Will
Will Deacon (3):
ARM: mach-virt: allow PCI support to be selected
ARM: bios32: use pci_enable_resource to enable PCI resources
PCI: ARM: add support for generic PCI host controller
.../devicetree/bindings/pci/host-generic-pci.txt | 88 +++++ arch/arm/kernel/bios32.c | 37 +- arch/arm/mach-virt/Kconfig | 1 + drivers/pci/host/Kconfig | 7 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pci-host-generic.c | 381 +++++++++++++++++++++ 6 files changed, 481 insertions(+), 34 deletions(-) create mode 100644 Documentation/devicetree/bindings/pci/host-generic-pci.txt create mode 100644 drivers/pci/host/pci-host-generic.c
Signature · 1 line
1.8.2.2
PATCH v3 1/3 ARM: mach-virt: allow PCI support to be selected
mach-virt can make use of virtio-pci devices, which requires the guest kernel to have PCI support selected.
This patch selects CONFIG_MIGHT_HAVE_PCI when CONFIG_ARCH_VIRT=y.
--- arch/arm/mach-virt/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-virt/Kconfig +1 -0
@@ -8,3 +8,4 @@ config ARCH_VIRT select CPU_V7 select SPARSE_IRQ select USE_OF + select MIGHT_HAVE_PCI
Signature · 1 line
1.8.2.2
PATCH v3 2/3 ARM: bios32: use pci_enable_resource to enable PCI resources
In reply to Will DeaconThis patch moves bios32 over to using the generic code for enabling PCI resources. Since the core code takes care of bridge resources too, we can also drop the explicit IO and MEMORY enabling for them in the arch code.
A side-effect of this change is that we no longer explicitly enable devices when running in PCI_PROBE_ONLY mode. This stays closer to the meaning of the option and prevents us from trying to enable devices without any assigned resources (the core code refuses to enable resources without parents).
--- arch/arm/kernel/bios32.c | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-)
arch/arm/kernel/bios32.c +3 -34
@@ -608,41 +608,10 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,*/ int pcibios_enable_device (struct pci_dev *dev,int mask) { -u16 cmd, old_cmd; -int idx; -struct resource *r; - -pci_read_config_word (dev,PCI_COMMAND , &cmd); - old_cmd = cmd; -for (idx =0 ; idx <6 ; idx++) { -/* Only set up the requested stuff */ -if (!(mask & (1 << idx))) -continue ; - - r = dev->resource + idx; -if (!r->start && r->end) { -printk (KERN_ERR "PCI: Device %s not available because" -" of resource collisions\n" ,pci_name (dev)); -return -EINVAL ; - } -if (r->flags &IORESOURCE_IO ) - cmd |=PCI_COMMAND_IO ; -if (r->flags &IORESOURCE_MEM ) - cmd |=PCI_COMMAND_MEMORY ; - } +if (pci_has_flag (PCI_PROBE_ONLY )) +return 0 ; -/* -* Bridges (eg, cardbus bridges) need to be fully enabled -*/ -if ((dev->class >>16 ) ==PCI_BASE_CLASS_BRIDGE ) - cmd |=PCI_COMMAND_IO |PCI_COMMAND_MEMORY ; - -if (cmd != old_cmd) { -printk ("PCI: enabling device %s (%04x -> %04x)\n" , -pci_name (dev), old_cmd, cmd); -pci_write_config_word (dev,PCI_COMMAND , cmd); - } -return 0 ; +return pci_enable_resources (dev, mask); } int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
Signature · 1 line
1.8.2.2
PATCH v3 2/3 ARM: bios32: use pci_enable_resource to enable PCI resources
Quoted 11 lines · Will Deacon
This patch moves bios32 over to using the generic code for enabling PCI resources. Since the core code takes care of bridge resources too, we can also drop the explicit IO and MEMORY enabling for them in the arch code.
A side-effect of this change is that we no longer explicitly enable devices when running in
PCI_PROBE_ONLYmode. This stays closer to the meaning of the option and prevents us from trying to enable devices without any assigned resources (the core code refuses to enable resources without parents).
Quoted 3 lines
Tested-by Jason Gunthorpe <[email protected]>Tested-by Jingoo Han <[email protected]>Signed-off-by Will Deacon <[email protected]>
Tested acceptably fine here with crudbus-from-hell.
Signature · 3 lines
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad. Estimate before purchase was "up to 13.2Mbit".
PATCH v3 2/3 ARM: bios32: use pci_enable_resource to enable PCI resources
Quoted 12 lines · Russell King - ARM Linux
Quoted 11 lines · Will Deacon
This patch moves bios32 over to using the generic code for enabling PCI resources. Since the core code takes care of bridge resources too, we can also drop the explicit IO and MEMORY enabling for them in the arch code.
A side-effect of this change is that we no longer explicitly enable devices when running in
PCI_PROBE_ONLYmode. This stays closer to the meaning of the option and prevents us from trying to enable devices without any assigned resources (the core code refuses to enable resources without parents).
Quoted 7 lines
Quoted 3 lines
Tested-by Jason Gunthorpe <[email protected]>Tested-by Jingoo Han <[email protected]>Signed-off-by Will Deacon <[email protected]>Tested acceptably fine here with crudbus-from-hell.
Tested-by Russell King <[email protected]>
Cheers Russell.
Will
PATCH v3 2/3 ARM: bios32: use pci_enable_resource to enable PCI resources
In reply to Russell King - ARM LinuxQuoted 12 lines · Russell King - ARM Linux
Quoted 11 lines · Will Deacon
This patch moves bios32 over to using the generic code for enabling PCI resources. Since the core code takes care of bridge resources too, we can also drop the explicit IO and MEMORY enabling for them in the arch code.
A side-effect of this change is that we no longer explicitly enable devices when running in
PCI_PROBE_ONLYmode. This stays closer to the meaning of the option and prevents us from trying to enable devices without any assigned resources (the core code refuses to enable resources without parents).
Quoted 7 lines
Quoted 3 lines
Tested-by Jason Gunthorpe <[email protected]>Tested-by Jingoo Han <[email protected]>Signed-off-by Will Deacon <[email protected]>Tested acceptably fine here with crudbus-from-hell.
Tested-by Russell King <[email protected]>
Damn, I just found a problem with this patch when PCI_PROBE_ONLY is set.
The problem is that bios32.c won't create a resource hierarchy for the firmware-initialised resources, so we have a bunch of orphaned resources that we can't pass to pci_enable_resources (since it checks r->parent).
This means that, unless firmware *enables* all of the resources, Linux won't be able to enable them. I think this is stronger than simply not re-assigning devices like the PCI_PROBE_ONLY flag intends.
I can see two solutions:
(1) Just drop this patch and stick with the old code (which doesn't check r->parent). The downside is we still don't have any resource hierarchy, so /proc/iomem doesn't contain bus information.
(2) Walk over the bus claiming the resources that we find. Patch below.
Any thoughts?
Will
--->8
commit 802062290eee961362d3090a50cf851412a63314
Author: Will Deacon <[email protected]> Date: Wed Feb 19 23:29:30 2014 +0000
ARM: bios32: claim firmware-initialised resources when PCI_PROBE_ONLY
When initialising a PCI bus with the PCI_PROBE_ONLY flag set, we don't (re-)assign any firmware-initialised resources, leading to an incomplete resource hierarchy and devices with orphaned resources.
If we try to enable these orphaned resources using pci_enable_resources, we will get back -EINVAL since a valid ->parent pointer is required. Consequently, pcibios_enable_device doesn't attempt to enable devices when PCI_PROBE_ONLY is set. This has the unfortunate effect of requiring the firmware to *enable* all of the devices!
This patch fixes the problem by building up a resource hierarchy from the firmware-initialised resources when PCI_PROBE_ONLY is set.
arch/arm/kernel/bios32.c +31 -3
@@ -514,6 +514,35 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, } } +static void pcibios_claim_one_bus (struct pci_bus *bus) +{ +struct pci_dev *dev; +struct pci_bus *child_bus; + +list_for_each_entry (dev, &bus->devices, bus_list) { +int i; + +for (i =0 ; i <PCI_NUM_RESOURCES ; i++) { +struct resource *r = &dev->resource[i]; + +if (r->parent || !r->start || !r->flags) +continue ; + +pr_debug ("PCI: Claiming %s: " +"Resource %d: %016llx..%016llx [%x]\n" , +pci_name (dev), i, + (unsigned long long )r->start, + (unsigned long long )r->end, + (unsigned int )r->flags); + +pci_claim_resource (dev, i); + } + } + +list_for_each_entry (child_bus, &bus->children, node) +pcibios_claim_one_bus (child_bus); +} +void pci_common_init_dev (struct device *parent,struct hw_pci *hw) {struct pci_sys_data *sys;
@@ -541,6 +570,8 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)* Assign resources. */ pci_bus_assign_resources (bus); + }else { +pcibios_claim_one_bus (bus); }/*
@@ -608,9 +639,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,*/ int pcibios_enable_device (struct pci_dev *dev,int mask) { -if (pci_has_flag (PCI_PROBE_ONLY )) -return 0 ; -return pci_enable_resources (dev, mask); }
Bjorn Helgaas
maintainerPATCH v3 2/3 ARM: bios32: use pci_enable_resource to enable PCI resources
Quoted 23 lines · Will Deacon
Quoted 12 lines · Russell King - ARM Linux
Quoted 11 lines · Will Deacon
This patch moves bios32 over to using the generic code for enabling PCI resources. Since the core code takes care of bridge resources too, we can also drop the explicit IO and MEMORY enabling for them in the arch code.
A side-effect of this change is that we no longer explicitly enable devices when running in
PCI_PROBE_ONLYmode. This stays closer to the meaning of the option and prevents us from trying to enable devices without any assigned resources (the core code refuses to enable resources without parents).Quoted 7 lines
Quoted 3 lines
Tested-by Jason Gunthorpe <[email protected]>Tested-by Jingoo Han <[email protected]>Signed-off-by Will Deacon <[email protected]>Tested acceptably fine here with crudbus-from-hell.
Tested-by Russell King <[email protected]>Damn, I just found a problem with this patch when
PCI_PROBE_ONLYis set.
Quoted 7 lines
The problem is that
bios32.cwon't create a resource hierarchy for the firmware-initialised resources, so we have a bunch of orphaned resources that we can't pass topci_enable_resources(since it checksr->parent).This means that, unless firmware *enables* all of the resources, Linux won't be able to enable them. I think this is stronger than simply not re-assigning devices like the
PCI_PROBE_ONLYflag intends.
By "firmware enabling resources," do you mean firmware assigning addresses in the BARs and turning on the PCI_COMMAND_MEMORY (or _IO) bits?
I'd like to make the generic code ignore BAR values if PCI_COMMAND_MEMORY (or _IO) is cleared. When those bits are cleared, I don't think there's a good way to determine whether the address in a BAR is valid.
It sounds like you want PCI_PROBE_ONLY to mean that we should try to use the existing BAR contents even if PCI_COMMAND_MEMORY is cleared. Is that right? Maybe we could try to use the existing BAR address if we can actually claim it, i.e., if it is inside one of the upstream bridge windows.
Quoted 9 lines
I can see two solutions:
(1) Just drop this patch and stick with the old code (which doesn't check
r->parent). The downside is we still don't have any resource hierarchy, so/proc/iomemdoesn't contain bus information.(2) Walk over the bus claiming the resources that we find. Patch below.
Any thoughts?
I really want to nuke all the arch-specific "claim resource" code because it isn't arch-dependent.
Quoted 80 lines
commit
802062290eee961362d3090a50cf851412a63314Author: Will Deacon <[email protected]> Date: Wed Feb 19 23:29:30 2014 +0000ARM: bios32: claim firmware-initialised resources when
PCI_PROBE_ONLYWhen initialising a PCI bus with the
PCI_PROBE_ONLYflag set, we don't (re-)assign any firmware-initialised resources, leading to an incomplete resource hierarchy and devices with orphaned resources.If we try to enable these orphaned resources using
pci_enable_resources, we will get back-EINVALsince a valid ->parent pointer is required. Consequently,pcibios_enable_devicedoesn't attempt to enable devices whenPCI_PROBE_ONLYis set. This has the unfortunate effect of requiring the firmware to *enable* all of the devices!This patch fixes the problem by building up a resource hierarchy from the firmware-initialised resources when
PCI_PROBE_ONLYis set.Signed-off-by Will Deacon <[email protected]>arch/arm/kernel/bios32.c +31
-3@@ -514,6 +514,35 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, } } +static void pcibios_claim_one_bus (struct pci_bus *bus) +{ +struct pci_dev *dev; +struct pci_bus *child_bus; + +list_for_each_entry (dev, &bus->devices, bus_list) { +int i; + +for (i =0 ; i <PCI_NUM_RESOURCES ; i++) { +struct resource *r = &dev->resource[i]; + +if (r->parent || !r->start || !r->flags) +continue ; + +pr_debug ("PCI: Claiming %s: " +"Resource %d: %016llx..%016llx [%x]\n" , +pci_name (dev), i, + (unsigned long long )r->start, + (unsigned long long )r->end, + (unsigned int )r->flags); + +pci_claim_resource (dev, i); + } + } + +list_for_each_entry (child_bus, &bus->children, node) +pcibios_claim_one_bus (child_bus); +} +void pci_common_init_dev (struct device *parent,struct hw_pci *hw) {struct pci_sys_data *sys;@@ -541,6 +570,8 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)* Assign resources. */ pci_bus_assign_resources (bus); + }else { +pcibios_claim_one_bus (bus); }/* @@ -608,9 +639,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,*/ int pcibios_enable_device (struct pci_dev *dev,int mask) { -if (pci_has_flag (PCI_PROBE_ONLY )) -return 0 ; -return pci_enable_resources (dev, mask); }
PATCH v3 2/3 ARM: bios32: use pci_enable_resource to enable PCI resources
Quoted 10 lines · Bjorn Helgaas
Quoted 9 lines
Damn, I just found a problem with this patch when
PCI_PROBE_ONLYis set.The problem is that
bios32.cwon't create a resource hierarchy for the firmware-initialised resources, so we have a bunch of orphaned resources that we can't pass topci_enable_resources(since it checksr->parent).This means that, unless firmware *enables* all of the resources, Linux won't be able to enable them. I think this is stronger than simply not re-assigning devices like the
PCI_PROBE_ONLYflag intends.
Quoted 8 lines
By "firmware enabling resources," do you mean firmware assigning addresses in the BARs and turning on the
PCI_COMMAND_MEMORY(or_IO) bits?I'd like to make the generic code ignore BAR values if
PCI_COMMAND_MEMORY(or_IO) is cleared. When those bits are cleared, I don't think there's a good way to determine whether the address in a BAR is valid.
I think this is pretty smart, PROBE_ONLY really should mean 'everything is perfect, do not touch it' and if the device isn't enabled, well.. It isn't enabled, the firmware should have done it.
Will, this if for kvmtool right? Keeping the patch as is and instead changing kvmtool to enable the devices seems like a good option?
Alternatively, there are OF ways to communicate the BAR assignment through the DT. I actually have no idea how this information is used by the core code, but it might let you avoid the probe_only by specifying the desired BAR value through the DT.
Regards,
Jason
PATCH v3 2/3 ARM: bios32: use pci_enable_resource to enable PCI resources
Hi Jason, Bjorn,
Thanks for the comments.
Quoted 15 lines · Jason Gunthorpe
Quoted 14 lines · Bjorn Helgaas
Quoted 9 lines
Damn, I just found a problem with this patch when
PCI_PROBE_ONLYis set.The problem is that
bios32.cwon't create a resource hierarchy for the firmware-initialised resources, so we have a bunch of orphaned resources that we can't pass topci_enable_resources(since it checksr->parent).This means that, unless firmware *enables* all of the resources, Linux won't be able to enable them. I think this is stronger than simply not re-assigning devices like the
PCI_PROBE_ONLYflag intends.By "firmware enabling resources," do you mean firmware assigning addresses in the BARs and turning on the
PCI_COMMAND_MEMORY(or_IO) bits?
Quoted 8 lines
Quoted 4 lines
I'd like to make the generic code ignore BAR values if
PCI_COMMAND_MEMORY(or_IO) is cleared. When those bits are cleared, I don't think there's a good way to determine whether the address in a BAR is valid.I think this is pretty smart,
PROBE_ONLYreally should mean 'everything is perfect, do not touch it' and if the device isn't enabled, well.. It isn't enabled, the firmware should have done it.
Yes, that's one (sane) interpretation of the PROBE_ONLY flag and I'm happy to run with it if we all agree. We'll need some extra code paths to assign disabled resources when PROBE_ONLY is passed, but that can come later.
Quoted 2 lines
Will, this if for kvmtool right? Keeping the patch as is and instead changing kvmtool to enable the devices seems like a good option?
Sure, I can do that easily enough. I just wanted to make sure that we agree on PROBE_ONLY before I start hacking kvmtool. I'll drop this additional patch.
Cheers,
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
In reply to Will DeaconThis patch adds support for a generic PCI host controller, such as a firmware-initialised device with static windows or an emulation by something such as kvmtool.
The controller itself has no configuration registers and has its address spaces described entirely by the device-tree (using the bindings from ePAPR). Both CAM and ECAM are supported for Config Space accesses.
Corresponding documentation is added for the DT binding.
--- .../devicetree/bindings/pci/host-generic-pci.txt | 88 +++++ drivers/pci/host/Kconfig | 7 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pci-host-generic.c | 381 +++++++++++++++++++++ 4 files changed, 477 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/host-generic-pci.txt create mode 100644 drivers/pci/host/pci-host-generic.c
Documentation/devicetree/bindings/pci/host-generic-pci.txt new file +88 -0
@@ -0,0 +1,88 @@ +* Generic PCI host controller + +Firmware-initialised PCI host controllers and PCI emulations, such as the +virtio-pci implementations found in kvmtool and other para-virtualised +systems, do not require driver support for complexities such as regulator +and clock management. In fact, the controller may not even require the +configuration of a control interface by the operating system, instead +presenting a set of fixed windows describing a subset of IO, Memory and +Configuration Spaces. + +Such a controller can be described purely in terms of the standardized device +tree bindings communicated in pci.txt: + +- compatible : Must be "pci-host-cam-generic" or "pci-host-ecam-generic" + depending on the layout of configuration space (CAM vs + ECAM respectively). + +- device_type : Must be "pci". + +- ranges : As described in IEEE Std 1275-1994, but must provide + at least a definition of non-prefetchable memory. One + or both of prefetchable Memory and IO Space may also + be provided. + +- bus-range : Optional property (also described in IEEE Std 1275-1994) + to indicate the range of bus numbers for this controller. + If absent, defaults to <0 255> (i.e. all buses). + +- #address-cells : Must be 3. + +- #size-cells : Must be 2. + +- reg : The Configuration Space base address and size, as accessed + from the parent bus. + +Configuration Space is assumed to be memory-mapped (as opposed to being +accessed via an ioport) and laid out with a direct correspondence to the +geography of a PCI bus address by concatenating the various components to +form an offset. + +For CAM, this 24-bit offset is: + + cfg_offset(bus, device, function, register) = + bus << 16 | device << 11 | function << 8 | register + +Whilst ECAM extends this by 4 bits to accomodate 4k of function space: + + cfg_offset(bus, device, function, register) = + bus << 20 | device << 15 | function << 12 | register + +Interrupt mapping is exactly as described in `Open Firmware Recommended +Practice: Interrupt Mapping' and requires the following properties: + +- #interrupt-cells : Must be 1 + +- interrupt-map : <see aforementioned specification> + +- interrupt-map-mask : <see aforementioned specification> + + +Example: + +pci { + compatible = "pci-host-cam-generic" + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0x1>; + + // CPU_PHYSICAL(2) SIZE(2) + reg = <0x0 0x40000000 0x0 0x1000000>; + + // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) + ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>, + <0x2000000 0x0 0x41000000 0x0 0x41000000 0x0 0x3f000000>; + + + #interrupt-cells = <0x1>; + + // PCI_DEVICE(3) INT#(1) CONTROLLER(PHANDLE) CONTROLLER_DATA(3) + interrupt-map = < 0x0 0x0 0x0 0x1 &gic 0x0 0x4 0x1 + 0x800 0x0 0x0 0x1 &gic 0x0 0x5 0x1 + 0x1000 0x0 0x0 0x1 &gic 0x0 0x6 0x1 + 0x1800 0x0 0x0 0x1 &gic 0x0 0x7 0x1>; + + // PCI_DEVICE(3) INT#(1) + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; +}
drivers/pci/host/Kconfig +7 -0
@@ -33,4 +33,11 @@ config PCI_RCAR_GEN2 There are 3 internal PCI controllers available with a single built-in EHCI/OHCI host controller present on each one. +config PCI_HOST_GENERIC + bool "Generic PCI host controller" + depends on ARM && OF + help + Say Y here if you want to support a simple generic PCI host + controller, such as the one emulated by kvmtool. + endmenu
drivers/pci/host/Makefile +1 -0
@@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o +obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
drivers/pci/host/pci-host-generic.c new file +381 -0
381 lines not on this page · raw message
Signature · 1 line
1.8.2.2
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 9 lines · On Tuesday 18 February 2014 12:20:43 Will Deacon wrote:
drivers/pci/host/pci-host-generic.c new file +9
-0+static int gen_pci_alloc_io_offset (u32 sz,resource_size_t *offset) +{ + static DECLARE_BITMAP(io_map, (IO_SPACE_LIMIT + 1) / SZ_64K); +int idx, num_wins; + +if (sz >SZ_64K ) +return -ENOSPC ; + + num_wins = (IO_SPACE_LIMIT +1 ) /SZ_64K ;
drivers/pci/host/pci-host-generic.c line 177
Quoted 10 lines
drivers/pci/host/pci-host-generic.c new file +10
-0+ idx =0 ; +do { + idx =find_next_zero_bit (io_map, num_wins, idx); +if (idx == num_wins) +return -ENOSPC ; + }while (test_and_set_bit (idx, io_map)); + + *offset = idx *SZ_64K ; +return 0 ; +}
Sicne you're always starting the search at 0 and you never free the map, this is essentially the same as remembering the last number that was used and using the next one, right?
You should also pass the rang->pci_addr here to calculate the offset in case the pci_addr is not zero.
drivers/pci/host/pci-host-generic.c line 304
Quoted 8 lines
drivers/pci/host/pci-host-generic.c new file +8
-0+/* Register our I/O and Memory resources */ + res_valid =0 ; +list_for_each_entry (win, &pci->host.windows, list) { +struct resource *parent; + +if (resource_type (win->res) ==IORESOURCE_IO ) { + parent = &ioport_resource; + err =pci_ioremap_io (win->offset, win->res->start);
and consequently pass the pci_addr rather than the offset here. How about moving the pci_ioremap_io() call into gen_pci_alloc_io_offset()?
Arnd
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 17 lines · Arnd Bergmann
Quoted 15 lines · On Tuesday 18 February 2014 12:20:43 Will Deacon wrote:
drivers/pci/host/pci-host-generic.c new file +15
-0+static int gen_pci_alloc_io_offset (u32 sz,resource_size_t *offset) +{ + static DECLARE_BITMAP(io_map, (IO_SPACE_LIMIT + 1) / SZ_64K); +int idx, num_wins; + +if (sz >SZ_64K ) +return -ENOSPC ; + + num_wins = (IO_SPACE_LIMIT +1 ) /SZ_64K ; + idx =0 ; +do { + idx =find_next_zero_bit (io_map, num_wins, idx); +if (idx == num_wins) +return -ENOSPC ; + }while (test_and_set_bit (idx, io_map));
Quoted 8 lines
drivers/pci/host/pci-host-generic.c line 177
Quoted 4 lines
drivers/pci/host/pci-host-generic.c new file +4
-0+ + *offset = idx *SZ_64K ; +return 0 ; +}Sicne you're always starting the search at 0 and you never free the map, this is essentially the same as remembering the last number that was used and using the next one, right?
Yes, I can implement that easily enough. I was wondering if there was a case for allowing windows to be freed, but it doesn't feel especially compelling.
Quoted 14 lines
You should also pass the
rang->pci_addrhere to calculate the offset in case thepci_addris not zero.drivers/pci/host/pci-host-generic.c line 304
Quoted 8 lines
drivers/pci/host/pci-host-generic.c new file +8
-0+/* Register our I/O and Memory resources */ + res_valid =0 ; +list_for_each_entry (win, &pci->host.windows, list) { +struct resource *parent; + +if (resource_type (win->res) ==IORESOURCE_IO ) { + parent = &ioport_resource; + err =pci_ioremap_io (win->offset, win->res->start);and consequently pass the
pci_addrrather than the offset here. How about moving thepci_ioremap_io()call intogen_pci_alloc_io_offset()?
Can do.
Thanks for the feedback.
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 13 lines · Will Deacon
Quoted 12 lines · Arnd Bergmann
drivers/pci/host/pci-host-generic.c line 304
Quoted 8 lines · On Tuesday 18 February 2014 12:20:43 Will Deacon wrote:
drivers/pci/host/pci-host-generic.c new file +8
-0+/* Register our I/O and Memory resources */ + res_valid =0 ; +list_for_each_entry (win, &pci->host.windows, list) { +struct resource *parent; + +if (resource_type (win->res) ==IORESOURCE_IO ) { + parent = &ioport_resource; + err =pci_ioremap_io (win->offset, win->res->start);and consequently pass the
pci_addrrather than the offset here. How about moving thepci_ioremap_io()call intogen_pci_alloc_io_offset()?
I've probably just confused myself, but passing the pci_addr to pci_ioremap_io doesn't make sense to me. My understanding is that:
cpu = bus + offset
In the case of I/O, the offset is really:
offset = (PCI_IO_VIRT_BASE - bus) + window
where window is determined by the simple allocator I wrote.
Now, the __io macro takes care of PCI_IO_VIRT_BASE so we don't actually care about that when adding the PCI I/O resources, instead we'll just pass:
offset = window - bus
and then pci_ioremap_io will just want the window offset, since that's added directly on to PCI_IO_VIRT_BASE for the ioremap_page_range.
If I call pci_ioremap_io(range->pci_addr, ...) then I'm going to trip a BUG_ON unless the pci_addr is within IO_SPACE_LIMIT.
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 12 lines · On Wednesday 19 February 2014 11:07:19 Will Deacon wrote:
Quoted 11 lines · Will Deacon
Quoted 10 lines · Arnd Bergmann
Quoted 8 lines · On Tuesday 18 February 2014 12:20:43 Will Deacon wrote:
+ /* Register our I/O and Memory resources */
+res_valid= 0;
+list_for_each_entry(win, &pci->host.windows, list){drivers/pci/host/pci-host-generic.c new file +5
-0+struct resource *parent; + +if (resource_type (win->res) ==IORESOURCE_IO ) { + parent = &ioport_resource; + err =pci_ioremap_io (win->offset, win->res->start);
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
and consequently pass the
pci_addrrather than the offset here. How about moving thepci_ioremap_io()call intogen_pci_alloc_io_offset()?I've probably just confused myself, but passing the
pci_addrtopci_ioremap_iodoesn't make sense to me.
I think the confusion is that there are two different things we call offset here. The calculation of the offset you pass into pci_ioremap_io() is correct AFAICT now, but it's not what you are supposed to pass into pci_add_resource_offset() or what we normally put into pci_host_bridge_window->offset.
Quoted 3 lines
My understanding is that:
cpu = bus + offset
Right. This would be the case for mem_offset.
Quoted 3 lines
In the case of I/O, the offset is really:
offset = (
PCI_IO_VIRT_BASE- bus) + window
I can't seem to make sense of this calculation. PCI_IO_VIRT_BASE is a pointer to the start of the virtual window. You can add offsets to the pointer, but subtracting a number from it is not a well-defined operation.
Quoted 1 line
where window is determined by the simple allocator I wrote.
And your allocator calls it offset, which is what confused me.
Quoted 4 lines
Now, the
__iomacro takes care ofPCI_IO_VIRT_BASEso we don't actually care about that when adding the PCI I/O resources, instead we'll just pass:offset = window - bus
Yes, this would be the io_offset that you pass into pci_add_resource_offset().
Quoted 2 lines
and then
pci_ioremap_iowill just want the window offset, since that's added directly on toPCI_IO_VIRT_BASEfor theioremap_page_range.
Yes.
Quoted 2 lines
If I call
pci_ioremap_io(range->pci_addr, ...)then I'm going to trip aBUG_ONunless thepci_addris withinIO_SPACE_LIMIT.
range->pci_addr is what you call 'bus' above. Since you want 'window', you have to pass 'bus'+'offset', or 'range->pci_addr + io_offset'. Normally, one of the two would be zero, while the other is equal to 'window'.
Arnd
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Hi Arnd,
Quoted 39 lines · Arnd Bergmann
Quoted 2 lines · On Wednesday 19 February 2014 11:07:19 Will Deacon wrote:
I've probably just confused myself, but passing the
pci_addrtopci_ioremap_iodoesn't make sense to me.I think the confusion is that there are two different things we call offset here. The calculation of the offset you pass into
pci_ioremap_io()is correct AFAICT now, but it's not what you are supposed to pass intopci_add_resource_offset()or what we normally put intopci_host_bridge_window->offset.Quoted 3 lines
My understanding is that:
cpu = bus + offset
Right. This would be the case for
mem_offset.Quoted 3 lines
In the case of I/O, the offset is really:
offset = (
PCI_IO_VIRT_BASE- bus) + windowI can't seem to make sense of this calculation.
PCI_IO_VIRT_BASEis a pointer to the start of the virtual window. You can add offsets to the pointer, but subtracting a number from it is not a well-defined operation.Quoted 1 line
where window is determined by the simple allocator I wrote.
And your allocator calls it offset, which is what confused me.
Quoted 4 lines
Now, the
__iomacro takes care ofPCI_IO_VIRT_BASEso we don't actually care about that when adding the PCI I/O resources, instead we'll just pass:offset = window - bus
Yes, this would be the
io_offsetthat you pass intopci_add_resource_offset().Quoted 2 lines
and then
pci_ioremap_iowill just want the window offset, since that's added directly on toPCI_IO_VIRT_BASEfor theioremap_page_range.
Quoted 8 lines
Yes.
Quoted 2 lines
If I call
pci_ioremap_io(range->pci_addr, ...)then I'm going to trip aBUG_ONunless thepci_addris withinIO_SPACE_LIMIT.
range->pci_addris what you call 'bus' above. Since you want 'window', you have to pass 'bus'+'offset', or 'range->pci_addr+io_offset'. Normally, one of the two would be zero, while the other is equal to 'window'.
Good, so we're in agreement! The issue indeed seems to be that there are multiple names for the same things :)
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
In reply to Will DeaconDocumentation/devicetree/bindings/pci/host-generic-pci.txt line 74
Quoted 3 lines · Will Deacon
Documentation/devicetree/bindings/pci/host-generic-pci.txt new file +3
-0+ + // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) + ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>,
^^^^^^^^^^^^^^
This probably shouldn't be 0 in the example, nor in your kvm tool output. For example purposes any value will do.
Regards,
Jason
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 8 lines · Jason Gunthorpe
Documentation/devicetree/bindings/pci/host-generic-pci.txt line 74
Quoted 3 lines · Will Deacon
Documentation/devicetree/bindings/pci/host-generic-pci.txt new file +3
-0+ + // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) + ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>,^^^^^^^^^^^^^^This probably shouldn't be 0 in the example, nor in your kvm tool output. For example purposes any value will do.
Hmm, so kvmtool actually provides a PC ioport at 0x0, which is handy since there's an 8250 down there. That means we have:
0x0 - 0x6200 : Weird PC stuff0x6200 - 0x10000 : PCI IO space
Should I just change everything to be offset by 0x6200?
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 10 lines · On Tuesday 18 February 2014 18:44:20 Will Deacon wrote:
Quoted 8 lines · Jason Gunthorpe
Documentation/devicetree/bindings/pci/host-generic-pci.txt line 74
Quoted 3 lines · Will Deacon
Documentation/devicetree/bindings/pci/host-generic-pci.txt new file +3
-0+ + // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) + ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>,^^^^^^^^^^^^^^This probably shouldn't be 0 in the example, nor in your kvm tool output. For example purposes any value will do.
Quoted 7 lines
Hmm, so kvmtool actually provides a PC ioport at
0x0, which is handy since there's an 8250 down there. That means we have:
0x0-0x6200: Weird PC stuff0x6200-0x10000: PCI IO spaceShould I just change everything to be offset by
0x6200?
Do you have a list of the stuff in there?
If that is actually port I/O, leaving it in there may be best, but I agree the example should be changed.
Arnd
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 14 lines · Arnd Bergmann
Quoted 13 lines · On Tuesday 18 February 2014 18:44:20 Will Deacon wrote:
Quoted 8 lines · Jason Gunthorpe
Documentation/devicetree/bindings/pci/host-generic-pci.txt line 74
Quoted 3 lines · Will Deacon
Documentation/devicetree/bindings/pci/host-generic-pci.txt new file +3
-0+ + // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) + ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>,^^^^^^^^^^^^^^This probably shouldn't be 0 in the example, nor in your kvm tool output. For example purposes any value will do.
Hmm, so kvmtool actually provides a PC ioport at
0x0, which is handy since there's an 8250 down there. That means we have:
Quoted 6 lines
Quoted 4 lines
0x0-0x6200: Weird PC stuff0x6200-0x10000: PCI IO spaceShould I just change everything to be offset by
0x6200?Do you have a list of the stuff in there?
kvmtool provides an i8042, pci-shmem, an rtc, 8250 and vesa at the usual PC offsets. On ARM, I regularly use the 8250 (there are even DT bindings for it) and MarcZ got the rtc working for fun. Not tried the others though.
Quoted 2 lines
If that is actually port I/O, leaving it in there may be best, but I agree the example should be changed.
Yup, it is port I/O. I'll make something up for the example.
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 4 lines · On Tuesday 18 February 2014 18:51:50 Will Deacon wrote:
kvmtool provides an i8042, pci-shmem, an rtc, 8250 and vesa at the usual PC offsets. On ARM, I regularly use the 8250 (there are even DT bindings for it) and MarcZ got the rtc working for fun. Not tried the others though.
Ah, interesting. But which ones are between 0x1000-0x6200? The ones you list should all be in the ISA range between 0x0-0xfff as far as I can tell, which we keep clear of by setting PCIBIOS_MIN_IO to 0x1000.
Arnd
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 10 lines · Arnd Bergmann
Quoted 4 lines · On Tuesday 18 February 2014 18:51:50 Will Deacon wrote:
kvmtool provides an i8042, pci-shmem, an rtc, 8250 and vesa at the usual PC offsets. On ARM, I regularly use the 8250 (there are even DT bindings for it) and MarcZ got the rtc working for fun. Not tried the others though.
Ah, interesting. But which ones are between 0x1000-0x6200? The ones you list should all be in the ISA range between 0x0-0xfff as far as I can tell, which we keep clear of by setting
PCIBIOS_MIN_IOto0x1000.
I think there's just a hole between 0x1000 - 0x6200.
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
In reply to Will DeaconQuoted 10 lines · Will Deacon
Quoted 8 lines · Jason Gunthorpe
Documentation/devicetree/bindings/pci/host-generic-pci.txt line 74
Quoted 3 lines · Will Deacon
Documentation/devicetree/bindings/pci/host-generic-pci.txt new file +3
-0+ + // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) + ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>,^^^^^^^^^^^^^^This probably shouldn't be 0 in the example, nor in your kvm tool output. For example purposes any value will do.
Quoted 7 lines
Hmm, so kvmtool actually provides a PC ioport at
0x0, which is handy since there's an 8250 down there. That means we have:
0x0-0x6200: Weird PC stuff0x6200-0x10000: PCI IO spaceShould I just change everything to be offset by
0x6200?
Just to be clear, kvm has reserved the first 64k of physical address space for this IO window? The 0 is fine then, but it isn't typical of real hardware.
Regarding the 0x6200.. There are two conflicting issues there :(
- You really don't want to let the PCI core assign resources to that range, it probably won't work.
- You probably need that range mapped into the ARM IO window, and the PCI driver is the thing doing that
The PCI core already has a black out for low IO ports, I think it already covers the usual PC suspects so you are probably fine with what you have for KVM.
Jason
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 14 lines · Jason Gunthorpe
Quoted 13 lines · Will Deacon
Quoted 8 lines · Jason Gunthorpe
Documentation/devicetree/bindings/pci/host-generic-pci.txt line 74
Quoted 3 lines · Will Deacon
Documentation/devicetree/bindings/pci/host-generic-pci.txt new file +3
-0+ + // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) + ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>,^^^^^^^^^^^^^^This probably shouldn't be 0 in the example, nor in your kvm tool output. For example purposes any value will do.
Hmm, so kvmtool actually provides a PC ioport at
0x0, which is handy since there's an 8250 down there. That means we have:
Quoted 8 lines
Quoted 4 lines
0x0-0x6200: Weird PC stuff0x6200-0x10000: PCI IO spaceShould I just change everything to be offset by
0x6200?Just to be clear, kvm has reserved the first 64k of physical address space for this IO window? The 0 is fine then, but it isn't typical of real hardware.
Yup, that's spot on.
Quoted 3 lines
Regarding the
0x6200.. There are two conflicting issues there :(
- You really don't want to let the PCI core assign resources to that range, it probably won't work.
Right, with kvmtool we don't support resource assignment (the BARs are fixed) so everything is PCI_PROBE_ONLY.
Quoted 6 lines
- You probably need that range mapped into the ARM IO window, and the PCI driver is the thing doing that
The PCI core already has a black out for low IO ports, I think it already covers the usual PC suspects so you are probably fine with what you have for KVM.
Great, so I'll just update the example then. Thanks!
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 7 lines · On Tuesday 18 February 2014 19:09:29 Will Deacon wrote:
Quoted 4 lines
Regarding the
0x6200.. There are two conflicting issues there
- You really don't want to let the PCI core assign resources to that range, it probably won't work.Right, with kvmtool we don't support resource assignment (the BARs are fixed) so everything is
PCI_PROBE_ONLY.
Ok, I looked at the source now and can confirm:
* 0x0-0x1000 are used for lots of legacy ISA devices.
* PCI devices get assigned IO addresses in 0x400 steps starting at 0x6200.
* There are three PCI drivers doing this: VESA, PCI-SHMEM and virtio-pci.
Regarding the PCI_PROBE_ONLY flag, how do you set that? Should we have a standard DT property for that? On PowerPC we already specified "linux,pci-probe-only" and "linux,pci-assign-all-buses", which seems reasonable to use in architecture independent code as well.
Arnd
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 11 lines · Arnd Bergmann
Quoted 7 lines · On Tuesday 18 February 2014 19:09:29 Will Deacon wrote:
Quoted 4 lines
Regarding the
0x6200.. There are two conflicting issues there
- You really don't want to let the PCI core assign resources to that range, it probably won't work.Right, with kvmtool we don't support resource assignment (the BARs are fixed) so everything is
PCI_PROBE_ONLY.Ok, I looked at the source now and can confirm:
Quoted 8 lines
* 0x0-0x1000 are used for lots of legacy ISA devices.
* PCI devices get assigned IO addresses in0x400steps starting at0x6200.
* There are three PCI drivers doing this: VESA, PCI-SHMEM and virtio-pci.Regarding the
PCI_PROBE_ONLYflag, how do you set that? Should we have a standard DT property for that? On PowerPC we already specified "linux,pci-probe-only" and "linux,pci-assign-all-buses", which seems reasonable to use in architecture independent code as well.
For arch/arm/ it's done on the command line (pci=firmware) but yes, for the generic driver it sounds like a good idea to put this in the device-tree. I'll look at adding the ppc properties in the next version.
Cheers,
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 16 lines · Will Deacon
Quoted 15 lines · Arnd Bergmann
Quoted 7 lines · On Tuesday 18 February 2014 19:09:29 Will Deacon wrote:
Quoted 4 lines
Regarding the
0x6200.. There are two conflicting issues there
- You really don't want to let the PCI core assign resources to that range, it probably won't work.Right, with kvmtool we don't support resource assignment (the BARs are fixed) so everything is
PCI_PROBE_ONLY.Ok, I looked at the source now and can confirm:
* 0x0-0x1000 are used for lots of legacy ISA devices.
* PCI devices get assigned IO addresses in0x400steps starting at0x6200.
* There are three PCI drivers doing this: VESA, PCI-SHMEM and virtio-pci.
Quoted 8 lines
Quoted 4 lines
Regarding the
PCI_PROBE_ONLYflag, how do you set that? Should we have a standard DT property for that? On PowerPC we already specified "linux,pci-probe-only" and "linux,pci-assign-all-buses", which seems reasonable to use in architecture independent code as well.For
arch/arm/it's done on the command line (pci=firmware) but yes, for the generic driver it sounds like a good idea to put this in the device-tree. I'll look at adding the ppc properties in the next version.
Damn, I spoke too soon. PowerPC puts this information in the /chosen node, so it applies to all PCI host controllers in the system. That then maps nicely to pci_{add,clear}_flags which are global properties in Linux.
It sounds like this should really be per-controller. What do you think?
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 12 lines · On Tuesday 18 February 2014 19:57:32 Will Deacon wrote:
Quoted 10 lines · Will Deacon
Quoted 5 lines · Arnd Bergmann
On Tuesday 18 February 2014 19:09:29 Will Deacon wrote:
Regarding thePCI_PROBE_ONLYflag, how do you set that? Should we have a standard DT property for that? On PowerPC we already specified "linux,pci-probe-only" and "linux,pci-assign-all-buses", which seems reasonable to use in architecture independent code as well.For
arch/arm/it's done on the command line (pci=firmware) but yes, for the generic driver it sounds like a good idea to put this in the device-tree. I'll look at adding the ppc properties in the next version.
Quoted 5 lines
Damn, I spoke too soon. PowerPC puts this information in the /chosen node, so it applies to all PCI host controllers in the system. That then maps nicely to pci_{add,clear}_flags which are global properties in Linux.
It sounds like this should really be per-controller. What do you think?
I don't have a strong opinion either way. I think the reason for having it in the /chosen node is so that a second-stage boot loader can easily override it, which is not a concern for us. In particular, the properties are only used on rtas-pci, which means we access the config space to firmware runtime abstraction services rather than hardware registers.
Apparently the embedded powerpc platforms don't support these flags at all, which I also didn't notice at first.
Arnd
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 19 lines · Arnd Bergmann
Quoted 12 lines · On Tuesday 18 February 2014 19:57:32 Will Deacon wrote:
Quoted 10 lines · Will Deacon
Quoted 5 lines · Arnd Bergmann
On Tuesday 18 February 2014 19:09:29 Will Deacon wrote:
Regarding thePCI_PROBE_ONLYflag, how do you set that? Should we have a standard DT property for that? On PowerPC we already specified "linux,pci-probe-only" and "linux,pci-assign-all-buses", which seems reasonable to use in architecture independent code as well.For
arch/arm/it's done on the command line (pci=firmware) but yes, for the generic driver it sounds like a good idea to put this in the device-tree. I'll look at adding the ppc properties in the next version.Quoted 5 lines
Damn, I spoke too soon. PowerPC puts this information in the /chosen node, so it applies to all PCI host controllers in the system. That then maps nicely to pci_{add,clear}_flags which are global properties in Linux.
It sounds like this should really be per-controller. What do you think?
Quoted 8 lines
I don't have a strong opinion either way. I think the reason for having it in the /chosen node is so that a second-stage boot loader can easily override it, which is not a concern for us. In particular, the properties are only used on rtas-pci, which means we access the config space to firmware runtime abstraction services rather than hardware registers.
Apparently the embedded powerpc platforms don't support these flags at all, which I also didn't notice at first.
Even in the rtas case there's a:
#ifdef CONFIG_PPC32 /* Will be made generic soon */
for linux,pci-assign-all-buses. I think I'll just go for linux,pci-probe-only initially, especially as PCI_REASSIGN_ALL_BUS isn't actually used anywhere outside of arch/powerpc/.
Will
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
In reply to Will DeaconQuoted 10 lines · On Tuesday 18 February 2014 18:44:20 Will Deacon wrote:
Quoted 8 lines · Jason Gunthorpe
Review
Quoted 3 lines · Will Deacon
(quoted diff) +3
-0+ + // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) + ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>,^^^^^^^^^^^^^^This probably shouldn't be 0 in the example, nor in your kvm tool output. For example purposes any value will do.
Quoted 7 lines
Hmm, so kvmtool actually provides a PC ioport at
0x0, which is handy since there's an 8250 down there. That means we have:
0x0-0x6200: Weird PC stuff0x6200-0x10000: PCI IO spaceShould I just change everything to be offset by
0x6200?
Some more comments about this:
* After I looked at the kvmtool code some more, I think it would be nice to actually move the I/O space window to a nonzero location, e.g. between the PCI space and the AXI space. It's really confusing the way it is, and easy to introduce bugs if you have any code that accidentally relies on the numbers matching up. For all I can tell, kvmtool should just work fine with any definition of ARM_IOPORT_AREA, as long as you apply the trivial patch below.
* pci_get_io_space_block() is a very confusing name for a function that allocates a memory space block in kvmtool. It seems that KVM_IOPORT_AREA is a misnomer for the same reason. Note that PowerPC sets KVM_IOPORT_AREA to zero, but has the I/O space window at SPAPR_PCI_IO_WIN_ADDR, which is non-zero.
* It's interesting that you also support I/O space access to the PCI config space through PC-Style ports 0cf8-0cff. Not sure if that helps at all, but it is another standard way to probe the bus that could easily be implemented as an alternative to CAM and ECAM, in a generic PCI host driver.
Arnd
tools/kvm/arm/kvm-cpu.c +1 -1
@@ -105,7 +105,7 @@ bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len,return kvm__emulate_mmio (kvm, phys_addr, data, len, is_write); }else if (arm_addr_in_ioport_region (phys_addr)) {int direction = is_write ?KVM_EXIT_IO_OUT :KVM_EXIT_IO_IN ; -u16 port = phys_addr &USHRT_MAX ; +u16 port = (phys_addr -ARM_IOPORT_AREA ) &USHRT_MAX ;return kvm__emulate_io (kvm, port, data, direction, len,1 ); }else if (arm_addr_in_pci_region (phys_addr)) {return kvm__emulate_mmio (kvm, phys_addr, data, len, is_write);
PATCH v3 3/3 PCI: ARM: add support for generic PCI host controller
Quoted 21 lines · Arnd Bergmann
Quoted 10 lines · On Tuesday 18 February 2014 18:44:20 Will Deacon wrote:
Quoted 8 lines · Jason Gunthorpe
Review
Quoted 3 lines · Will Deacon
(quoted diff) +3
-0+ + // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) + ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>,^^^^^^^^^^^^^^This probably shouldn't be 0 in the example, nor in your kvm tool output. For example purposes any value will do.
Quoted 7 lines
Hmm, so kvmtool actually provides a PC ioport at
0x0, which is handy since there's an 8250 down there. That means we have:
0x0-0x6200: Weird PC stuff0x6200-0x10000: PCI IO spaceShould I just change everything to be offset by
0x6200?Some more comments about this:
Quoted 7 lines
* After I looked at the kvmtool code some more, I think it would be nice to actually move the I/O space window to a nonzero location, e.g. between the PCI space and the AXI space. It's really confusing the way it is, and easy to introduce bugs if you have any code that accidentally relies on the numbers matching up. For all I can tell, kvmtool should just work fine with any definition of
ARM_IOPORT_AREA, as long as you apply the trivial patch below.
Well, I think we need a bit more than that otherwise our I/O BARs won't be initialised correctly.
Quoted 5 lines
*
pci_get_io_space_block()is a very confusing name for a function that allocates a memory space block in kvmtool. It seems thatKVM_IOPORT_AREAis a misnomer for the same reason. Note that PowerPC setsKVM_IOPORT_AREAto zero, but has the I/O space window atSPAPR_PCI_IO_WIN_ADDR, which is non-zero.
Agreed about pci_get_io_space_block being a misnomer, that's probably due some cleanup. I don't think KVM_IOPORT_AREA is too bad though (it's zero for PowerPC because I added it and don't have a platform to test on).
Quoted 5 lines
* It's interesting that you also support I/O space access to the PCI config space through PC-Style ports 0cf8-0cff. Not sure if that helps at all, but it is another standard way to probe the bus that could easily be implemented as an alternative to CAM and ECAM, in a generic PCI host driver.
I won't add that initially, but if somebody needs it then it's easy to extend what we currently have.
Will