As part of porting the pxb device to Q35 remove the internal pci-2-pci bridge. The only way to hot-pug devices on the extra PCI root buses is by adding a pci-2-pci to the pxb before the firmware assign the IO/mem resources.
Keep the internal bridge for existing machines. Signed-off-by: Marcel Apfelbaum <mar...@redhat.com> --- hw/pci-bridge/pci_expander_bridge.c | 27 +++++++++++++++++++-------- include/hw/compat.h | 4 ++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 57f8a37..541414c 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -34,6 +34,9 @@ typedef struct PXBBus { #define TYPE_PXB_DEVICE "pxb" #define PXB_DEV(obj) OBJECT_CHECK(PXBDev, (obj), TYPE_PXB_DEVICE) +#define PXB_FLAG_ENABLE_BRIDGE_BIT 0 +#define PXB_FLAG_ENABLE_BRIDGE (1 << PXB_FLAG_ENABLE_BRIDGE_BIT) + typedef struct PXBDev { /*< private >*/ PCIDevice parent_obj; @@ -41,6 +44,7 @@ typedef struct PXBDev { uint8_t bus_nr; uint16_t numa_node; + uint32_t flags; } PXBDev; static GList *pxb_dev_list; @@ -196,7 +200,7 @@ static gint pxb_compare(gconstpointer a, gconstpointer b) static int pxb_dev_initfn(PCIDevice *dev) { PXBDev *pxb = PXB_DEV(dev); - DeviceState *ds, *bds; + DeviceState *ds, *bds = NULL; PCIBus *bus; const char *dev_name = NULL; @@ -211,18 +215,21 @@ static int pxb_dev_initfn(PCIDevice *dev) } ds = qdev_create(NULL, TYPE_PXB_HOST); - bus = pci_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS); + if (pxb->flags & PXB_FLAG_ENABLE_BRIDGE) { + bus = pci_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS); + bds = qdev_create(BUS(bus), "pci-bridge"); + bds->id = dev_name; + qdev_prop_set_uint8(bds, PCI_BRIDGE_DEV_PROP_CHASSIS_NR, pxb->bus_nr); + qdev_prop_set_bit(bds, PCI_BRIDGE_DEV_PROP_SHPC, false); + } else { + bus = pci_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_BUS); + } bus->parent_dev = dev; bus->address_space_mem = dev->bus->address_space_mem; bus->address_space_io = dev->bus->address_space_io; bus->map_irq = pxb_map_irq_fn; - bds = qdev_create(BUS(bus), "pci-bridge"); - bds->id = dev_name; - qdev_prop_set_uint8(bds, PCI_BRIDGE_DEV_PROP_CHASSIS_NR, pxb->bus_nr); - qdev_prop_set_bit(bds, PCI_BRIDGE_DEV_PROP_SHPC, false); - PCI_HOST_BRIDGE(ds)->bus = bus; if (pxb_register_bus(dev, bus)) { @@ -230,7 +237,9 @@ static int pxb_dev_initfn(PCIDevice *dev) } qdev_init_nofail(ds); - qdev_init_nofail(bds); + if (bds) { + qdev_init_nofail(bds); + } pci_word_test_and_set_mask(dev->config + PCI_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK); @@ -251,6 +260,8 @@ static Property pxb_dev_properties[] = { /* Note: 0 is not a legal a PXB bus number. */ DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0), DEFINE_PROP_UINT16("numa_node", PXBDev, numa_node, NUMA_NODE_UNASSIGNED), + DEFINE_PROP_BIT("x-enable-internal-bridge", PXBDev, flags, + PXB_FLAG_ENABLE_BRIDGE_BIT, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/compat.h b/include/hw/compat.h index 97feb75..cbf65ee 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -10,6 +10,10 @@ .driver = "virtio-pci",\ .property = "disable-pcie",\ .value = "on",\ + },{\ + .driver = "pxb",\ + .property = "x-enable-internal-bridge",\ + .value = "on",\ }, #define HW_COMPAT_2_3 \ -- 2.1.0