mirror of https://gitee.com/openkylin/qemu.git
target-arm: Add and use symbolic names for register banks
Add BANK_<cpumode> #defines to index banked registers. Suggested-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
130d0bc659
commit
99a99c1fc8
|
@ -3130,7 +3130,8 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
|
|||
{ .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
|
||||
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[1]) },
|
||||
.access = PL1_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
|
||||
/* We rely on the access checks not allowing the guest to write to the
|
||||
* state field when SPSel indicates that it's being used as the stack
|
||||
* pointer.
|
||||
|
@ -3299,23 +3300,28 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
|
|||
{ .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[6]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
|
||||
{ .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[4]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) },
|
||||
{ .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[2]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) },
|
||||
{ .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[3]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) },
|
||||
{ .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[5]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) },
|
||||
{ .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
|
||||
.access = PL2_RW, .writefn = vbar_write,
|
||||
|
@ -3552,7 +3558,8 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
|
|||
{ .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
|
||||
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[7]) },
|
||||
.access = PL3_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) },
|
||||
{ .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
|
||||
.access = PL3_RW, .writefn = vbar_write,
|
||||
|
@ -5183,21 +5190,21 @@ int bank_number(int mode)
|
|||
switch (mode) {
|
||||
case ARM_CPU_MODE_USR:
|
||||
case ARM_CPU_MODE_SYS:
|
||||
return 0;
|
||||
return BANK_USRSYS;
|
||||
case ARM_CPU_MODE_SVC:
|
||||
return 1;
|
||||
return BANK_SVC;
|
||||
case ARM_CPU_MODE_ABT:
|
||||
return 2;
|
||||
return BANK_ABT;
|
||||
case ARM_CPU_MODE_UND:
|
||||
return 3;
|
||||
return BANK_UND;
|
||||
case ARM_CPU_MODE_IRQ:
|
||||
return 4;
|
||||
return BANK_IRQ;
|
||||
case ARM_CPU_MODE_FIQ:
|
||||
return 5;
|
||||
return BANK_FIQ;
|
||||
case ARM_CPU_MODE_HYP:
|
||||
return 6;
|
||||
return BANK_HYP;
|
||||
case ARM_CPU_MODE_MON:
|
||||
return 7;
|
||||
return BANK_MON;
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,16 @@
|
|||
#ifndef TARGET_ARM_INTERNALS_H
|
||||
#define TARGET_ARM_INTERNALS_H
|
||||
|
||||
/* register banks for CPU modes */
|
||||
#define BANK_USRSYS 0
|
||||
#define BANK_SVC 1
|
||||
#define BANK_ABT 2
|
||||
#define BANK_UND 3
|
||||
#define BANK_IRQ 4
|
||||
#define BANK_FIQ 5
|
||||
#define BANK_HYP 6
|
||||
#define BANK_MON 7
|
||||
|
||||
static inline bool excp_is_internal(int excp)
|
||||
{
|
||||
/* Return true if this exception number represents a QEMU-internal
|
||||
|
@ -91,9 +101,9 @@ static inline void arm_log_exception(int idx)
|
|||
static inline unsigned int aarch64_banked_spsr_index(unsigned int el)
|
||||
{
|
||||
static const unsigned int map[4] = {
|
||||
[1] = 1, /* EL1. */
|
||||
[2] = 6, /* EL2. */
|
||||
[3] = 7, /* EL3. */
|
||||
[1] = BANK_SVC, /* EL1. */
|
||||
[2] = BANK_HYP, /* EL2. */
|
||||
[3] = BANK_MON, /* EL3. */
|
||||
};
|
||||
assert(el >= 1 && el <= 3);
|
||||
return map[el];
|
||||
|
|
|
@ -280,30 +280,30 @@ static const Reg regs[] = {
|
|||
COREREG(usr_regs.uregs[10], usr_regs[2]),
|
||||
COREREG(usr_regs.uregs[11], usr_regs[3]),
|
||||
COREREG(usr_regs.uregs[12], usr_regs[4]),
|
||||
COREREG(usr_regs.uregs[13], banked_r13[0]),
|
||||
COREREG(usr_regs.uregs[14], banked_r14[0]),
|
||||
COREREG(usr_regs.uregs[13], banked_r13[BANK_USRSYS]),
|
||||
COREREG(usr_regs.uregs[14], banked_r14[BANK_USRSYS]),
|
||||
/* R13, R14, SPSR for SVC, ABT, UND, IRQ banks */
|
||||
COREREG(svc_regs[0], banked_r13[1]),
|
||||
COREREG(svc_regs[1], banked_r14[1]),
|
||||
COREREG64(svc_regs[2], banked_spsr[1]),
|
||||
COREREG(abt_regs[0], banked_r13[2]),
|
||||
COREREG(abt_regs[1], banked_r14[2]),
|
||||
COREREG64(abt_regs[2], banked_spsr[2]),
|
||||
COREREG(und_regs[0], banked_r13[3]),
|
||||
COREREG(und_regs[1], banked_r14[3]),
|
||||
COREREG64(und_regs[2], banked_spsr[3]),
|
||||
COREREG(irq_regs[0], banked_r13[4]),
|
||||
COREREG(irq_regs[1], banked_r14[4]),
|
||||
COREREG64(irq_regs[2], banked_spsr[4]),
|
||||
COREREG(svc_regs[0], banked_r13[BANK_SVC]),
|
||||
COREREG(svc_regs[1], banked_r14[BANK_SVC]),
|
||||
COREREG64(svc_regs[2], banked_spsr[BANK_SVC]),
|
||||
COREREG(abt_regs[0], banked_r13[BANK_ABT]),
|
||||
COREREG(abt_regs[1], banked_r14[BANK_ABT]),
|
||||
COREREG64(abt_regs[2], banked_spsr[BANK_ABT]),
|
||||
COREREG(und_regs[0], banked_r13[BANK_UND]),
|
||||
COREREG(und_regs[1], banked_r14[BANK_UND]),
|
||||
COREREG64(und_regs[2], banked_spsr[BANK_UND]),
|
||||
COREREG(irq_regs[0], banked_r13[BANK_IRQ]),
|
||||
COREREG(irq_regs[1], banked_r14[BANK_IRQ]),
|
||||
COREREG64(irq_regs[2], banked_spsr[BANK_IRQ]),
|
||||
/* R8_fiq .. R14_fiq and SPSR_fiq */
|
||||
COREREG(fiq_regs[0], fiq_regs[0]),
|
||||
COREREG(fiq_regs[1], fiq_regs[1]),
|
||||
COREREG(fiq_regs[2], fiq_regs[2]),
|
||||
COREREG(fiq_regs[3], fiq_regs[3]),
|
||||
COREREG(fiq_regs[4], fiq_regs[4]),
|
||||
COREREG(fiq_regs[5], banked_r13[5]),
|
||||
COREREG(fiq_regs[6], banked_r14[5]),
|
||||
COREREG64(fiq_regs[7], banked_spsr[5]),
|
||||
COREREG(fiq_regs[5], banked_r13[BANK_FIQ]),
|
||||
COREREG(fiq_regs[6], banked_r14[BANK_FIQ]),
|
||||
COREREG64(fiq_regs[7], banked_spsr[BANK_FIQ]),
|
||||
/* R15 */
|
||||
COREREG(usr_regs.uregs[15], regs[15]),
|
||||
/* VFP system registers */
|
||||
|
|
|
@ -392,9 +392,9 @@ uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
|
|||
uint32_t val;
|
||||
|
||||
if (regno == 13) {
|
||||
val = env->banked_r13[0];
|
||||
val = env->banked_r13[BANK_USRSYS];
|
||||
} else if (regno == 14) {
|
||||
val = env->banked_r14[0];
|
||||
val = env->banked_r14[BANK_USRSYS];
|
||||
} else if (regno >= 8
|
||||
&& (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
|
||||
val = env->usr_regs[regno - 8];
|
||||
|
@ -407,9 +407,9 @@ uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
|
|||
void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
|
||||
{
|
||||
if (regno == 13) {
|
||||
env->banked_r13[0] = val;
|
||||
env->banked_r13[BANK_USRSYS] = val;
|
||||
} else if (regno == 14) {
|
||||
env->banked_r14[0] = val;
|
||||
env->banked_r14[BANK_USRSYS] = val;
|
||||
} else if (regno >= 8
|
||||
&& (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
|
||||
env->usr_regs[regno - 8] = val;
|
||||
|
|
Loading…
Reference in New Issue