diff options
author | Greg Kurz <groug@kaod.org> | 2019-04-01 19:55:02 +0200 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2019-04-09 09:14:47 +1000 |
commit | 1c685a9026349752c3627aa24b090973e35b83c3 (patch) | |
tree | 8618f5915e18c85135e6b72507e1a300a6109e9a /hw | |
parent | 5263724b78f89cdea2354c8e92c53bac1b4641a3 (diff) |
pci: Allow PCI bus subtypes to support extended config space accesses
Some PHB implementations, eg. PAPR used on pseries machine, act like
a regular PCI bus rather than a PCIe bus, but allow access to the
PCIe extended config space anyway.
Introduce a new PCI bus class method to modelize this behaviour and
use it when adjusting the config space size limit during accesses.
No behaviour change for existing PCI bus types.
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <155414130271.574858.4253514266378127489.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/pci/pci.c | 24 | ||||
-rw-r--r-- | hw/pci/pci_host.c | 2 |
2 files changed, 25 insertions, 1 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 35451c1e99..6d13ef877b 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -147,6 +147,11 @@ static uint16_t pcibus_numa_node(PCIBus *bus) return NUMA_NODE_UNASSIGNED; } +static bool pcibus_allows_extended_config_space(PCIBus *bus) +{ + return false; +} + static void pci_bus_class_init(ObjectClass *klass, void *data) { BusClass *k = BUS_CLASS(klass); @@ -162,6 +167,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data) pbc->is_root = pcibus_is_root; pbc->bus_num = pcibus_num; pbc->numa_node = pcibus_numa_node; + pbc->allows_extended_config_space = pcibus_allows_extended_config_space; } static const TypeInfo pci_bus_info = { @@ -182,9 +188,22 @@ static const TypeInfo conventional_pci_interface_info = { .parent = TYPE_INTERFACE, }; +static bool pciebus_allows_extended_config_space(PCIBus *bus) +{ + return true; +} + +static void pcie_bus_class_init(ObjectClass *klass, void *data) +{ + PCIBusClass *pbc = PCI_BUS_CLASS(klass); + + pbc->allows_extended_config_space = pciebus_allows_extended_config_space; +} + static const TypeInfo pcie_bus_info = { .name = TYPE_PCIE_BUS, .parent = TYPE_PCI_BUS, + .class_init = pcie_bus_class_init, }; static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num); @@ -401,6 +420,11 @@ bool pci_bus_is_root(PCIBus *bus) return PCI_BUS_GET_CLASS(bus)->is_root(bus); } +bool pci_bus_allows_extended_config_space(PCIBus *bus) +{ + return PCI_BUS_GET_CLASS(bus)->allows_extended_config_space(bus); +} + void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent, const char *name, MemoryRegion *address_space_mem, diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c index 5f5345dbac..9d64b2e12f 100644 --- a/hw/pci/pci_host.c +++ b/hw/pci/pci_host.c @@ -54,7 +54,7 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, uint32_t addr) static void pci_adjust_config_limit(PCIBus *bus, uint32_t *limit) { if (*limit > PCI_CONFIG_SPACE_SIZE) { - if (!pci_bus_is_express(bus)) { + if (!pci_bus_allows_extended_config_space(bus)) { *limit = PCI_CONFIG_SPACE_SIZE; return; } |