[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH v2 3/9] spapr_pci: Introduce a finish_realize() callba
From: |
Alexey Kardashevskiy |
Subject: |
[Qemu-ppc] [PATCH v2 3/9] spapr_pci: Introduce a finish_realize() callback |
Date: |
Thu, 22 May 2014 21:19:24 +1000 |
The spapr-pci PHB initializes IOMMU for emulated devices only.
The upcoming VFIO support will do it different. However both emulated
and VFIO PHB types share most of the initialization code.
For the type specific things a new finish_realize() callback is
introduced.
This introduces sPAPRPHBClass derived from PCIHostBridgeClass and
adds the callback pointer.
This implements finish_realize() for emulated devices.
Signed-off-by: Alexey Kardashevskiy <address@hidden>
---
The difference to VFIO is that for VFIO we have to ask the kernel
about DMA window size before calling spapr_tce_new_table() and
then we have to tell VFIO KVM device about LIOBN <-> IOMMU link.
---
hw/ppc/spapr_pci.c | 38 ++++++++++++++++++++++++++------------
include/hw/pci-host/spapr.h | 14 ++++++++++++++
2 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 1db73f2..b141e83 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -528,6 +528,7 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
SysBusDevice *s = SYS_BUS_DEVICE(dev);
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s);
+ sPAPRPHBClass *info = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(s);
char *namebuf;
int i;
PCIBus *bus;
@@ -609,18 +610,6 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
phb->bus = bus;
- sphb->dma_window_start = 0;
- sphb->dma_window_size = 0x40000000;
- sphb->tcet = spapr_tce_new_table(dev, sphb->dma_liobn,
- sphb->dma_window_size);
- if (!sphb->tcet) {
- error_setg(errp, "Unable to create TCE table for %s",
- sphb->dtbusname);
- return;
- }
- address_space_init(&sphb->iommu_as, spapr_tce_get_iommu(sphb->tcet),
- sphb->dtbusname);
-
pci_setup_iommu(bus, spapr_pci_dma_iommu, sphb);
pci_bus_set_route_irq_fn(bus, spapr_route_intx_pin_to_irq);
@@ -639,6 +628,28 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
sphb->lsi_table[i].irq = irq;
}
+
+ if (!info->finish_realize) {
+ error_setg(errp, "finish_realize not defined");
+ return;
+ }
+
+ info->finish_realize(sphb, errp);
+}
+
+static void spapr_phb_finish_realize(sPAPRPHBState *sphb, Error **errp)
+{
+ 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) {
+ error_setg(errp, "Unable to create TCE table for %s",
+ sphb->dtbusname);
+ return ;
+ }
+ address_space_init(&sphb->iommu_as, spapr_tce_get_iommu(sphb->tcet),
+ sphb->dtbusname);
}
static void spapr_phb_reset(DeviceState *qdev)
@@ -722,6 +733,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void
*data)
{
PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
+ sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_CLASS(klass);
hc->root_bus_path = spapr_phb_root_bus_path;
dc->realize = spapr_phb_realize;
@@ -730,6 +742,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void
*data)
dc->vmsd = &vmstate_spapr_pci;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->cannot_instantiate_with_device_add_yet = false;
+ spc->finish_realize = spapr_phb_finish_realize;
}
static const TypeInfo spapr_phb_info = {
@@ -737,6 +750,7 @@ static const TypeInfo spapr_phb_info = {
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(sPAPRPHBState),
.class_init = spapr_phb_class_init,
+ .class_size = sizeof(sPAPRPHBClass),
};
PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index)
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 970b4a9..ab29281 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -34,6 +34,20 @@
#define SPAPR_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(sPAPRPHBState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
+#define SPAPR_PCI_HOST_BRIDGE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(sPAPRPHBClass, (klass), TYPE_SPAPR_PCI_HOST_BRIDGE)
+#define SPAPR_PCI_HOST_BRIDGE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(sPAPRPHBClass, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
+
+typedef struct sPAPRPHBClass sPAPRPHBClass;
+typedef struct sPAPRPHBState sPAPRPHBState;
+
+struct sPAPRPHBClass {
+ PCIHostBridgeClass parent_class;
+
+ void (*finish_realize)(sPAPRPHBState *sphb, Error **errp);
+};
+
typedef struct sPAPRPHBState {
PCIHostState parent_obj;
--
1.9.rc0
- [Qemu-ppc] [PATCH v2 0/9] spapr_pci: Prepare for VFIO, Alexey Kardashevskiy, 2014/05/22
- [Qemu-ppc] [PATCH v2 4/9] spapr_pci: spapr_iommu: Make DMA window a subregion, Alexey Kardashevskiy, 2014/05/22
- [Qemu-ppc] [PATCH v2 9/9] spapr_iommu: Introduce bus_offset in sPAPRTCETable, Alexey Kardashevskiy, 2014/05/22
- [Qemu-ppc] [PATCH v2 8/9] spapr_iommu: Introduce page_shift in sPAPRTCETable, Alexey Kardashevskiy, 2014/05/22
- [Qemu-ppc] [PATCH v2 5/9] spapr_pci: Allow multiple TCE tables per PHB, Alexey Kardashevskiy, 2014/05/22
- [Qemu-ppc] [PATCH v2 7/9] spapr_iommu: Get rid of window_size in sPAPRTCETable, Alexey Kardashevskiy, 2014/05/22
- [Qemu-ppc] [PATCH v2 6/9] spapr_iommu: Convert old qdev_init_nofail() to object_property_set_bool, Alexey Kardashevskiy, 2014/05/22
- [Qemu-ppc] [PATCH v2 3/9] spapr_pci: Introduce a finish_realize() callback,
Alexey Kardashevskiy <=
- [Qemu-ppc] [PATCH v2 1/9] spapr: Enable dynamic change of the supported hypercalls list, Alexey Kardashevskiy, 2014/05/22
- [Qemu-ppc] [PATCH v2 2/9] spapr_iommu: Enable multiple TCE requests, Alexey Kardashevskiy, 2014/05/22