hw/arm/armv7m_nvic: Check subpriority in nvic_recompute_state_secure()
Rule R_CQRV says that if two pending interrupts have the same group priority then ties are broken by looking at the subpriority. We had a comment describing this but had forgotten to actually implement the subpriority comparison. Correct the omission. (The further tie break rules of "lowest exception number" and "secure before non-secure" are handled implicitly by the order in which we iterate through the exceptions in the loops.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20190430131439.25251-2-peter.maydell@linaro.org
This commit is contained in:
parent
946376c21b
commit
b01e2f0284
@ -213,6 +213,7 @@ static void nvic_recompute_state_secure(NVICState *s)
|
|||||||
int active_prio = NVIC_NOEXC_PRIO;
|
int active_prio = NVIC_NOEXC_PRIO;
|
||||||
int pend_irq = 0;
|
int pend_irq = 0;
|
||||||
bool pending_is_s_banked = false;
|
bool pending_is_s_banked = false;
|
||||||
|
int pend_subprio = 0;
|
||||||
|
|
||||||
/* R_CQRV: precedence is by:
|
/* R_CQRV: precedence is by:
|
||||||
* - lowest group priority; if both the same then
|
* - 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 (i = 1; i < s->num_irq; i++) {
|
||||||
for (bank = M_REG_S; bank >= M_REG_NS; bank--) {
|
for (bank = M_REG_S; bank >= M_REG_NS; bank--) {
|
||||||
VecInfo *vec;
|
VecInfo *vec;
|
||||||
int prio;
|
int prio, subprio;
|
||||||
bool targets_secure;
|
bool targets_secure;
|
||||||
|
|
||||||
if (bank == M_REG_S) {
|
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);
|
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_prio = prio;
|
||||||
|
pend_subprio = subprio;
|
||||||
pend_irq = i;
|
pend_irq = i;
|
||||||
pending_is_s_banked = (bank == M_REG_S);
|
pending_is_s_banked = (bank == M_REG_S);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user