aboutsummaryrefslogtreecommitdiff
path: root/hw/intc/armv7m_nvic.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/intc/armv7m_nvic.c')
-rw-r--r--hw/intc/armv7m_nvic.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index fff6e69..131b593 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -213,6 +213,7 @@ static void nvic_recompute_state_secure(NVICState *s)
int active_prio = NVIC_NOEXC_PRIO;
int pend_irq = 0;
bool pending_is_s_banked = false;
+ int pend_subprio = 0;
/* R_CQRV: precedence is by:
* - lowest group priority; if both the same then
@@ -226,7 +227,7 @@ static void nvic_recompute_state_secure(NVICState *s)
for (i = 1; i < s->num_irq; i++) {
for (bank = M_REG_S; bank >= M_REG_NS; bank--) {
VecInfo *vec;
- int prio;
+ int prio, subprio;
bool targets_secure;
if (bank == M_REG_S) {
@@ -241,8 +242,12 @@ static void nvic_recompute_state_secure(NVICState *s)
}
prio = exc_group_prio(s, vec->prio, targets_secure);
- if (vec->enabled && vec->pending && prio < pend_prio) {
+ subprio = vec->prio & ~nvic_gprio_mask(s, targets_secure);
+ if (vec->enabled && vec->pending &&
+ ((prio < pend_prio) ||
+ (prio == pend_prio && prio >= 0 && subprio < pend_subprio))) {
pend_prio = prio;
+ pend_subprio = subprio;
pend_irq = i;
pending_is_s_banked = (bank == M_REG_S);
}