From: Alexey Kardashevskiy Date: Tue, 27 May 2014 05:36:33 +0000 (+1000) Subject: spapr_pci: Allow multiple TCE tables per PHB X-Git-Tag: TizenStudio_2.0_p2.3.2~208^2~773^2~56 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e28c16f61feefa197e04e83662f32bfc1d607723;p=sdk%2Femulator%2Fqemu.git spapr_pci: Allow multiple TCE tables per PHB At the moment sPAPRPHBState contains a @tcet pointer to the only TCE table. However sPAPR spec allows having more than one DMA window. Since the TCE object is already a child of SPAPR PHB object, there is no need to keep an additional pointer to it in sPAPRPHBState so remove it. This changes the way sPAPRPHBState::reset performs reset of sPAPRTCETable objects. This changes the default DMA window properties calculation. Signed-off-by: Alexey Kardashevskiy Signed-off-by: Alexander Graf --- diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index ba02032..bc23614 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -653,11 +653,13 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) static void spapr_phb_finish_realize(sPAPRPHBState *sphb, Error **errp) { + sPAPRTCETable *tcet; + sphb->dma_window_start = 0; sphb->dma_window_size = 0x40000000; - sphb->tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn, - sphb->dma_window_size); - if (!sphb->tcet) { + tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn, + sphb->dma_window_size); + if (!tcet) { error_setg(errp, "Unable to create TCE table for %s", sphb->dtbusname); return ; @@ -665,16 +667,24 @@ static void spapr_phb_finish_realize(sPAPRPHBState *sphb, Error **errp) /* Register default 32bit DMA window */ memory_region_add_subregion(&sphb->iommu_root, 0, - spapr_tce_get_iommu(sphb->tcet)); + spapr_tce_get_iommu(tcet)); } -static void spapr_phb_reset(DeviceState *qdev) +static int spapr_phb_children_reset(Object *child, void *opaque) { - SysBusDevice *s = SYS_BUS_DEVICE(qdev); - sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); + DeviceState *dev = (DeviceState *) object_dynamic_cast(child, TYPE_DEVICE); + + if (dev) { + device_reset(dev); + } + return 0; +} + +static void spapr_phb_reset(DeviceState *qdev) +{ /* Reset the IOMMU state */ - device_reset(DEVICE(sphb->tcet)); + object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL); } static Property spapr_phb_properties[] = { @@ -788,6 +798,29 @@ PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index) #define b_fff(x) b_x((x), 8, 3) /* function number */ #define b_rrrrrrrr(x) b_x((x), 0, 8) /* register number */ +typedef struct sPAPRTCEDT { + void *fdt; + int node_off; +} sPAPRTCEDT; + +static int spapr_phb_children_dt(Object *child, void *opaque) +{ + sPAPRTCEDT *p = opaque; + sPAPRTCETable *tcet; + + tcet = (sPAPRTCETable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE); + if (!tcet) { + return 0; + } + + spapr_dma_dt(p->fdt, p->node_off, "ibm,dma-window", + tcet->liobn, 0, + tcet->window_size); + /* Stop after the first window */ + + return 1; +} + int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt) @@ -867,9 +900,8 @@ 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_liobn, phb->dma_window_start, - phb->dma_window_size); + object_child_foreach(OBJECT(phb), spapr_phb_children_dt, + &((sPAPRTCEDT){ .fdt = fdt, .node_off = bus_off })); return 0; } diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index fcb6213..9ce83ea 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -62,7 +62,6 @@ struct sPAPRPHBState { uint32_t dma_liobn; uint64_t dma_window_start; uint64_t dma_window_size; - sPAPRTCETable *tcet; AddressSpace iommu_as; MemoryRegion iommu_root;