From 59c6845adaccaa09c4b21914f90ee44195b8caea Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sun, 4 Mar 2018 21:00:27 -0500 Subject: [PATCH] target/arm: Make CONTROL register banked for v8M Make the CONTROL register banked if v8M security extensions are enabled. Backports commit 8bfc26ea302ec03585d7258a7cf8938f76512730 from qemu --- qemu/target/arm/cpu.h | 5 +++-- qemu/target/arm/helper.c | 21 +++++++++++---------- qemu/target/arm/translate.c | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index db92be4f..c2829415 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -427,7 +427,7 @@ typedef struct CPUARMState { uint32_t other_sp; uint32_t vecbase; uint32_t basepri[2]; - uint32_t control; + uint32_t control[2]; uint32_t ccr; /* Configuration and Control */ uint32_t cfsr; /* Configurable Fault Status */ uint32_t hfsr; /* HardFault Status */ @@ -1659,7 +1659,8 @@ static inline bool arm_v7m_is_handler_mode(CPUARMState *env) static inline int arm_current_el(CPUARMState *env) { if (arm_feature(env, ARM_FEATURE_M)) { - return arm_v7m_is_handler_mode(env) || !(env->v7m.control & 1); + return arm_v7m_is_handler_mode(env) || + !(env->v7m.control[env->v7m.secure] & 1); } if (is_a64(env)) { diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index baf3dc77..e75faad1 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -5307,13 +5307,14 @@ static uint32_t v7m_pop(CPUARMState *env) static void switch_v7m_sp(CPUARMState *env, bool new_spsel) { uint32_t tmp; - bool old_spsel = env->v7m.control & R_V7M_CONTROL_SPSEL_MASK; + uint32_t old_control = env->v7m.control[env->v7m.secure]; + bool old_spsel = old_control & R_V7M_CONTROL_SPSEL_MASK; if (old_spsel != new_spsel) { tmp = env->v7m.other_sp; env->v7m.other_sp = env->regs[13]; env->regs[13] = tmp; - env->v7m.control = deposit32(env->v7m.control, + env->v7m.control[env->v7m.secure] = deposit32(old_control, R_V7M_CONTROL_SPSEL_SHIFT, R_V7M_CONTROL_SPSEL_LENGTH, new_spsel); } @@ -5681,7 +5682,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) } lr = 0xfffffff1; - if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) { + if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) { lr |= 4; } if (!arm_v7m_is_handler_mode(env)) { @@ -8101,7 +8102,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) return xpsr_read(env) & mask; break; case 20: /* CONTROL */ - return env->v7m.control; + return env->v7m.control[env->v7m.secure]; } if (el == 0) { @@ -8110,10 +8111,10 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) switch (reg) { case 8: /* MSP */ - return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ? + return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ? env->v7m.other_sp : env->regs[13]; case 9: /* PSP */ - return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ? + return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ? env->regs[13] : env->v7m.other_sp; case 16: /* PRIMASK */ return env->v7m.primask[env->v7m.secure]; @@ -8170,14 +8171,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) } break; case 8: /* MSP */ - if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) { + if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) { env->v7m.other_sp = val; } else { env->regs[13] = val; } break; case 9: /* PSP */ - if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) { + if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) { env->regs[13] = val; } else { env->v7m.other_sp = val; @@ -8208,8 +8209,8 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) if (!arm_v7m_is_handler_mode(env)) { switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0); } - env->v7m.control &= ~R_V7M_CONTROL_NPRIV_MASK; - env->v7m.control |= val & R_V7M_CONTROL_NPRIV_MASK; + env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK; + env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK; break; default: qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special" diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 9d14164e..13c54da6 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -12518,7 +12518,7 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, if (xpsr & XPSR_EXCP) { mode = "handler"; } else { - if (env->v7m.control & R_V7M_CONTROL_NPRIV_MASK) { + if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) { mode = "unpriv-thread"; } else { mode = "priv-thread";