target/arm: Handle SPSEL and current stack being out of sync in MSP/PSP reads

For v8M it is possible for the CONTROL.SPSEL bit value and the
current stack to be out of sync. This means we need to update
the checks used in reads and writes of the PSP and MSP special
registers to use v7m_using_psp() rather than directly checking
the SPSEL bit in the control register.

Backports commit 1169d3aa5b19adca9384d954d80e1f48da388284 from qemu
This commit is contained in:
Peter Maydell 2018-03-05 13:09:21 -05:00 committed by Lioncash
parent 64a535ea8c
commit 6713884243
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -9142,11 +9142,9 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
switch (reg) {
case 8: /* MSP */
return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
env->v7m.other_sp : env->regs[13];
return v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13];
case 9: /* PSP */
return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
env->regs[13] : env->v7m.other_sp;
return v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp;
case 16: /* PRIMASK */
return env->v7m.primask[env->v7m.secure];
case 17: /* BASEPRI */
@ -9256,14 +9254,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
}
break;
case 8: /* MSP */
if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
if (v7m_using_psp(env)) {
env->v7m.other_sp = val;
} else {
env->regs[13] = val;
}
break;
case 9: /* PSP */
if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
if (v7m_using_psp(env)) {
env->regs[13] = val;
} else {
env->v7m.other_sp = val;