提交 9208b961 编写于 作者: E Edgar E. Iglesias 提交者: Peter Maydell

target-arm: A64: Break out aarch64_save/restore_sp

Break out code to save/restore AArch64 SP into functions.
Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
Signed-off-by: NEdgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: NGreg Bellows <greg.bellows@linaro.org>
Message-id: 1402994746-8328-2-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
上级 9db11cef
...@@ -105,6 +105,24 @@ enum arm_fprounding { ...@@ -105,6 +105,24 @@ enum arm_fprounding {
int arm_rmode_to_sf(int rmode); int arm_rmode_to_sf(int rmode);
static inline void aarch64_save_sp(CPUARMState *env, int el)
{
if (env->pstate & PSTATE_SP) {
env->sp_el[el] = env->xregs[31];
} else {
env->sp_el[0] = env->xregs[31];
}
}
static inline void aarch64_restore_sp(CPUARMState *env, int el)
{
if (env->pstate & PSTATE_SP) {
env->xregs[31] = env->sp_el[el];
} else {
env->xregs[31] = env->sp_el[0];
}
}
static inline void update_spsel(CPUARMState *env, uint32_t imm) static inline void update_spsel(CPUARMState *env, uint32_t imm)
{ {
unsigned int cur_el = arm_current_pl(env); unsigned int cur_el = arm_current_pl(env);
...@@ -114,21 +132,14 @@ static inline void update_spsel(CPUARMState *env, uint32_t imm) ...@@ -114,21 +132,14 @@ static inline void update_spsel(CPUARMState *env, uint32_t imm)
if (!((imm ^ env->pstate) & PSTATE_SP)) { if (!((imm ^ env->pstate) & PSTATE_SP)) {
return; return;
} }
aarch64_save_sp(env, cur_el);
env->pstate = deposit32(env->pstate, 0, 1, imm); env->pstate = deposit32(env->pstate, 0, 1, imm);
/* We rely on illegal updates to SPsel from EL0 to get trapped /* We rely on illegal updates to SPsel from EL0 to get trapped
* at translation time. * at translation time.
*/ */
assert(cur_el >= 1 && cur_el <= 3); assert(cur_el >= 1 && cur_el <= 3);
if (env->pstate & PSTATE_SP) { aarch64_restore_sp(env, cur_el);
/* Switch from using SP_EL0 to using SP_ELx */
env->sp_el[0] = env->xregs[31];
env->xregs[31] = env->sp_el[cur_el];
} else {
/* Switch from SP_EL0 to SP_ELx */
env->sp_el[cur_el] = env->xregs[31];
env->xregs[31] = env->sp_el[0];
}
} }
/* Valid Syndrome Register EC field values */ /* Valid Syndrome Register EC field values */
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "kvm_arm.h" #include "kvm_arm.h"
#include "cpu.h" #include "cpu.h"
#include "internals.h"
#include "hw/arm/arm.h" #include "hw/arm/arm.h"
static inline void set_feature(uint64_t *features, int feature) static inline void set_feature(uint64_t *features, int feature)
...@@ -132,11 +133,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) ...@@ -132,11 +133,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
/* KVM puts SP_EL0 in regs.sp and SP_EL1 in regs.sp_el1. On the /* KVM puts SP_EL0 in regs.sp and SP_EL1 in regs.sp_el1. On the
* QEMU side we keep the current SP in xregs[31] as well. * QEMU side we keep the current SP in xregs[31] as well.
*/ */
if (env->pstate & PSTATE_SP) { aarch64_save_sp(env, 1);
env->sp_el[1] = env->xregs[31];
} else {
env->sp_el[0] = env->xregs[31];
}
reg.id = AARCH64_CORE_REG(regs.sp); reg.id = AARCH64_CORE_REG(regs.sp);
reg.addr = (uintptr_t) &env->sp_el[0]; reg.addr = (uintptr_t) &env->sp_el[0];
...@@ -235,11 +232,7 @@ int kvm_arch_get_registers(CPUState *cs) ...@@ -235,11 +232,7 @@ int kvm_arch_get_registers(CPUState *cs)
/* KVM puts SP_EL0 in regs.sp and SP_EL1 in regs.sp_el1. On the /* KVM puts SP_EL0 in regs.sp and SP_EL1 in regs.sp_el1. On the
* QEMU side we keep the current SP in xregs[31] as well. * QEMU side we keep the current SP in xregs[31] as well.
*/ */
if (env->pstate & PSTATE_SP) { aarch64_restore_sp(env, 1);
env->xregs[31] = env->sp_el[1];
} else {
env->xregs[31] = env->sp_el[0];
}
reg.id = AARCH64_CORE_REG(regs.pc); reg.id = AARCH64_CORE_REG(regs.pc);
reg.addr = (uintptr_t) &env->pc; reg.addr = (uintptr_t) &env->pc;
......
...@@ -376,11 +376,7 @@ void HELPER(exception_return)(CPUARMState *env) ...@@ -376,11 +376,7 @@ void HELPER(exception_return)(CPUARMState *env)
uint32_t spsr = env->banked_spsr[spsr_idx]; uint32_t spsr = env->banked_spsr[spsr_idx];
int new_el, i; int new_el, i;
if (env->pstate & PSTATE_SP) { aarch64_save_sp(env, cur_el);
env->sp_el[cur_el] = env->xregs[31];
} else {
env->sp_el[0] = env->xregs[31];
}
env->exclusive_addr = -1; env->exclusive_addr = -1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册