target/arm: Export arm_v7m_get_sp_ptr
Allow the function to be used outside of m_helper.c. Move to be outside of ifndef CONFIG_USER_ONLY block. Rename from get_v7m_sp_ptr. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: David Reiss <dreiss@meta.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230227213329.793795-14-richard.henderson@linaro.org [rth: Split out of a larger patch] Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
48688c9441
commit
6c8676512f
@ -1360,6 +1360,16 @@ void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
|
||||
/* Read the CONTROL register as the MRS instruction would. */
|
||||
uint32_t arm_v7m_mrs_control(CPUARMState *env, uint32_t secure);
|
||||
|
||||
/*
|
||||
* Return a pointer to the location where we currently store the
|
||||
* stack pointer for the requested security state and thread mode.
|
||||
* This pointer will become invalid if the CPU state is updated
|
||||
* such that the stack pointers are switched around (eg changing
|
||||
* the SPSEL control bit).
|
||||
*/
|
||||
uint32_t *arm_v7m_get_sp_ptr(CPUARMState *env, bool secure,
|
||||
bool threadmode, bool spsel);
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
|
||||
#else
|
||||
|
@ -650,42 +650,6 @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
|
||||
arm_rebuild_hflags(env);
|
||||
}
|
||||
|
||||
static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
|
||||
bool spsel)
|
||||
{
|
||||
/*
|
||||
* Return a pointer to the location where we currently store the
|
||||
* stack pointer for the requested security state and thread mode.
|
||||
* This pointer will become invalid if the CPU state is updated
|
||||
* such that the stack pointers are switched around (eg changing
|
||||
* the SPSEL control bit).
|
||||
* Compare the v8M ARM ARM pseudocode LookUpSP_with_security_mode().
|
||||
* Unlike that pseudocode, we require the caller to pass us in the
|
||||
* SPSEL control bit value; this is because we also use this
|
||||
* function in handling of pushing of the callee-saves registers
|
||||
* part of the v8M stack frame (pseudocode PushCalleeStack()),
|
||||
* and in the tailchain codepath the SPSEL bit comes from the exception
|
||||
* return magic LR value from the previous exception. The pseudocode
|
||||
* opencodes the stack-selection in PushCalleeStack(), but we prefer
|
||||
* to make this utility function generic enough to do the job.
|
||||
*/
|
||||
bool want_psp = threadmode && spsel;
|
||||
|
||||
if (secure == env->v7m.secure) {
|
||||
if (want_psp == v7m_using_psp(env)) {
|
||||
return &env->regs[13];
|
||||
} else {
|
||||
return &env->v7m.other_sp;
|
||||
}
|
||||
} else {
|
||||
if (want_psp) {
|
||||
return &env->v7m.other_ss_psp;
|
||||
} else {
|
||||
return &env->v7m.other_ss_msp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
|
||||
uint32_t *pvec)
|
||||
{
|
||||
@ -810,7 +774,7 @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
|
||||
!mode;
|
||||
|
||||
mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, M_REG_S, priv);
|
||||
frame_sp_p = get_v7m_sp_ptr(env, M_REG_S, mode,
|
||||
frame_sp_p = arm_v7m_get_sp_ptr(env, M_REG_S, mode,
|
||||
lr & R_V7M_EXCRET_SPSEL_MASK);
|
||||
want_psp = mode && (lr & R_V7M_EXCRET_SPSEL_MASK);
|
||||
if (want_psp) {
|
||||
@ -1656,10 +1620,8 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
|
||||
* use 'frame_sp_p' after we do something that makes it invalid.
|
||||
*/
|
||||
bool spsel = env->v7m.control[return_to_secure] & R_V7M_CONTROL_SPSEL_MASK;
|
||||
uint32_t *frame_sp_p = get_v7m_sp_ptr(env,
|
||||
return_to_secure,
|
||||
!return_to_handler,
|
||||
spsel);
|
||||
uint32_t *frame_sp_p = arm_v7m_get_sp_ptr(env, return_to_secure,
|
||||
!return_to_handler, spsel);
|
||||
uint32_t frameptr = *frame_sp_p;
|
||||
bool pop_ok = true;
|
||||
ARMMMUIdx mmu_idx;
|
||||
@ -1965,7 +1927,7 @@ static bool do_v7m_function_return(ARMCPU *cpu)
|
||||
threadmode = !arm_v7m_is_handler_mode(env);
|
||||
spsel = env->v7m.control[M_REG_S] & R_V7M_CONTROL_SPSEL_MASK;
|
||||
|
||||
frame_sp_p = get_v7m_sp_ptr(env, true, threadmode, spsel);
|
||||
frame_sp_p = arm_v7m_get_sp_ptr(env, true, threadmode, spsel);
|
||||
frameptr = *frame_sp_p;
|
||||
|
||||
/*
|
||||
@ -2900,3 +2862,39 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
uint32_t *arm_v7m_get_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
|
||||
bool spsel)
|
||||
{
|
||||
/*
|
||||
* Return a pointer to the location where we currently store the
|
||||
* stack pointer for the requested security state and thread mode.
|
||||
* This pointer will become invalid if the CPU state is updated
|
||||
* such that the stack pointers are switched around (eg changing
|
||||
* the SPSEL control bit).
|
||||
* Compare the v8M ARM ARM pseudocode LookUpSP_with_security_mode().
|
||||
* Unlike that pseudocode, we require the caller to pass us in the
|
||||
* SPSEL control bit value; this is because we also use this
|
||||
* function in handling of pushing of the callee-saves registers
|
||||
* part of the v8M stack frame (pseudocode PushCalleeStack()),
|
||||
* and in the tailchain codepath the SPSEL bit comes from the exception
|
||||
* return magic LR value from the previous exception. The pseudocode
|
||||
* opencodes the stack-selection in PushCalleeStack(), but we prefer
|
||||
* to make this utility function generic enough to do the job.
|
||||
*/
|
||||
bool want_psp = threadmode && spsel;
|
||||
|
||||
if (secure == env->v7m.secure) {
|
||||
if (want_psp == v7m_using_psp(env)) {
|
||||
return &env->regs[13];
|
||||
} else {
|
||||
return &env->v7m.other_sp;
|
||||
}
|
||||
} else {
|
||||
if (want_psp) {
|
||||
return &env->v7m.other_ss_psp;
|
||||
} else {
|
||||
return &env->v7m.other_ss_msp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user