hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling

The PENDNMISET/CLR bits in the ICSR should be RAZ/WI from
NonSecure state if the AIRCR.BFHFNMINS bit is zero. We had
misimplemented this as making the bits RAZ/WI from both
Secure and NonSecure states. Fix this bug by checking
attrs.secure so that Secure code can pend and unpend NMIs.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180209165810.6668-3-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2018-02-15 18:29:37 +00:00
parent 5a53e2c1dc
commit 4f2eff36ad

View File

@ -830,8 +830,8 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
}
}
/* NMIPENDSET */
if ((cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
s->vectors[ARMV7M_EXCP_NMI].pending) {
if ((attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))
&& s->vectors[ARMV7M_EXCP_NMI].pending) {
val |= (1 << 31);
}
/* ISRPREEMPT: RES0 when halting debug not implemented */
@ -1193,7 +1193,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
break;
}
case 0xd04: /* Interrupt Control State (ICSR) */
if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
if (attrs.secure || cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
if (value & (1 << 31)) {
armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
} else if (value & (1 << 30) &&