aboutsummaryrefslogtreecommitdiff
path: root/target/arm/cpu.h
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-10-06 16:46:47 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-10-06 16:46:47 +0100
commitde2db7ec894f11931932ca78cd14a8d2b1389d5b (patch)
tree8f1e5195fb4bab772520ca7c71ef88281b283fa7 /target/arm/cpu.h
parent5b5223997c04b769bb362767cecb5f7ec382c5f0 (diff)
target/arm: Prepare for CONTROL.SPSEL being nonzero in Handler mode
In the v7M architecture, there is an invariant that if the CPU is in Handler mode then the CONTROL.SPSEL bit cannot be nonzero. This in turn means that the current stack pointer is always indicated by CONTROL.SPSEL, even though Handler mode always uses the Main stack pointer. In v8M, this invariant is removed, and CONTROL.SPSEL may now be nonzero in Handler mode (though Handler mode still always uses the Main stack pointer). In preparation for this change, change how we handle this bit: rename switch_v7m_sp() to the now more accurate write_v7m_control_spsel(), and make it check both the handler mode state and the SPSEL bit. Note that this implicitly changes the point at which we switch active SP on exception exit from before we pop the exception frame to after it. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-4-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/cpu.h')
-rw-r--r--target/arm/cpu.h8
1 files changed, 7 insertions, 1 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 8afceca873..ad6eff498b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -991,6 +991,11 @@ void pmccntr_sync(CPUARMState *env);
#define PSTATE_MODE_EL1t 4
#define PSTATE_MODE_EL0t 0
+/* Write a new value to v7m.exception, thus transitioning into or out
+ * of Handler mode; this may result in a change of active stack pointer.
+ */
+void write_v7m_exception(CPUARMState *env, uint32_t new_exc);
+
/* Map EL and handler into a PSTATE_MODE. */
static inline unsigned int aarch64_pstate_mode(unsigned int el, bool handler)
{
@@ -1071,7 +1076,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
env->condexec_bits |= (val >> 8) & 0xfc;
}
if (mask & XPSR_EXCP) {
- env->v7m.exception = val & XPSR_EXCP;
+ /* Note that this only happens on exception exit */
+ write_v7m_exception(env, val & XPSR_EXCP);
}
}