aboutsummaryrefslogtreecommitdiff
path: root/hw
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
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')
-rw-r--r--hw/intc/armv7m_nvic.c26
-rw-r--r--hw/intc/trace-events4
2 files changed, 22 insertions, 8 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 */
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 29bd308bf2..b86f242b0f 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -176,8 +176,8 @@ nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending irq %d secure-bank %d (enabled: %d priority %d)"
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
-nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (prio %d)"
-nvic_complete_irq(int irq) "NVIC complete IRQ %d"
+nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
+nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"