aboutsummaryrefslogtreecommitdiff
path: root/hw/intc/xive.c
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2022-03-02 06:51:39 +0100
committerCédric Le Goater <clg@kaod.org>2022-03-02 06:51:39 +0100
commit0aa2612a01f233a4a25fb89e8362baf6cf896be6 (patch)
tree843c92a177ce54f209f8f069fa35aa3405d5f938 /hw/intc/xive.c
parentaadf13abaad43dd1f8b6113e516649578af63775 (diff)
downloadqemu-0aa2612a01f233a4a25fb89e8362baf6cf896be6.zip
qemu-0aa2612a01f233a4a25fb89e8362baf6cf896be6.tar.gz
qemu-0aa2612a01f233a4a25fb89e8362baf6cf896be6.tar.bz2
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.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 0d98b95..deb0db2 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);