[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 04/19] spapr: add support for the LSI interrupt s
From: |
Cédric Le Goater |
Subject: |
[Qemu-devel] [PATCH v2 04/19] spapr: add support for the LSI interrupt sources |
Date: |
Sat, 9 Dec 2017 09:43:23 +0100 |
The 'sent' status of the LSI interrupt source is modeled with the 'P'
bit of the ESB and the assertion status of the source is maintained in
an array under the main sPAPRXive object. The type of the source is
stored in the same array for practical reasons.
The OS will use the H_INT_GET_SOURCE_INFO hcall to determine the type
of an interrupt source.
Signed-off-by: Cédric Le Goater <address@hidden>
---
hw/intc/spapr_xive.c | 54 +++++++++++++++++++++++++++++++++++++++++----
include/hw/ppc/spapr_xive.h | 10 ++++++++-
2 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 43df6814619d..c772c726667f 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -144,6 +144,21 @@ static bool spapr_xive_pq_trigger(sPAPRXive *xive,
uint32_t lisn)
}
/*
+ * LSI interrupt sources use the P bit and a custom assertion flag
+ */
+static bool spapr_xive_lsi_trigger(sPAPRXive *xive, uint32_t lisn)
+{
+ uint8_t old_pq = spapr_xive_pq_get(xive, lisn);
+
+ if (old_pq == XIVE_ESB_RESET &&
+ xive->status[lisn] & XIVE_STATUS_ASSERTED) {
+ spapr_xive_pq_set(xive, lisn, XIVE_ESB_PENDING);
+ return true;
+ }
+ return false;
+}
+
+/*
* XIVE Interrupt Source MMIOs
*/
@@ -165,6 +180,14 @@ static uint64_t spapr_xive_esb_read(void *opaque, hwaddr
addr, unsigned size)
* XIVE_ESB_STORE_EOI support for the interrupt sources
*/
ret = spapr_xive_pq_eoi(xive, lisn);
+
+ /* If the LSI source is still asserted, forward a new source
+ * event notification */
+ if (spapr_xive_irq_is_lsi(xive, lisn)) {
+ if (spapr_xive_lsi_trigger(xive, lisn)) {
+ spapr_xive_irq(xive, lisn);
+ }
+ }
break;
case XIVE_ESB_GET:
@@ -201,6 +224,14 @@ static void spapr_xive_esb_write(void *opaque, hwaddr addr,
* notification
*/
notify = spapr_xive_pq_eoi(xive, lisn);
+
+ /* LSI sources do not set the Q bit but they can still be
+ * asserted, in which case we should forward a new source
+ * event notification
+ */
+ if (spapr_xive_irq_is_lsi(xive, lisn)) {
+ notify = spapr_xive_lsi_trigger(xive, lisn);
+ }
break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid ESB write addr %d\n",
@@ -233,8 +264,17 @@ static void spapr_xive_source_set_irq(void *opaque, int
lisn, int val)
sPAPRXive *xive = SPAPR_XIVE(opaque);
bool notify = false;
- if (val) {
- notify = spapr_xive_pq_trigger(xive, lisn);
+ if (spapr_xive_irq_is_lsi(xive, lisn)) {
+ if (val) {
+ xive->status[lisn] |= XIVE_STATUS_ASSERTED;
+ } else {
+ xive->status[lisn] &= ~XIVE_STATUS_ASSERTED;
+ }
+ notify = spapr_xive_lsi_trigger(xive, lisn);
+ } else {
+ if (val) {
+ notify = spapr_xive_pq_trigger(xive, lisn);
+ }
}
/* Forward the source event notification for routing */
@@ -260,7 +300,8 @@ void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor
*mon)
pq = spapr_xive_pq_get(xive, i);
- monitor_printf(mon, " %4x %s %c%c %08x %08x\n", i,
+ monitor_printf(mon, " %4x %s %s %c%c %08x %08x\n", i,
+ spapr_xive_irq_is_lsi(xive, i) ? "LSI" : "MSI",
ive->w & IVE_MASKED ? "M" : " ",
pq & XIVE_ESB_VAL_P ? 'P' : '-',
pq & XIVE_ESB_VAL_Q ? 'Q' : '-',
@@ -274,6 +315,8 @@ static void spapr_xive_reset(DeviceState *dev)
sPAPRXive *xive = SPAPR_XIVE(dev);
int i;
+ /* Do not clear IRQ's status */
+
/* Mask all valid IVEs in the IRQ number space. */
for (i = 0; i < xive->nr_irqs; i++) {
XiveIVE *ive = &xive->ivt[i];
@@ -301,6 +344,7 @@ static void spapr_xive_realize(DeviceState *dev, Error
**errp)
/* QEMU IRQs */
xive->qirqs = qemu_allocate_irqs(spapr_xive_source_set_irq, xive,
xive->nr_irqs);
+ xive->status = g_malloc0(xive->nr_irqs);
/* Allocate SBEs (State Bit Entry). 2 bits, so 4 entries per byte */
xive->sbe_size = DIV_ROUND_UP(xive->nr_irqs, 4);
@@ -381,7 +425,7 @@ XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn)
return lisn < xive->nr_irqs ? &xive->ivt[lisn] : NULL;
}
-bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn)
+bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn, bool lsi)
{
XiveIVE *ive = spapr_xive_get_ive(xive, lisn);
@@ -390,6 +434,7 @@ bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn)
}
ive->w |= IVE_VALID;
+ xive->status[lisn] |= lsi ? XIVE_STATUS_LSI : 0;
return true;
}
@@ -402,5 +447,6 @@ bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn)
}
ive->w &= ~IVE_VALID;
+ xive->status[lisn] = 0;
return true;
}
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index ecc15d889b74..a7e59fd601d7 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -23,6 +23,9 @@ struct sPAPRXive {
/* Properties */
uint32_t nr_irqs;
+#define XIVE_STATUS_LSI 0x1
+#define XIVE_STATUS_ASSERTED 0x2
+ uint8_t *status;
/* IRQ */
qemu_irq *qirqs;
@@ -37,7 +40,12 @@ struct sPAPRXive {
MemoryRegion esb_iomem;
};
-bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn);
+static inline bool spapr_xive_irq_is_lsi(sPAPRXive *xive, int lisn)
+{
+ return xive->status[lisn] & XIVE_STATUS_LSI;
+}
+
+bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn, bool lsi);
bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn);
void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon);
--
2.13.6
[Qemu-devel] [PATCH v2 04/19] spapr: add support for the LSI interrupt sources,
Cédric Le Goater <=
[Qemu-devel] [PATCH v2 05/19] spapr: introduce a XIVE interrupt presenter model, Cédric Le Goater, 2017/12/09
[Qemu-devel] [PATCH v2 06/19] spapr: introduce the XIVE Event Queues, Cédric Le Goater, 2017/12/09
[Qemu-devel] [PATCH v2 07/19] spapr: push the XIVE EQ data in OS event queue, Cédric Le Goater, 2017/12/09
[Qemu-devel] [PATCH v2 08/19] spapr: notify the CPU when the XIVE interrupt priority is more privileged, Cédric Le Goater, 2017/12/09
[Qemu-devel] [PATCH v2 09/19] spapr: add support for the SET_OS_PENDING command (XIVE), Cédric Le Goater, 2017/12/09
[Qemu-devel] [PATCH v2 10/19] spapr: introduce a 'xive_exploitation' boolean to enable XIVE, Cédric Le Goater, 2017/12/09
[Qemu-devel] [PATCH v2 11/19] spapr: add a sPAPRXive object to the machine, Cédric Le Goater, 2017/12/09
[Qemu-devel] [PATCH v2 12/19] spapr: add hcalls support for the XIVE exploitation interrupt mode, Cédric Le Goater, 2017/12/09
[Qemu-devel] [PATCH v2 13/19] spapr: add device tree support for the XIVE interrupt mode, Cédric Le Goater, 2017/12/09
[Qemu-devel] [PATCH v2 14/19] spapr: introduce a helper to map the XIVE memory regions, Cédric Le Goater, 2017/12/09