Skip to content

Commit

Permalink
hw/intc/arm_gic: Change behavior of EOIR writes
Browse files Browse the repository at this point in the history
Grouping (GICv2) and Security Extensions change the behavior of EOIR
writes. Completing Group0 interrupts is only allowed from Secure state.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1430502643-25909-13-git-send-email-peter.maydell@linaro.org
Message-id: 1429113742-8371-13-git-send-email-greg.bellows@linaro.org
[PMM: Rather than go to great lengths to ignore the UNPREDICTABLE case
 of a Secure EOI of a Group1 (NS) irq with AckCtl == 0, we just let
 it fall through; add a comment about it.]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
Fabian Aggeler authored and pm215 committed May 12, 2015
1 parent 7c0fa10 commit f9c6a7f
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
14 changes: 12 additions & 2 deletions hw/intc/arm_gic.c
Expand Up @@ -382,7 +382,7 @@ static uint8_t gic_get_running_priority(GICState *s, int cpu, MemTxAttrs attrs)
}
}

void gic_complete_irq(GICState *s, int cpu, int irq)
void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
{
int update = 0;
int cm = 1 << cpu;
Expand Down Expand Up @@ -412,6 +412,16 @@ void gic_complete_irq(GICState *s, int cpu, int irq)
}
}

if (s->security_extn && !attrs.secure && !GIC_TEST_GROUP(irq, cm)) {
DPRINTF("Non-secure EOI for Group0 interrupt %d ignored\n", irq);
return;
}

/* Secure EOI with GICC_CTLR.AckCtl == 0 when the IRQ is a Group 1
* interrupt is UNPREDICTABLE. We choose to handle it as if AckCtl == 1,
* i.e. go ahead and complete the irq anyway.
*/

if (irq != s->running_irq[cpu]) {
/* Complete an IRQ that is not currently running. */
int tmp = s->running_irq[cpu];
Expand Down Expand Up @@ -959,7 +969,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
}
break;
case 0x10: /* End Of Interrupt */
gic_complete_irq(s, cpu, value & 0x3ff);
gic_complete_irq(s, cpu, value & 0x3ff, attrs);
return MEMTX_OK;
case 0x1c: /* Aliased Binary Point */
if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) {
Expand Down
2 changes: 1 addition & 1 deletion hw/intc/armv7m_nvic.c
Expand Up @@ -144,7 +144,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq)
nvic_state *s = (nvic_state *)opaque;
if (irq >= 16)
irq += 16;
gic_complete_irq(&s->gic, 0, irq);
gic_complete_irq(&s->gic, 0, irq, MEMTXATTRS_UNSPECIFIED);
}

static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
Expand Down
2 changes: 1 addition & 1 deletion hw/intc/gic_internal.h
Expand Up @@ -79,7 +79,7 @@

void gic_set_pending_private(GICState *s, int cpu, int irq);
uint32_t gic_acknowledge_irq(GICState *s, int cpu);
void gic_complete_irq(GICState *s, int cpu, int irq);
void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs);
void gic_update(GICState *s);
void gic_init_irqs_and_distributor(GICState *s);
void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val,
Expand Down

0 comments on commit f9c6a7f

Please sign in to comment.