mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-10-14 23:13:30 +00:00
target-arm: A64: Break out aarch64_save/restore_sp
Break out code to save/restore AArch64 SP into functions. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Greg Bellows <greg.bellows@linaro.org> Message-id: 1402994746-8328-2-git-send-email-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
9db11cef8c
commit
9208b9617f
|
@ -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)
|
||||||
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 @@
|
||||||
#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)
|
||||||
/* 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)
|
||||||
/* 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)
|
||||||
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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue