The XiveFabric offers a simple interface, between the XiveSource object and the main interrupt controller of the machine. It will forward event notifications to the XIVE Interrupt Virtualization Routing Engine (IVRE).
Signed-off-by: Cédric Le Goater <c...@kaod.org> --- include/hw/ppc/xive.h | 23 +++++++++++++++++++++++ hw/intc/xive.c | 25 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index e118acd59f1e..be93fae6317b 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -12,6 +12,27 @@ #include "hw/sysbus.h" +/* + * XIVE Fabric (Interface between Source and Router) + */ + +typedef struct XiveFabric { + Object parent; +} XiveFabric; + +#define TYPE_XIVE_FABRIC "xive-fabric" +#define XIVE_FABRIC(obj) \ + OBJECT_CHECK(XiveFabric, (obj), TYPE_XIVE_FABRIC) +#define XIVE_FABRIC_CLASS(klass) \ + OBJECT_CLASS_CHECK(XiveFabricClass, (klass), TYPE_XIVE_FABRIC) +#define XIVE_FABRIC_GET_CLASS(obj) \ + OBJECT_GET_CLASS(XiveFabricClass, (obj), TYPE_XIVE_FABRIC) + +typedef struct XiveFabricClass { + InterfaceClass parent; + void (*notify)(XiveFabric *xf, uint32_t lisn); +} XiveFabricClass; + /* * XIVE Interrupt Source */ @@ -42,6 +63,8 @@ typedef struct XiveSource { uint64_t esb_flags; uint32_t esb_shift; MemoryRegion esb_mmio; + + XiveFabric *xive; } XiveSource; /* diff --git a/hw/intc/xive.c b/hw/intc/xive.c index ac4605fee8b7..014a2e41f71f 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -152,7 +152,11 @@ static bool xive_source_esb_eoi(XiveSource *xsrc, uint32_t srcno) */ static void xive_source_notify(XiveSource *xsrc, int srcno) { + XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xsrc->xive); + if (xfc->notify) { + xfc->notify(xsrc->xive, srcno); + } } /* @@ -358,6 +362,17 @@ static void xive_source_reset(DeviceState *dev) static void xive_source_realize(DeviceState *dev, Error **errp) { XiveSource *xsrc = XIVE_SOURCE(dev); + Object *obj; + Error *local_err = NULL; + + obj = object_property_get_link(OBJECT(dev), "xive", &local_err); + if (!obj) { + error_propagate(errp, local_err); + error_prepend(errp, "required link 'xive' not found: "); + return; + } + + xsrc->xive = XIVE_FABRIC(obj); if (!xsrc->nr_irqs) { error_setg(errp, "Number of interrupt needs to be greater than 0"); @@ -427,9 +442,19 @@ static const TypeInfo xive_source_info = { .class_init = xive_source_class_init, }; +/* + * XIVE Fabric + */ +static const TypeInfo xive_fabric_info = { + .name = TYPE_XIVE_FABRIC, + .parent = TYPE_INTERFACE, + .class_size = sizeof(XiveFabricClass), +}; + static void xive_register_types(void) { type_register_static(&xive_source_info); + type_register_static(&xive_fabric_info); } type_init(xive_register_types) -- 2.17.2