These are very similar to the XICS handlers in a simpler form. They make use of a status array for the LSI interrupts. The spapr_xive_irq() routine in charge of triggering the CPU interrupt line will be filled later on.
Signed-off-by: Cédric Le Goater <c...@kaod.org> --- hw/intc/spapr_xive.c | 55 +++++++++++++++++++++++++++++++++++++++++++-- include/hw/ppc/spapr_xive.h | 14 +++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index b2fc3007c85f..66c533fb1d78 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -26,6 +26,47 @@ #include "xive-internal.h" +static void spapr_xive_irq(sPAPRXive *xive, int lisn) +{ + +} + +/* + * XIVE Interrupt Source + */ +static void spapr_xive_source_set_irq_msi(sPAPRXive *xive, int lisn, int val) +{ + if (val) { + spapr_xive_irq(xive, lisn); + } +} + +static void spapr_xive_source_set_irq_lsi(sPAPRXive *xive, int lisn, int val) +{ + if (val) { + xive->status[lisn] |= XIVE_STATUS_ASSERTED; + } else { + xive->status[lisn] &= ~XIVE_STATUS_ASSERTED; + } + + if (xive->status[lisn] & XIVE_STATUS_ASSERTED && + !(xive->status[lisn] & XIVE_STATUS_SENT)) { + xive->status[lisn] |= XIVE_STATUS_SENT; + spapr_xive_irq(xive, lisn); + } +} + +static void spapr_xive_source_set_irq(void *opaque, int lisn, int val) +{ + sPAPRXive *xive = SPAPR_XIVE(opaque); + + if (spapr_xive_irq_is_lsi(xive, lisn)) { + spapr_xive_source_set_irq_lsi(xive, lisn, val); + } else { + spapr_xive_source_set_irq_msi(xive, lisn, val); + } +} + /* * Main XIVE object */ @@ -41,7 +82,8 @@ void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon) continue; } - monitor_printf(mon, " %4x %s %08x %08x\n", i, + monitor_printf(mon, " %4x %s %s %08x %08x\n", i, + spapr_xive_irq_is_lsi(xive, i) ? "LSI" : "MSI", ive->w & IVE_MASKED ? "M" : " ", (int) GETFIELD(IVE_EQ_INDEX, ive->w), (int) GETFIELD(IVE_EQ_DATA, ive->w)); @@ -53,6 +95,8 @@ void spapr_xive_reset(void *dev) sPAPRXive *xive = SPAPR_XIVE(dev); int i; + /* Do not clear IRQs status */ + /* Mask all valid IVEs in the IRQ number space. */ for (i = 0; i < xive->nr_irqs; i++) { XiveIVE *ive = &xive->ivt[i]; @@ -71,6 +115,11 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) return; } + /* QEMU IRQs */ + xive->qirqs = qemu_allocate_irqs(spapr_xive_source_set_irq, xive, + xive->nr_irqs); + xive->status = g_malloc0(xive->nr_irqs); + /* Allocate the IVT (Interrupt Virtualization Table) */ xive->ivt = g_malloc0(xive->nr_irqs * sizeof(XiveIVE)); @@ -102,6 +151,7 @@ static const VMStateDescription vmstate_spapr_xive = { VMSTATE_UINT32_EQUAL(nr_irqs, sPAPRXive, NULL), VMSTATE_STRUCT_VARRAY_UINT32_ALLOC(ivt, sPAPRXive, nr_irqs, 1, vmstate_spapr_xive_ive, XiveIVE), + VMSTATE_VBUFFER_UINT32(status, sPAPRXive, 1, NULL, nr_irqs), VMSTATE_END_OF_LIST() }, }; @@ -140,7 +190,7 @@ XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn) return lisn < xive->nr_irqs ? &xive->ivt[lisn] : NULL; } -bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn) +bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn, bool lsi) { XiveIVE *ive = spapr_xive_get_ive(xive, lisn); @@ -149,6 +199,7 @@ bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn) } ive->w |= IVE_VALID; + xive->status[lisn] |= lsi ? XIVE_STATUS_LSI : 0; return true; } diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 795b3f4ded7c..6a799cdaba66 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -33,11 +33,23 @@ struct sPAPRXive { /* Properties */ uint32_t nr_irqs; + /* IRQ */ + qemu_irq *qirqs; +#define XIVE_STATUS_LSI 0x1 +#define XIVE_STATUS_ASSERTED 0x2 +#define XIVE_STATUS_SENT 0x4 + uint8_t *status; + /* XIVE internal tables */ XiveIVE *ivt; }; -bool spapr_xive_irq_set(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_set(sPAPRXive *xive, uint32_t lisn, bool lsi); bool spapr_xive_irq_unset(sPAPRXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); -- 2.13.6