aboutsummaryrefslogtreecommitdiff
path: root/hw/intc/armv7m_nvic.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-09-12 19:14:06 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-09-21 16:31:09 +0100
commit5cb18069d7b9486126d1d6f08b7ffd28f57a4fa3 (patch)
tree822d0e74cca1f64d64d47cdcd32cccd9aab5cd7a /hw/intc/armv7m_nvic.c
parent437d59c17e96976a567ad1547e272cdfe4a5f1d7 (diff)
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.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 19b0be1576..d90d8d0784 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 */