From: Ruslan Ruslichenko <[email protected]> Call plugin_register_primary_intc() at the end of the realization of both ARM GICv2 and GICv3.
This links the system's primary interrupt controllers ot the plugins subsystem, so that plugins can inject hardware irqs using generic qemu_plugin_set_irq() API. Signed-off-by: Ruslan Ruslichenko <[email protected]> --- hw/intc/arm_gic.c | 28 ++++++++++++++++++++++++++++ hw/intc/arm_gicv3.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 4d4b79e6f3..aef39b3ef7 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -29,6 +29,8 @@ #include "trace.h" #include "system/kvm.h" #include "system/qtest.h" +#include "qemu/plugin.h" + /* #define DEBUG_GIC */ @@ -2096,6 +2098,31 @@ static const MemoryRegionOps gic_viface_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static void gic_plugin_irq_inject(void *opaque, int irq, int cpu, bool pulse) +{ + DeviceState *dev = opaque; + GICState *s = ARM_GIC(dev); + + qemu_irq gic_irq; + + if (irq >= GIC_INTERNAL) { + assert(irq < s->num_irq); + + gic_irq = qdev_get_gpio_in(dev, irq - GIC_INTERNAL); + } else { + assert(cpu < s->num_cpu); + + uint32_t offset = s->num_irq - GIC_INTERNAL + (cpu * GIC_INTERNAL) + irq; + gic_irq = qdev_get_gpio_in(dev, offset); + } + + if (pulse) { + qemu_irq_pulse(gic_irq); + } else { + qemu_irq_raise(gic_irq); + } +} + static void arm_gic_realize(DeviceState *dev, Error **errp) { /* Device instance realize function for the GIC sysbus device */ @@ -2160,6 +2187,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) } } + plugin_register_intc(dev, gic_plugin_irq_inject); } static void arm_gic_class_init(ObjectClass *klass, const void *data) diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c index 542f81ea49..1bae8c9f17 100644 --- a/hw/intc/arm_gicv3.c +++ b/hw/intc/arm_gicv3.c @@ -20,6 +20,8 @@ #include "qemu/module.h" #include "hw/intc/arm_gicv3.h" #include "gicv3_internal.h" +#include "hw/core/irq.h" +#include "qemu/plugin.h" static bool irqbetter(GICv3CPUState *cs, int irq, uint8_t prio, bool nmi) { @@ -434,6 +436,31 @@ static const MemoryRegionOps gic_ops[] = { } }; +static void gicv3_plugin_irq_inject(void *opaque, int irq, int cpu, bool pulse) +{ + DeviceState *dev = opaque; + GICv3State *s = ARM_GICV3(dev); + + qemu_irq gic_irq; + + if (irq >= GIC_INTERNAL) { + assert(irq < s->num_irq); + + gic_irq = qdev_get_gpio_in(dev, irq - GIC_INTERNAL); + } else { + assert(cpu < s->num_cpu); + + uint32_t offset = s->num_irq - GIC_INTERNAL + (cpu * GIC_INTERNAL) + irq; + gic_irq = qdev_get_gpio_in(dev, offset); + } + + if (pulse) { + qemu_irq_pulse(gic_irq); + } else { + qemu_irq_raise(gic_irq); + } +} + static void arm_gic_realize(DeviceState *dev, Error **errp) { /* Device instance realize function for the GIC sysbus device */ @@ -450,6 +477,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops); gicv3_init_cpuif(s); + plugin_register_intc(dev, gicv3_plugin_irq_inject); } static void arm_gicv3_class_init(ObjectClass *klass, const void *data) -- 2.43.0
