Skip to content

Commit

Permalink
pseries dma: DMA window params added to PHB and DT population changed
Browse files Browse the repository at this point in the history
Previously the only PCI bus supported was the emulated PCI bus with
fixed DMA window with start at 0 and size 1GB. As we are going to support
PCI pass through which DMA window properties are set by the host
kernel, we have to support DMA windows with parameters other than default.

This patch adds:

1. DMA window properties to sPAPRPHBState: LIOBN (bus id), start,
size of the window.

2. An additional function spapr_dma_dt() to populate DMA window
properties in the device tree which simply accepts all the parameters
and does not try to guess what kind of IOMMU is given to it.
The original spapr_dma_dt() is renamed to spapr_tcet_dma_dt().

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
  • Loading branch information
aik authored and agraf committed Aug 15, 2012
1 parent 0ee2c05 commit 5c4cbcf
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 28 deletions.
4 changes: 3 additions & 1 deletion hw/spapr.h
Expand Up @@ -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__) */
58 changes: 37 additions & 21 deletions hw/spapr_iommu.c
Expand Up @@ -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;
}
11 changes: 7 additions & 4 deletions hw/spapr_pci.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 3 additions & 1 deletion hw/spapr_pci.h
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion hw/spapr_vio.c
Expand Up @@ -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;
}
Expand Down

0 comments on commit 5c4cbcf

Please sign in to comment.