[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH 5/9] spapr_pci: Allow multiple TCE tables per PHB
From: |
Alexey Kardashevskiy |
Subject: |
[Qemu-ppc] [PATCH 5/9] spapr_pci: Allow multiple TCE tables per PHB |
Date: |
Thu, 22 May 2014 00:21:16 +1000 |
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 <address@hidden>
---
The only reason for sPAPRPHBState to keep a pointer to sPAPRTCETable is
to have a direct link to calculate default 32bit window properties.
So I decided to replace the link with a spapr_phb_children_dt() loop
and use first TCE table for default window. Is that ok or ugly?
---
hw/ppc/spapr_pci.c | 54 ++++++++++++++++++++++++++++++++++++---------
include/hw/pci-host/spapr.h | 1 -
2 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index f1684c2..aa29116 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 int spapr_phb_children_reset(Object *child, void *opaque)
+{
+ DeviceState *dev = (DeviceState *) object_dynamic_cast(child, TYPE_DEVICE);
+
+ if (dev) {
+ device_reset(dev);
+ }
+
+ return 0;
}
static void spapr_phb_reset(DeviceState *qdev)
{
- SysBusDevice *s = SYS_BUS_DEVICE(qdev);
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
-
/* Reset the IOMMU state */
- device_reset(DEVICE(sphb->tcet));
+ object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL);
}
static Property spapr_phb_properties[] = {
@@ -791,6 +801,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)
@@ -870,9 +903,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 c98ebdf..5ea4745 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -62,7 +62,6 @@ typedef struct sPAPRPHBState {
uint32_t dma_liobn;
uint64_t dma_window_start;
uint64_t dma_window_size;
- sPAPRTCETable *tcet;
AddressSpace iommu_as;
MemoryRegion iommu_root;
--
1.9.rc0
- [Qemu-ppc] [PATCH 0/9] spapr_pci: Prepare for VFIO, Alexey Kardashevskiy, 2014/05/21
- [Qemu-ppc] [PATCH 3/9] spapr_pci: Introduce a finish_realize() callback, Alexey Kardashevskiy, 2014/05/21
- [Qemu-ppc] [PATCH 2/9] spapr_iommu: Enable multiple TCE requests, Alexey Kardashevskiy, 2014/05/21
- [Qemu-ppc] [PATCH 1/9] spapr: Enable dynamic change of the supported hypercalls list, Alexey Kardashevskiy, 2014/05/21
- [Qemu-ppc] [PATCH 7/9] spapr_iommu: Get rid of window_size in sPAPRTCETable, Alexey Kardashevskiy, 2014/05/21
- [Qemu-ppc] [PATCH 4/9] spapr_pci: spapr_iommu: Make DMA window a subregion, Alexey Kardashevskiy, 2014/05/21
- [Qemu-ppc] [PATCH 8/9] spapr_iommu: Introduce page_shift in sPAPRTCETable, Alexey Kardashevskiy, 2014/05/21
- [Qemu-ppc] [PATCH 9/9] spapr_iommu: Introduce bus_offset in sPAPRTCETable, Alexey Kardashevskiy, 2014/05/21
- [Qemu-ppc] [PATCH 6/9] spapr_iommu: Convert old qdev_init_nofail() to object_property_set_bool, Alexey Kardashevskiy, 2014/05/21
- [Qemu-ppc] [PATCH 5/9] spapr_pci: Allow multiple TCE tables per PHB,
Alexey Kardashevskiy <=