static void mch_init_dmar(MCHPCIState *mch) { PCIBus *pci_bus = PCI_BUS(qdev_get_parent_bus(DEVICE(mch))); mch->iommu = INTEL_IOMMU_DEVICE(qdev_create(NULL, TYPE_INTEL_IOMMU_DEVICE)); object_property_add_child(OBJECT(mch), "intel-iommu", OBJECT(mch->iommu), NULL); qdev_init_nofail(DEVICE(mch->iommu)); sysbus_mmio_map(SYS_BUS_DEVICE(mch->iommu), 0, Q35_HOST_BRIDGE_IOMMU_ADDR); pci_setup_iommu(pci_bus, q35_host_dma_iommu, mch->iommu); }
static int ppc440_pcix_initfn(SysBusDevice *dev) { PPC440PCIXState *s; PCIHostState *h; int i; h = PCI_HOST_BRIDGE(dev); s = PPC440_PCIX_HOST_BRIDGE(dev); for (i = 0; i < ARRAY_SIZE(s->irq); i++) { sysbus_init_irq(dev, &s->irq[i]); } memory_region_init(&s->busmem, OBJECT(dev), "pci bus memory", UINT64_MAX); h->bus = pci_register_root_bus(DEVICE(dev), NULL, ppc440_pcix_set_irq, ppc440_pcix_map_irq, s->irq, &s->busmem, get_system_io(), PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS); s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0), "ppc4xx-host-bridge"); memory_region_init(&s->bm, OBJECT(s), "bm-ppc440-pcix", UINT64_MAX); memory_region_add_subregion(&s->bm, 0x0, &s->busmem); address_space_init(&s->bm_as, &s->bm, "pci-bm"); pci_setup_iommu(h->bus, ppc440_pcix_set_iommu, s); memory_region_init(&s->container, OBJECT(s), "pci-container", PCI_ALL_SIZE); memory_region_init_io(&h->conf_mem, OBJECT(s), &pci_host_conf_le_ops, h, "pci-conf-idx", 4); memory_region_init_io(&h->data_mem, OBJECT(s), &ppc440_pcix_host_data_ops, h, "pci-conf-data", 4); memory_region_init_io(&s->iomem, OBJECT(s), &pci_reg_ops, s, "pci.reg", PPC440_REG_SIZE); memory_region_add_subregion(&s->container, PCIC0_CFGADDR, &h->conf_mem); memory_region_add_subregion(&s->container, PCIC0_CFGDATA, &h->data_mem); memory_region_add_subregion(&s->container, PPC440_REG_BASE, &s->iomem); sysbus_init_mmio(dev, &s->container); return 0; }
PCIBus *dino_init(MemoryRegion *addr_space, qemu_irq *p_rtc_irq, qemu_irq *p_ser_irq) { DeviceState *dev; DinoState *s; PCIBus *b; int i; dev = qdev_create(NULL, TYPE_DINO_PCI_HOST_BRIDGE); s = DINO_PCI_HOST_BRIDGE(dev); /* Dino PCI access from main memory. */ memory_region_init_io(&s->this_mem, OBJECT(s), &dino_chip_ops, s, "dino", 4096); memory_region_add_subregion(addr_space, DINO_HPA, &s->this_mem); /* Dino PCI config. */ memory_region_init_io(&s->parent_obj.conf_mem, OBJECT(&s->parent_obj), &pci_host_conf_be_ops, dev, "pci-conf-idx", 4); memory_region_init_io(&s->parent_obj.data_mem, OBJECT(&s->parent_obj), &dino_config_data_ops, dev, "pci-conf-data", 4); memory_region_add_subregion(&s->this_mem, DINO_PCI_CONFIG_ADDR, &s->parent_obj.conf_mem); memory_region_add_subregion(&s->this_mem, DINO_CONFIG_DATA, &s->parent_obj.data_mem); /* Dino PCI bus memory. */ memory_region_init(&s->pci_mem, OBJECT(s), "pci-memory", 1ull << 32); b = pci_register_root_bus(dev, "pci", dino_set_irq, dino_pci_map_irq, s, &s->pci_mem, get_system_io(), PCI_DEVFN(0, 0), 32, TYPE_PCI_BUS); s->parent_obj.bus = b; qdev_init_nofail(dev); /* Set up windows into PCI bus memory. */ for (i = 1; i < 31; i++) { uint32_t addr = 0xf0000000 + i * DINO_MEM_CHUNK_SIZE; char *name = g_strdup_printf("PCI Outbound Window %d", i); memory_region_init_alias(&s->pci_mem_alias[i], OBJECT(s), name, &s->pci_mem, addr, DINO_MEM_CHUNK_SIZE); } /* Set up PCI view of memory: Bus master address space. */ memory_region_init(&s->bm, OBJECT(s), "bm-dino", 1ull << 32); memory_region_init_alias(&s->bm_ram_alias, OBJECT(s), "bm-system", addr_space, 0, 0xf0000000 + DINO_MEM_CHUNK_SIZE); memory_region_init_alias(&s->bm_pci_alias, OBJECT(s), "bm-pci", &s->pci_mem, 0xf0000000 + DINO_MEM_CHUNK_SIZE, 30 * DINO_MEM_CHUNK_SIZE); memory_region_init_alias(&s->bm_cpu_alias, OBJECT(s), "bm-cpu", addr_space, 0xfff00000, 0xfffff); memory_region_add_subregion(&s->bm, 0, &s->bm_ram_alias); memory_region_add_subregion(&s->bm, 0xf0000000 + DINO_MEM_CHUNK_SIZE, &s->bm_pci_alias); memory_region_add_subregion(&s->bm, 0xfff00000, &s->bm_cpu_alias); address_space_init(&s->bm_as, &s->bm, "pci-bm"); pci_setup_iommu(b, dino_pcihost_set_iommu, s); *p_rtc_irq = qemu_allocate_irq(dino_set_timer_irq, s, 0); *p_ser_irq = qemu_allocate_irq(dino_set_serial_irq, s, 0); return b; }