diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-09-08 17:38:42 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-09-08 17:38:42 +0100 |
commit | b06c262b45cf7afcf56dd0f2189ad8948b117e7d (patch) | |
tree | 406180418657b11461ab30f72b547426ecdd0797 /hw/intc | |
parent | 8611280505119e296757a60711a881341603fa5a (diff) | |
download | qemu-b06c262b45cf7afcf56dd0f2189ad8948b117e7d.zip qemu-b06c262b45cf7afcf56dd0f2189ad8948b117e7d.tar.gz qemu-b06c262b45cf7afcf56dd0f2189ad8948b117e7d.tar.bz2 |
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
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/armv7m_nvic.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index e13b729..3ec8408 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -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) |