hw/intc/armv7m_nvic: for v8.1M VECTPENDING hides S exceptions from NS
In Arm v8.1M the VECTPENDING field in the ICSR has new behaviour: if the register is accessed NonSecure and the highest priority pending enabled exception (that would be returned in the VECTPENDING field) targets Secure, then the VECTPENDING field must read 1 rather than the exception number of the pending exception. Implement this. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210723162146.5167-7-peter.maydell@linaro.org
This commit is contained in:
parent
7caad65756
commit
845d27a913
|
@ -804,6 +804,16 @@ void armv7m_nvic_acknowledge_irq(void *opaque)
|
||||||
nvic_irq_update(s);
|
nvic_irq_update(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool vectpending_targets_secure(NVICState *s)
|
||||||
|
{
|
||||||
|
/* Return true if s->vectpending targets Secure state */
|
||||||
|
if (s->vectpending_is_s_banked) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !exc_is_banked(s->vectpending) &&
|
||||||
|
exc_targets_secure(s, s->vectpending);
|
||||||
|
}
|
||||||
|
|
||||||
void armv7m_nvic_get_pending_irq_info(void *opaque,
|
void armv7m_nvic_get_pending_irq_info(void *opaque,
|
||||||
int *pirq, bool *ptargets_secure)
|
int *pirq, bool *ptargets_secure)
|
||||||
{
|
{
|
||||||
|
@ -813,12 +823,7 @@ void armv7m_nvic_get_pending_irq_info(void *opaque,
|
||||||
|
|
||||||
assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
|
assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
|
||||||
|
|
||||||
if (s->vectpending_is_s_banked) {
|
targets_secure = vectpending_targets_secure(s);
|
||||||
targets_secure = true;
|
|
||||||
} else {
|
|
||||||
targets_secure = !exc_is_banked(pending) &&
|
|
||||||
exc_targets_secure(s, pending);
|
|
||||||
}
|
|
||||||
|
|
||||||
trace_nvic_get_pending_irq_info(pending, targets_secure);
|
trace_nvic_get_pending_irq_info(pending, targets_secure);
|
||||||
|
|
||||||
|
@ -1039,7 +1044,19 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
|
||||||
/* VECTACTIVE */
|
/* VECTACTIVE */
|
||||||
val = cpu->env.v7m.exception;
|
val = cpu->env.v7m.exception;
|
||||||
/* VECTPENDING */
|
/* VECTPENDING */
|
||||||
val |= (s->vectpending & 0x1ff) << 12;
|
if (s->vectpending) {
|
||||||
|
/*
|
||||||
|
* From v8.1M VECTPENDING must read as 1 if accessed as
|
||||||
|
* NonSecure and the highest priority pending and enabled
|
||||||
|
* exception targets Secure.
|
||||||
|
*/
|
||||||
|
int vp = s->vectpending;
|
||||||
|
if (!attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_V8_1M) &&
|
||||||
|
vectpending_targets_secure(s)) {
|
||||||
|
vp = 1;
|
||||||
|
}
|
||||||
|
val |= (vp & 0x1ff) << 12;
|
||||||
|
}
|
||||||
/* ISRPENDING - set if any external IRQ is pending */
|
/* ISRPENDING - set if any external IRQ is pending */
|
||||||
if (nvic_isrpending(s)) {
|
if (nvic_isrpending(s)) {
|
||||||
val |= (1 << 22);
|
val |= (1 << 22);
|
||||||
|
|
Loading…
Reference in a new issue