aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-09-12 19:14:01 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-09-21 16:31:09 +0100
commit7208b426c7347982af8f5d6f2608cab6b3431ede (patch)
treedfef4f86958ad26723606f311fdc2bb2bc34c450
parent331f4bae6c514a719676d803625cfe197d81a91c (diff)
downloadqemu-7208b426c7347982af8f5d6f2608cab6b3431ede.zip
qemu-7208b426c7347982af8f5d6f2608cab6b3431ede.tar.gz
qemu-7208b426c7347982af8f5d6f2608cab6b3431ede.tar.bz2
nvic: Disable the non-secure HardFault if AIRCR.BFHFNMINS is clear
If AIRCR.BFHFNMINS is clear, then although NonSecure HardFault can still be pended via SHCSR.HARDFAULTPENDED it mustn't actually preempt execution. The simple way to achieve this is to clear the enable bit for it, since the enable bit isn't guest visible. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1505240046-11454-15-git-send-email-peter.maydell@linaro.org
-rw-r--r--hw/intc/armv7m_nvic.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 0c1d591..35225c8 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -937,11 +937,16 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
(R_V7M_AIRCR_SYSRESETREQS_MASK |
R_V7M_AIRCR_BFHFNMINS_MASK |
R_V7M_AIRCR_PRIS_MASK);
- /* BFHFNMINS changes the priority of Secure HardFault */
+ /* BFHFNMINS changes the priority of Secure HardFault, and
+ * allows a pending Non-secure HardFault to preempt (which
+ * we implement by marking it enabled).
+ */
if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
s->sec_vectors[ARMV7M_EXCP_HARD].prio = -3;
+ s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
} else {
s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
+ s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
}
}
nvic_irq_update(s);
@@ -1566,7 +1571,6 @@ static void armv7m_nvic_reset(DeviceState *dev)
NVICState *s = NVIC(dev);
s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
- s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
/* MEM, BUS, and USAGE are enabled through
* the System Handler Control register
*/
@@ -1588,6 +1592,10 @@ static void armv7m_nvic_reset(DeviceState *dev)
/* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */
s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
+ /* If AIRCR.BFHFNMINS is 0 then NS HF is (effectively) disabled */
+ s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
+ } else {
+ s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
}
/* Strictly speaking the reset handler should be enabled.