When the XIVE IVRE sub-engine (XiveRouter) looks for a Notification Virtual Target (NVT) to notify, it broadcasts a message on the PowerBUS to find an XIVE IVPE sub-engine (Presenter) which has the NVT dispatched on one of its HW threads, and then forwards the notification if any response was received.
The current XIVE presenter model is sufficient for the pseries machine because it has a single interrupt controller device, but the PowerNV machine can have multiple chips each having its own interrupt controller. In this case, the XIVE presenter model is too simple and the CAM line matching should scan all chips of the system. We introduce a XiveFabric QOM interface which needs to be implemented by the machine. It acts as the PowerBUS interface between the interrupt controller and the system. On HW, the XIVE sub-engine responsible for the communication with the other chip is the Common Queue (CQ) bridge unit. This interface offers a 'match_nvt' handler to perform the CAM line matching when looking for a XIVE Presenter with a dispatched NVT. We also introduce a XivePresenter QOM interface to represent the XIVE Presenter (PC) sub-engine of the XIVE controller with a similar 'match_nvt' handler to perform the CAM line matching. This interface could be merged in the XiveRouter but as it is stateless and performs the XIVE IVPE sub-engine tasks, it makes sense to keep it independent. It should have its use in POWER10. Fixes: af53dbf6227a ("ppc/xive: introduce a simplified XIVE presenter") Signed-off-by: Cédric Le Goater <c...@kaod.org> --- include/hw/ppc/xive.h | 54 +++++++++++++++++++++++++++++++++++++++++++ hw/intc/xive.c | 36 +++++++++++++++++++++-------- 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 4851ff87e795..165134ce52a5 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -368,6 +368,60 @@ int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx, XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs); void xive_router_notify(XiveNotifier *xn, uint32_t lisn); +/* + * XIVE Presenter + */ + +typedef struct XiveTCTXMatch { + XiveTCTX *tctx; + uint8_t ring; +} XiveTCTXMatch; + +typedef struct XivePresenter XivePresenter; + +#define TYPE_XIVE_PRESENTER "xive-presenter" +#define XIVE_PRESENTER(obj) \ + INTERFACE_CHECK(XivePresenter, (obj), TYPE_XIVE_PRESENTER) +#define XIVE_PRESENTER_CLASS(klass) \ + OBJECT_CLASS_CHECK(XivePresenterClass, (klass), TYPE_XIVE_PRESENTER) +#define XIVE_PRESENTER_GET_CLASS(obj) \ + OBJECT_GET_CLASS(XivePresenterClass, (obj), TYPE_XIVE_PRESENTER) + +typedef struct XivePresenterClass { + InterfaceClass parent; + int (*match_nvt)(XivePresenter *xptr, uint8_t format, + uint8_t nvt_blk, uint32_t nvt_idx, + bool cam_ignore, uint8_t priority, + uint32_t logic_serv, XiveTCTXMatch *match); +} XivePresenterClass; + +int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, + uint8_t format, + uint8_t nvt_blk, uint32_t nvt_idx, + bool cam_ignore, uint32_t logic_serv); + +/* + * XIVE Fabric (Interface between Interrupt Controller and Machine) + */ + +typedef struct XiveFabric XiveFabric; + +#define TYPE_XIVE_FABRIC "xive-fabric" +#define XIVE_FABRIC(obj) \ + INTERFACE_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; + int (*match_nvt)(XiveFabric *xfb, uint8_t format, + uint8_t nvt_blk, uint32_t nvt_idx, + bool cam_ignore, uint8_t priority, + uint32_t logic_serv, XiveTCTXMatch *match); +} XiveFabricClass; + /* * XIVE END ESBs */ diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 88f2e560db0f..4bdedab13047 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1294,9 +1294,10 @@ static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx) /* * The thread context register words are in big-endian format. */ -static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format, - uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint32_t logic_serv) +int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, + uint8_t format, + uint8_t nvt_blk, uint32_t nvt_idx, + bool cam_ignore, uint32_t logic_serv) { uint32_t cam = xive_nvt_cam_line(nvt_blk, nvt_idx); uint32_t qw3w2 = xive_tctx_word2(&tctx->regs[TM_QW3_HV_PHYS]); @@ -1353,11 +1354,6 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format, return -1; } -typedef struct XiveTCTXMatch { - XiveTCTX *tctx; - uint8_t ring; -} XiveTCTXMatch; - static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, bool cam_ignore, uint8_t priority, @@ -1383,7 +1379,8 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format, * Check the thread context CAM lines and record matches. We * will handle CPU exception delivery later */ - ring = xive_presenter_tctx_match(tctx, format, nvt_blk, nvt_idx, + ring = xive_presenter_tctx_match(XIVE_PRESENTER(xrtr), tctx, format, + nvt_blk, nvt_idx, cam_ignore, logic_serv); /* * Save the context and follow on to catch duplicates, that we @@ -1670,6 +1667,7 @@ static const TypeInfo xive_router_info = { .class_init = xive_router_class_init, .interfaces = (InterfaceInfo[]) { { TYPE_XIVE_NOTIFIER }, + { TYPE_XIVE_PRESENTER }, { } } }; @@ -1841,10 +1839,30 @@ static const TypeInfo xive_notifier_info = { .class_size = sizeof(XiveNotifierClass), }; +/* + * XIVE Presenter + */ +static const TypeInfo xive_presenter_info = { + .name = TYPE_XIVE_PRESENTER, + .parent = TYPE_INTERFACE, + .class_size = sizeof(XivePresenterClass), +}; + +/* + * 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_notifier_info); + type_register_static(&xive_presenter_info); + type_register_static(&xive_fabric_info); type_register_static(&xive_router_info); type_register_static(&xive_end_source_info); type_register_static(&xive_tctx_info); -- 2.21.0