aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/armv7m_nvic.c23
-rw-r--r--hw/intc/trace-events2
2 files changed, 14 insertions, 11 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index a11df3d..fa5dd23 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -61,10 +61,10 @@ static const uint8_t nvic_id[] = {
static int nvic_pending_prio(NVICState *s)
{
- /* return the priority of the current pending interrupt,
+ /* return the group priority of the current pending interrupt,
* or NVIC_NOEXC_PRIO if no interrupt is pending
*/
- return s->vectpending ? s->vectors[s->vectpending].prio : NVIC_NOEXC_PRIO;
+ return s->vectpending_prio;
}
/* Return the value of the ISCR RETTOBASE bit:
@@ -156,10 +156,17 @@ static void nvic_recompute_state(NVICState *s)
active_prio &= nvic_gprio_mask(s);
}
+ if (pend_prio > 0) {
+ pend_prio &= nvic_gprio_mask(s);
+ }
+
s->vectpending = pend_irq;
+ s->vectpending_prio = pend_prio;
s->exception_prio = active_prio;
- trace_nvic_recompute_state(s->vectpending, s->exception_prio);
+ trace_nvic_recompute_state(s->vectpending,
+ s->vectpending_prio,
+ s->exception_prio);
}
/* Return the current execution priority of the CPU
@@ -323,7 +330,6 @@ void armv7m_nvic_acknowledge_irq(void *opaque)
CPUARMState *env = &s->cpu->env;
const int pending = s->vectpending;
const int running = nvic_exec_prio(s);
- int pendgroupprio;
VecInfo *vec;
assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
@@ -333,13 +339,9 @@ void armv7m_nvic_acknowledge_irq(void *opaque)
assert(vec->enabled);
assert(vec->pending);
- pendgroupprio = vec->prio;
- if (pendgroupprio > 0) {
- pendgroupprio &= nvic_gprio_mask(s);
- }
- assert(pendgroupprio < running);
+ assert(s->vectpending_prio < running);
- trace_nvic_acknowledge_irq(pending, vec->prio);
+ trace_nvic_acknowledge_irq(pending, s->vectpending_prio);
vec->active = 1;
vec->pending = 0;
@@ -1255,6 +1257,7 @@ static void armv7m_nvic_reset(DeviceState *dev)
s->exception_prio = NVIC_NOEXC_PRIO;
s->vectpending = 0;
s->vectpending_is_s_banked = false;
+ s->vectpending_prio = NVIC_NOEXC_PRIO;
}
static void nvic_systick_trigger(void *opaque, int n, int level)
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 4762329..5635a5f 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -167,7 +167,7 @@ gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor 0x%x
gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pending SGI %d"
# hw/intc/armv7m_nvic.c
-nvic_recompute_state(int vectpending, int exception_prio) "NVIC state recomputed: vectpending %d exception_prio %d"
+nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"
nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d priority %d"
nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d"
nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d"