diff options
-rw-r--r-- | hw/spapr.h | 4 | ||||
-rw-r--r-- | hw/spapr_iommu.c | 58 | ||||
-rw-r--r-- | hw/spapr_pci.c | 11 | ||||
-rw-r--r-- | hw/spapr_pci.h | 4 | ||||
-rw-r--r-- | hw/spapr_vio.c | 2 |
5 files changed, 51 insertions, 28 deletions
diff --git a/hw/spapr.h b/hw/spapr.h index 6229769ce0..ac34a171e3 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -337,6 +337,8 @@ void spapr_iommu_init(void); DMAContext *spapr_tce_new_dma_context(uint32_t liobn, size_t window_size); void spapr_tce_free(DMAContext *dma); int spapr_dma_dt(void *fdt, int node_off, const char *propname, - DMAContext *dma); + uint32_t liobn, uint64_t window, uint32_t size); +int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, + DMAContext *dma); #endif /* !defined (__HW_SPAPR_H__) */ diff --git a/hw/spapr_iommu.c b/hw/spapr_iommu.c index 388ffa4b22..53b731773a 100644 --- a/hw/spapr_iommu.c +++ b/hw/spapr_iommu.c @@ -216,31 +216,47 @@ void spapr_iommu_init(void) } int spapr_dma_dt(void *fdt, int node_off, const char *propname, - DMAContext *dma) + uint32_t liobn, uint64_t window, uint32_t size) { - if (dma) { - sPAPRTCETable *tcet = DO_UPCAST(sPAPRTCETable, dma, dma); - uint32_t dma_prop[] = {cpu_to_be32(tcet->liobn), - 0, 0, - 0, cpu_to_be32(tcet->window_size)}; - int ret; - - ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-address-cells", 2); - if (ret < 0) { - return ret; - } + uint32_t dma_prop[5]; + int ret; + + dma_prop[0] = cpu_to_be32(liobn); + dma_prop[1] = cpu_to_be32(window >> 32); + dma_prop[2] = cpu_to_be32(window & 0xFFFFFFFF); + dma_prop[3] = 0; /* window size is 32 bits */ + dma_prop[4] = cpu_to_be32(size); + + ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-address-cells", 2); + if (ret < 0) { + return ret; + } - ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-size-cells", 2); - if (ret < 0) { - return ret; - } + ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-size-cells", 2); + if (ret < 0) { + return ret; + } - ret = fdt_setprop(fdt, node_off, propname, dma_prop, - sizeof(dma_prop)); - if (ret < 0) { - return ret; - } + ret = fdt_setprop(fdt, node_off, propname, dma_prop, sizeof(dma_prop)); + if (ret < 0) { + return ret; } return 0; } + +int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, + DMAContext *iommu) +{ + if (!iommu) { + return 0; + } + + if (iommu->translate == spapr_tce_translate) { + sPAPRTCETable *tcet = DO_UPCAST(sPAPRTCETable, dma, iommu); + return spapr_dma_dt(fdt, node_off, propname, + tcet->liobn, 0, tcet->window_size); + } + + return -1; +} diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 780a4d6f16..b92583a991 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -518,7 +518,6 @@ static int spapr_phb_init(SysBusDevice *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); @@ -570,8 +569,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); + phb->dma_liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16); + phb->dma_window_start = 0; + phb->dma_window_size = 0x40000000; + phb->dma = spapr_tce_new_dma_context(phb->dma_liobn, phb->dma_window_size); pci_setup_iommu(bus, spapr_pci_dma_context_fn, phb); QLIST_INSERT_HEAD(&spapr->phbs, phb, list); @@ -729,7 +730,9 @@ int spapr_populate_pci_dt(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); + spapr_dma_dt(fdt, bus_off, "ibm,dma-window", + phb->dma_liobn, phb->dma_window_start, + phb->dma_window_size); return 0; } diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h index 6892e4fae5..7518899b85 100644 --- a/hw/spapr_pci.h +++ b/hw/spapr_pci.h @@ -41,7 +41,9 @@ typedef struct sPAPRPHBState { target_phys_addr_t msi_win_addr; MemoryRegion memwindow, iowindow, msiwindow; - + uint32_t dma_liobn; + uint64_t dma_window_start; + uint64_t dma_window_size; DMAContext *dma; struct { diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c index 3abe853f3d..7ca445216d 100644 --- a/hw/spapr_vio.c +++ b/hw/spapr_vio.c @@ -142,7 +142,7 @@ static int vio_make_devnode(VIOsPAPRDevice *dev, } } - ret = spapr_dma_dt(fdt, node_off, "ibm,my-dma-window", dev->dma); + ret = spapr_tcet_dma_dt(fdt, node_off, "ibm,my-dma-window", dev->dma); if (ret < 0) { return ret; } |