mirror of https://gitee.com/openkylin/qemu.git
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>
This commit is contained in:
parent
b4e3066684
commit
53e934921d
|
@ -1429,6 +1429,27 @@ static bool xive_presenter_notify(XiveRouter *xrtr, uint8_t format,
|
|||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -1558,6 +1572,18 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk,
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue