armv7m_nvic: Implement ICSR without using internal GIC state

Change the implementation of the Interrupt Control and State Register
in the v7M NVIC to not use the running_irq and last_active internal
state fields in the GIC. These fields don't correspond to state in
a real GIC and will be removed soon.
The changes to the ICSR are:
 * the VECTACTIVE field is documented as identical to the IPSR[8:0]
   field, so implement it that way
 * implement RETTOBASE via looking at the active state bits

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1438089748-5528-2-git-send-email-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2015-09-08 17:38:42 +01:00
parent 8611280505
commit b06c262b45
1 changed files with 6 additions and 7 deletions

View File

@ -185,26 +185,25 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
return cpu->midr;
case 0xd04: /* Interrupt Control State. */
/* VECTACTIVE */
val = s->gic.running_irq[0];
cpu = ARM_CPU(current_cpu);
val = cpu->env.v7m.exception;
if (val == 1023) {
val = 0;
} else if (val >= 32) {
val -= 16;
}
/* RETTOBASE */
if (s->gic.running_irq[0] == 1023
|| s->gic.last_active[s->gic.running_irq[0]][0] == 1023) {
val |= (1 << 11);
}
/* VECTPENDING */
if (s->gic.current_pending[0] != 1023)
val |= (s->gic.current_pending[0] << 12);
/* ISRPENDING */
/* ISRPENDING and RETTOBASE */
for (irq = 32; irq < s->num_irq; irq++) {
if (s->gic.irq_state[irq].pending) {
val |= (1 << 22);
break;
}
if (irq != cpu->env.v7m.exception && s->gic.irq_state[irq].active) {
val |= (1 << 11);
}
}
/* PENDSTSET */
if (s->gic.irq_state[ARMV7M_EXCP_SYSTICK].pending)