aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/intc/pnv_xive.c20
-rw-r--r--hw/intc/xive.c4
-rw-r--r--include/hw/ppc/xive_regs.h26
3 files changed, 41 insertions, 9 deletions
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index ed6e9d71bb..348f2fdd26 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -385,7 +385,7 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
PnvXive *xive = PNV_XIVE(xrtr);
if (pnv_xive_get_ic(blk) != xive) {
- xive_error(xive, "VST: EAS %x is remote !?", XIVE_SRCNO(blk, idx));
+ xive_error(xive, "VST: EAS %x is remote !?", XIVE_EAS(blk, idx));
return -1;
}
@@ -431,7 +431,7 @@ static void pnv_xive_notify(XiveNotifier *xn, uint32_t srcno)
PnvXive *xive = PNV_XIVE(xn);
uint8_t blk = xive->chip->chip_id;
- xive_router_notify(xn, XIVE_SRCNO(blk, srcno));
+ xive_router_notify(xn, XIVE_EAS(blk, srcno));
}
/*
@@ -1225,12 +1225,24 @@ static const MemoryRegionOps pnv_xive_ic_reg_ops = {
static void pnv_xive_ic_hw_trigger(PnvXive *xive, hwaddr addr, uint64_t val)
{
+ uint8_t blk;
+ uint32_t idx;
+
+ if (val & XIVE_TRIGGER_END) {
+ xive_error(xive, "IC: END trigger at @0x%"HWADDR_PRIx" data 0x%"PRIx64,
+ addr, val);
+ return;
+ }
+
/*
* Forward the source event notification directly to the Router.
* The source interrupt number should already be correctly encoded
* with the chip block id by the sending device (PHB, PSI).
*/
- xive_router_notify(XIVE_NOTIFIER(xive), val);
+ blk = XIVE_EAS_BLOCK(val);
+ idx = XIVE_EAS_INDEX(val);
+
+ xive_router_notify(XIVE_NOTIFIER(xive), XIVE_EAS(blk, idx));
}
static void pnv_xive_ic_notify_write(void *opaque, hwaddr addr, uint64_t val,
@@ -1566,7 +1578,7 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
{
XiveRouter *xrtr = XIVE_ROUTER(xive);
uint8_t blk = xive->chip->chip_id;
- uint32_t srcno0 = XIVE_SRCNO(blk, 0);
+ uint32_t srcno0 = XIVE_EAS(blk, 0);
uint32_t nr_ipis = pnv_xive_nr_ipis(xive);
uint32_t nr_ends = pnv_xive_nr_ends(xive);
XiveEAS eas;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 453d389848..d420c6571e 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1658,8 +1658,8 @@ do_escalation:
void xive_router_notify(XiveNotifier *xn, uint32_t lisn)
{
XiveRouter *xrtr = XIVE_ROUTER(xn);
- uint8_t eas_blk = XIVE_SRCNO_BLOCK(lisn);
- uint32_t eas_idx = XIVE_SRCNO_INDEX(lisn);
+ uint8_t eas_blk = XIVE_EAS_BLOCK(lisn);
+ uint32_t eas_idx = XIVE_EAS_INDEX(lisn);
XiveEAS eas;
/* EAS cache lookup */
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 08c8bf7172..55307cd153 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -22,9 +22,29 @@
/*
* Interrupt source number encoding on PowerBUS
*/
-#define XIVE_SRCNO_BLOCK(srcno) (((srcno) >> 28) & 0xf)
-#define XIVE_SRCNO_INDEX(srcno) ((srcno) & 0x0fffffff)
-#define XIVE_SRCNO(blk, idx) ((uint32_t)(blk) << 28 | (idx))
+/*
+ * Trigger data definition
+ *
+ * The trigger definition is used for triggers both for HW source
+ * interrupts (PHB, PSI), as well as for rerouting interrupts between
+ * Interrupt Controller.
+ *
+ * HW source controllers set bit0 of word0 to ‘0’ as they provide EAS
+ * information (EAS block + EAS index) in the 8 byte data and not END
+ * information, which is use for rerouting interrupts.
+ *
+ * bit1 of word0 to ‘1’ signals that the state bit check has been
+ * performed.
+ */
+#define XIVE_TRIGGER_END PPC_BIT(0)
+#define XIVE_TRIGGER_PQ PPC_BIT(1)
+
+/*
+ * QEMU macros to manipulate the trigger payload in native endian
+ */
+#define XIVE_EAS_BLOCK(n) (((n) >> 28) & 0xf)
+#define XIVE_EAS_INDEX(n) ((n) & 0x0fffffff)
+#define XIVE_EAS(blk, idx) ((uint32_t)(blk) << 28 | (idx))
#define TM_SHIFT 16