diff options
author | Cédric Le Goater <clg@kaod.org> | 2022-03-02 06:51:39 +0100 |
---|---|---|
committer | Cédric Le Goater <clg@kaod.org> | 2022-03-02 06:51:39 +0100 |
commit | 0aa2612a01f233a4a25fb89e8362baf6cf896be6 (patch) | |
tree | 843c92a177ce54f209f8f069fa35aa3405d5f938 /hw/intc/xive.c | |
parent | aadf13abaad43dd1f8b6113e516649578af63775 (diff) |
ppc/xive: Add support for PQ state bits offload
The trigger message coming from a HW source contains a special bit
informing the XIVE interrupt controller that the PQ bits have been
checked at the source or not. Depending on the value, the IC can
perform the check and the state transition locally using its own PQ
state bits.
The following changes add new accessors to the XiveRouter required to
query and update the PQ state bits. This only applies to the PowerNV
machine. sPAPR accessors are provided but the pSeries machine should
not be concerned by such complex configuration for the moment.
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'hw/intc/xive.c')
-rw-r--r-- | hw/intc/xive.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 0d98b9539c..deb0db21e0 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -938,7 +938,7 @@ static void xive_source_notify(XiveSource *xsrc, int srcno) XiveNotifierClass *xnc = XIVE_NOTIFIER_GET_CLASS(xsrc->xive); if (xnc->notify) { - xnc->notify(xsrc->xive, srcno); + xnc->notify(xsrc->xive, srcno, true); } } @@ -1370,6 +1370,24 @@ int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx, return xrc->get_eas(xrtr, eas_blk, eas_idx, eas); } +static +int xive_router_get_pq(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx, + uint8_t *pq) +{ + XiveRouterClass *xrc = XIVE_ROUTER_GET_CLASS(xrtr); + + return xrc->get_pq(xrtr, eas_blk, eas_idx, pq); +} + +static +int xive_router_set_pq(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx, + uint8_t *pq) +{ + XiveRouterClass *xrc = XIVE_ROUTER_GET_CLASS(xrtr); + + return xrc->set_pq(xrtr, eas_blk, eas_idx, pq); +} + int xive_router_get_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx, XiveEND *end) { @@ -1721,7 +1739,7 @@ do_escalation: xive_get_field32(END_W5_ESC_END_DATA, end.w5)); } -void xive_router_notify(XiveNotifier *xn, uint32_t lisn) +void xive_router_notify(XiveNotifier *xn, uint32_t lisn, bool pq_checked) { XiveRouter *xrtr = XIVE_ROUTER(xn); uint8_t eas_blk = XIVE_EAS_BLOCK(lisn); @@ -1734,11 +1752,27 @@ void xive_router_notify(XiveNotifier *xn, uint32_t lisn) return; } - /* - * The IVRE checks the State Bit Cache at this point. We skip the - * SBC lookup because the state bits of the sources are modeled - * internally in QEMU. - */ + if (!pq_checked) { + bool notify; + uint8_t pq; + + /* PQ cache lookup */ + if (xive_router_get_pq(xrtr, eas_blk, eas_idx, &pq)) { + /* Set FIR */ + g_assert_not_reached(); + } + + notify = xive_esb_trigger(&pq); + + if (xive_router_set_pq(xrtr, eas_blk, eas_idx, &pq)) { + /* Set FIR */ + g_assert_not_reached(); + } + + if (!notify) { + return; + } + } if (!xive_eas_is_valid(&eas)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid LISN %x\n", lisn); |