diff options
Diffstat (limited to 'hw/spapr_pci.c')
-rw-r--r-- | hw/spapr_pci.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 25b400aa47..b2e4f785ea 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -35,17 +35,18 @@ static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid, uint32_t config_addr) { - DeviceState *qdev; int devfn = (config_addr >> 8) & 0xFF; sPAPRPHBState *phb; QLIST_FOREACH(phb, &spapr->phbs, list) { + BusChild *kid; + if (phb->buid != buid) { continue; } - QTAILQ_FOREACH(qdev, &phb->host_state.bus->qbus.children, sibling) { - PCIDevice *dev = (PCIDevice *)qdev; + QTAILQ_FOREACH(kid, &phb->host_state.bus->qbus.children, sibling) { + PCIDevice *dev = (PCIDevice *)kid->child; if (dev->devfn == devfn) { return dev; } @@ -265,12 +266,21 @@ static const MemoryRegionOps spapr_io_ops = { /* * PHB PCI device */ +static DMAContext *spapr_pci_dma_context_fn(PCIBus *bus, void *opaque, + int devfn) +{ + sPAPRPHBState *phb = opaque; + + return phb->dma; +} + static int spapr_phb_init(SysBusDevice *s) { sPAPRPHBState *phb = FROM_SYSBUS(sPAPRPHBState, s); char *namebuf; int i; PCIBus *bus; + uint32_t liobn; phb->dtbusname = g_strdup_printf("pci@%" PRIx64, phb->buid); namebuf = alloca(strlen(phb->dtbusname) + 32); @@ -311,6 +321,10 @@ static int spapr_phb_init(SysBusDevice *s) PCI_DEVFN(0, 0), PCI_NUM_PINS); phb->host_state.bus = bus; + liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16); + phb->dma = spapr_tce_new_dma_context(liobn, 0x40000000); + pci_setup_iommu(bus, spapr_pci_dma_context_fn, phb); + QLIST_INSERT_HEAD(&spapr->phbs, phb, list); /* Initialize the LSI table */ @@ -404,7 +418,7 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb, uint64_t child; uint64_t parent; uint64_t size; - } __attribute__((packed)) ranges[] = { + } QEMU_PACKED ranges[] = { { cpu_to_be32(b_ss(1)), cpu_to_be64(0), cpu_to_be64(phb->io_win_addr), @@ -471,6 +485,8 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb, _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map, sizeof(interrupt_map))); + spapr_dma_dt(fdt, bus_off, "ibm,dma-window", phb->dma); + return 0; } |