summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/spapr.h4
-rw-r--r--hw/spapr_iommu.c58
-rw-r--r--hw/spapr_pci.c11
-rw-r--r--hw/spapr_pci.h4
-rw-r--r--hw/spapr_vio.c2
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;
}