.endianness = DEVICE_LITTLE_ENDIAN,
};
- static int pci_pbm_init_device(SysBusDevice *dev)
+ static void pci_pbm_realize(DeviceState *dev, Error **errp)
{
- APBState *s;
+ APBState *s = APB_DEVICE(dev);
+ PCIHostState *phb = PCI_HOST_BRIDGE(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(s);
+ PCIDevice *pci_dev;
+
+ /* apb_config */
+ sysbus_mmio_map(sbd, 0, s->special_base);
+ /* PCI configuration space */
+ sysbus_mmio_map(sbd, 1, s->special_base + 0x1000000ULL);
+ /* pci_ioport */
+ sysbus_mmio_map(sbd, 2, s->special_base + 0x2000000ULL);
+
+ memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
+ memory_region_add_subregion(get_system_memory(), s->mem_base,
+ &s->pci_mmio);
+
- phb->bus = pci_register_bus(dev, "pci",
- pci_apb_set_irq, pci_apb_map_irq, s,
- &s->pci_mmio,
- &s->pci_ioport,
- 0, 32, TYPE_PCI_BUS);
++ phb->bus = pci_register_root_bus(dev, "pci",
++ pci_apb_set_irq, pci_apb_map_irq, s,
++ &s->pci_mmio,
++ &s->pci_ioport,
++ 0, 32, TYPE_PCI_BUS);
+
+ pci_create_simple(phb->bus, 0, "pbm-pci");
+
+ /* APB IOMMU */
+ memory_region_add_subregion_overlap(&s->apb_config, 0x200,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(s->iommu), 0), 1);
+ pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, s->iommu);
+
+ /* APB secondary busses */
+ pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
+ TYPE_PBM_PCI_BRIDGE);
+ s->bridgeB = PCI_BRIDGE(pci_dev);
+ pci_bridge_map_irq(s->bridgeB, "pciB", pci_pbmB_map_irq);
+ qdev_init_nofail(&pci_dev->qdev);
+
+ pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
+ TYPE_PBM_PCI_BRIDGE);
+ s->bridgeA = PCI_BRIDGE(pci_dev);
+ pci_bridge_map_irq(s->bridgeA, "pciA", pci_pbmA_map_irq);
+ qdev_init_nofail(&pci_dev->qdev);
+ }
+
+ static void pci_pbm_init(Object *obj)
+ {
+ APBState *s = APB_DEVICE(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
unsigned int i;
- s = APB_DEVICE(dev);
for (i = 0; i < 8; i++) {
s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
}