diff options
author | Cédric Le Goater <clg@kaod.org> | 2019-07-18 13:54:09 +0200 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2019-08-21 17:17:39 +1000 |
commit | 53e934921d660be951167fccad4b6302c4633486 (patch) | |
tree | 201ffb7aa88bae4e03fcb05dbe443af0dcf6cf5d | |
parent | b4e3066684ea9379e09c8c6b0902eceb939fa97c (diff) | |
download | qemu-53e934921d660be951167fccad4b6302c4633486.zip qemu-53e934921d660be951167fccad4b6302c4633486.tar.gz qemu-53e934921d660be951167fccad4b6302c4633486.tar.bz2 |
ppc/xive: Provide unconditional escalation support
When the 'u' bit is set the escalation is said to be 'unconditional'
which means that the ESe PQ bits are not used. Introduce a
xive_router_end_es_notify() routine to share code with the ESn
notification.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20190718115420.19919-7-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | hw/intc/xive.c | 44 | ||||
-rw-r--r-- | include/hw/ppc/xive_regs.h | 2 |
2 files changed, 37 insertions, 9 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 12f0d09..3fe84f3 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1430,6 +1430,27 @@ static bool xive_presenter_notify(XiveRouter *xrtr, uint8_t format, } /* + * Notification using the END ESe/ESn bit (Event State Buffer for + * escalation and notification). Profide futher coalescing in the + * Router. + */ +static bool xive_router_end_es_notify(XiveRouter *xrtr, uint8_t end_blk, + uint32_t end_idx, XiveEND *end, + uint32_t end_esmask) +{ + uint8_t pq = xive_get_field32(end_esmask, end->w1); + bool notify = xive_esb_trigger(&pq); + + if (pq != xive_get_field32(end_esmask, end->w1)) { + end->w1 = xive_set_field32(end_esmask, end->w1, pq); + xive_router_write_end(xrtr, end_blk, end_idx, end, 1); + } + + /* ESe/n[Q]=1 : end of notification */ + return notify; +} + +/* * An END trigger can come from an event trigger (IPI or HW) or from * another chip. We don't model the PowerBus but the END trigger * message has the same parameters than in the function below. @@ -1485,16 +1506,9 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, * even futher coalescing in the Router */ if (!xive_end_is_notify(&end)) { - uint8_t pq = xive_get_field32(END_W1_ESn, end.w1); - bool notify = xive_esb_trigger(&pq); - - if (pq != xive_get_field32(END_W1_ESn, end.w1)) { - end.w1 = xive_set_field32(END_W1_ESn, end.w1, pq); - xive_router_write_end(xrtr, end_blk, end_idx, &end, 1); - } - /* ESn[Q]=1 : end of notification */ - if (!notify) { + if (!xive_router_end_es_notify(xrtr, end_blk, end_idx, + &end, END_W1_ESn)) { return; } } @@ -1559,6 +1573,18 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, } /* + * Check the END ESe (Event State Buffer for escalation) for even + * futher coalescing in the Router + */ + if (!xive_end_is_uncond_escalation(&end)) { + /* ESe[Q]=1 : end of notification */ + if (!xive_router_end_es_notify(xrtr, end_blk, end_idx, + &end, END_W1_ESe)) { + return; + } + } + + /* * The END trigger becomes an Escalation trigger */ xive_router_end_notify(xrtr, diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index b0c68ab..4378d72 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -210,6 +210,8 @@ typedef struct XiveEND { #define xive_end_is_notify(end) (be32_to_cpu((end)->w0) & END_W0_UCOND_NOTIFY) #define xive_end_is_backlog(end) (be32_to_cpu((end)->w0) & END_W0_BACKLOG) #define xive_end_is_escalate(end) (be32_to_cpu((end)->w0) & END_W0_ESCALATE_CTL) +#define xive_end_is_uncond_escalation(end) \ + (be32_to_cpu((end)->w0) & END_W0_UNCOND_ESCALATE) static inline uint64_t xive_end_qaddr(XiveEND *end) { |