diff options
Diffstat (limited to 'hw/intc/arm_gic.c')
-rw-r--r-- | hw/intc/arm_gic.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 4ad80e77bb..6abdb14379 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -213,14 +213,24 @@ static void gic_set_running_irq(GICState *s, int cpu, int irq) gic_update(s); } -uint32_t gic_acknowledge_irq(GICState *s, int cpu) +uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs) { int ret, irq, src; int cm = 1 << cpu; - irq = s->current_pending[cpu]; - if (irq == 1023 - || GIC_GET_PRIORITY(irq, cpu) >= s->running_priority[cpu]) { - DPRINTF("ACK no pending IRQ\n"); + + /* gic_get_current_pending_irq() will return 1022 or 1023 appropriately + * for the case where this GIC supports grouping and the pending interrupt + * is in the wrong group. + */ + irq = gic_get_current_pending_irq(s, cpu, attrs);; + + if (irq >= GIC_MAXIRQ) { + DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq); + return irq; + } + + if (GIC_GET_PRIORITY(irq, cpu) >= s->running_priority[cpu]) { + DPRINTF("ACK, pending interrupt (%d) has insufficient priority\n", irq); return 1023; } s->last_active[irq][cpu] = s->running_irq[cpu]; @@ -920,7 +930,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset, } break; case 0x0c: /* Acknowledge */ - *data = gic_acknowledge_irq(s, cpu); + *data = gic_acknowledge_irq(s, cpu, attrs); break; case 0x14: /* Running Priority */ *data = gic_get_running_priority(s, cpu, attrs); |