diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-09-12 19:14:06 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-09-21 16:31:09 +0100 |
commit | 5cb18069d7b9486126d1d6f08b7ffd28f57a4fa3 (patch) | |
tree | 822d0e74cca1f64d64d47cdcd32cccd9aab5cd7a /hw/intc/armv7m_nvic.c | |
parent | 437d59c17e96976a567ad1547e272cdfe4a5f1d7 (diff) | |
download | qemu-5cb18069d7b9486126d1d6f08b7ffd28f57a4fa3.zip qemu-5cb18069d7b9486126d1d6f08b7ffd28f57a4fa3.tar.gz qemu-5cb18069d7b9486126d1d6f08b7ffd28f57a4fa3.tar.bz2 |
nvic: Support banked exceptions in acknowledge and complete
Update armv7m_nvic_acknowledge_irq() and armv7m_nvic_complete_irq()
to handle banked exceptions:
* acknowledge needs to use the correct vector, which may be
in sec_vectors[]
* acknowledge needs to return to its caller whether the
exception should be taken to secure or non-secure state
* complete needs its caller to tell it whether the exception
being completed is a secure one or not
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 1505240046-11454-20-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'hw/intc/armv7m_nvic.c')
-rw-r--r-- | hw/intc/armv7m_nvic.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 19b0be1..d90d8d0 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -586,24 +586,32 @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure) } /* Make pending IRQ active. */ -void armv7m_nvic_acknowledge_irq(void *opaque) +bool armv7m_nvic_acknowledge_irq(void *opaque) { NVICState *s = (NVICState *)opaque; CPUARMState *env = &s->cpu->env; const int pending = s->vectpending; const int running = nvic_exec_prio(s); VecInfo *vec; + bool targets_secure; assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); - vec = &s->vectors[pending]; + if (s->vectpending_is_s_banked) { + vec = &s->sec_vectors[pending]; + targets_secure = true; + } else { + vec = &s->vectors[pending]; + targets_secure = !exc_is_banked(s->vectpending) && + exc_targets_secure(s, s->vectpending); + } assert(vec->enabled); assert(vec->pending); assert(s->vectpending_prio < running); - trace_nvic_acknowledge_irq(pending, s->vectpending_prio); + trace_nvic_acknowledge_irq(pending, s->vectpending_prio, targets_secure); vec->active = 1; vec->pending = 0; @@ -611,9 +619,11 @@ void armv7m_nvic_acknowledge_irq(void *opaque) env->v7m.exception = s->vectpending; nvic_irq_update(s); + + return targets_secure; } -int armv7m_nvic_complete_irq(void *opaque, int irq) +int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure) { NVICState *s = (NVICState *)opaque; VecInfo *vec; @@ -621,9 +631,13 @@ int armv7m_nvic_complete_irq(void *opaque, int irq) assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); - vec = &s->vectors[irq]; + if (secure && exc_is_banked(irq)) { + vec = &s->sec_vectors[irq]; + } else { + vec = &s->vectors[irq]; + } - trace_nvic_complete_irq(irq); + trace_nvic_complete_irq(irq, secure); if (!vec->active) { /* Tell the caller this was an illegal exception return */ |