Use new macro A32_BANKED_REG() for registers which are banked in Aarch32 and not mapped an EL3 register in Aarch64.
Using raw_write and raw_read in .readfn/.writefn to be able to use the same .readfn/writefn for secure and non-secure instance without case distinction. Whenever accessing banked registers using A32_BANKED_REG_GET macro or A32_MAPPED_EL3_REG_GET for registers which we map to EL3 registers. Signed-off-by: Sergey Fedorov <s.fedo...@samsung.com> Signed-off-by: Fabian Aggeler <aggel...@ethz.ch> --- linux-user/main.c | 2 +- target-arm/cpu.h | 32 ++++++---- target-arm/helper-a64.c | 3 +- target-arm/helper.c | 155 ++++++++++++++++++++++++++++++++++-------------- 4 files changed, 132 insertions(+), 60 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index c38fecf..809d731 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -566,7 +566,7 @@ do_kernel_trap(CPUARMState *env) end_exclusive(); break; case 0xffff0fe0: /* __kernel_get_tls */ - env->regs[0] = env->cp15.tpidrro_el0; + env->regs[0] = A32_BANKED_CURRENT_REG_GET(env, tpidrro_el0); break; case 0xffff0f60: /* __kernel_cmpxchg64 */ arm_kernel_cmpxchg64_helper(env); diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 780c1f5..c20c44a 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -179,7 +179,8 @@ typedef struct CPUARMState { /* System control coprocessor (cp15) */ struct { uint32_t c0_cpuid; - uint64_t c0_cssel; /* Cache size selection. */ + A32_BANKED_REG(uint64_t, c0_cssel); /* Cache size selection + (banked in Aarch32). */ uint64_t c1_sys_el1; /* System control register (EL1). */ uint64_t c1_sys_el3; /* System control register (EL3). */ uint64_t c1_coproc; /* Coprocessor access register. */ @@ -187,22 +188,28 @@ typedef struct CPUARMState { uint32_t c1_scr; /* secure config register. */ uint32_t c1_sder; /* Secure debug enable register. */ uint32_t c1_nsacr; /* Non-secure access control register. */ - uint64_t ttbr0_el1; /* MMU translation table base 0. */ - uint64_t ttbr1_el1; /* MMU translation table base 1. */ - uint64_t c2_control; /* MMU translation table base control. */ + uint64_t ttbr0_el1;/* MMU translation table base 0. */ + uint64_t ttbr0_el3; + uint64_t ttbr1_el1;/* MMU translation table base 1. */ + uint64_t ttbr1_el3; + A32_BANKED_REG(uint64_t, c2_control);/* MMU translation table base + control. (banked in Aarch32) */ uint32_t c2_mask; /* MMU translation table base selection mask. */ uint32_t c2_base_mask; /* MMU translation table base 0 mask. */ uint32_t c2_data; /* MPU data cachable bits. */ uint32_t c2_insn; /* MPU instruction cachable bits. */ - uint32_t c3; /* MMU domain access control register + A32_BANKED_REG(uint32_t, c3); /* MMU domain access control register MPU write buffer control. */ uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */ uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */ - uint32_t ifsr_el2; /* Fault status registers. */ + A32_BANKED_REG(uint32_t, ifsr_el2); /* Fault status registers. */ uint64_t esr_el1; + uint64_t esr_el3; uint32_t c6_region[8]; /* MPU base/size registers. */ uint64_t far_el1; /* Fault address registers. */ + uint64_t far_el3; uint64_t par_el1; /* Translation result. */ + uint64_t par_el3; uint32_t c9_insn; /* Cache lockdown registers. */ uint32_t c9_data; uint32_t c9_pmcr; /* performance monitor control register */ @@ -212,12 +219,13 @@ typedef struct CPUARMState { uint32_t c9_pmuserenr; /* perf monitor user enable */ uint32_t c9_pminten; /* perf monitor interrupt enables */ uint64_t mair_el1; - uint64_t c12_vbar; /* vector base address register */ - uint32_t c13_fcse; /* FCSE PID. */ - uint64_t contextidr_el1; /* Context ID. */ - uint64_t tpidr_el0; /* User RW Thread register. */ - uint64_t tpidrro_el0; /* User RO Thread register. */ - uint64_t tpidr_el1; /* Privileged Thread register. */ + uint64_t c12_vbar_el1; /* vector base address register */ + uint64_t c12_vbar_el3; /* vector base address register */ + A32_BANKED_REG(uint32_t, c13_fcse); /* FCSE PID. */ + A32_BANKED_REG(uint64_t, contextidr_el1); /* Context ID. */ + A32_BANKED_REG(uint64_t, tpidr_el0); /* User RW Thread register. */ + A32_BANKED_REG(uint64_t, tpidrro_el0); /* User RO Thread register. */ + A32_BANKED_REG(uint64_t, tpidr_el1); /* Privileged Thread register. */ uint64_t c14_cntfrq; /* Counter Frequency register */ uint64_t c14_cntkctl; /* Timer Control register */ ARMGenericTimer c14_timer[NUM_GTIMERS]; diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c index bf921cc..765ddf5 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -443,7 +443,8 @@ void aarch64_cpu_do_interrupt(CPUState *cs) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; - target_ulong addr = env->cp15.c12_vbar; + target_ulong addr = (arm_current_pl(env) == 3) ? + env->cp15.c12_vbar_el3 : env->cp15.c12_vbar_el1; int i; if (arm_current_pl(env) == 0) { diff --git a/target-arm/helper.c b/target-arm/helper.c index 757e07b..c76a86b 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -397,10 +397,11 @@ static const ARMCPRegInfo cp_reginfo[] = { .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse), - .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, }, + .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, + .type = ARM_CP_BANKED }, { .name = "CONTEXTIDR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1, - .access = PL1_RW, + .access = PL1_RW, .type = ARM_CP_BANKED_64BIT, .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el1), .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, }, REGINFO_SENTINEL @@ -413,7 +414,8 @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = { /* MMU Domain access control / MPU write buffer control */ { .name = "DACR", .cp = 15, .crn = 3, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c3), + .access = PL1_RW, .type = ARM_CP_BANKED, + .fieldoffset = offsetof(CPUARMState, cp15.c3), .resetvalue = 0, .writefn = dacr_write, .raw_writefn = raw_write, }, /* ??? This covers not just the impdef TLB lockdown registers but also * some v7VMSA registers relating to TEX remap, so it is overly broad. @@ -519,9 +521,13 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { { .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5, .access = PL0_W, .type = ARM_CP_NOP }, { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL1_RW, + .access = PL1_RW, .type = ARM_CP_NONSECURE, .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1), .resetvalue = 0, }, + { .name = "IFAR(S)", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL3_RW, .type = ARM_CP_SECURE, + .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el3), + .resetvalue = 0, }, /* Watchpoint Fault Address Register : should actually only be present * for 1136, 1176, 11MPCore. */ @@ -686,7 +692,7 @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri) { ARMCPU *cpu = arm_env_get_cpu(env); - return cpu->ccsidr[env->cp15.c0_cssel]; + return cpu->ccsidr[A32_BANKED_REG_GET(env, c0_cssel)]; } static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -786,15 +792,25 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), .resetvalue = 0, .writefn = pmintenclr_write, }, - { .name = "VBAR", .state = ARM_CP_STATE_BOTH, + { .name = "VBAR_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .writefn = vbar_write, - .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar), + .access = PL1_RW, .writefn = vbar_write, .type = ARM_CP_NONSECURE, + .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar_el1), + .resetvalue = 0 }, + { .name = "VBAR_EL1(S)", + .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL3_RW, .writefn = vbar_write, .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar_el3), + .resetvalue = 0 }, + { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 4, .opc2 = 5, + .access = PL3_RW, .writefn = vbar_write, + .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar_el3), .resetvalue = 0 }, { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0, .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE }, - { .name = "CSSELR", .state = ARM_CP_STATE_BOTH, + { .name = "CSSELR", .state = ARM_CP_STATE_BOTH, .type = ARM_CP_BANKED_64BIT, .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0, .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel), .writefn = csselr_write, .resetvalue = 0 }, @@ -871,7 +887,7 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = { .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 }, { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL0_RW, + .access = PL0_RW, .type = ARM_CP_BANKED_64BIT, .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0), .resetfn = arm_cp_reset_ignore }, { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64, @@ -879,12 +895,12 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = { .access = PL0_R|PL1_W, .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el0), .resetvalue = 0 }, { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3, - .access = PL0_R|PL1_W, + .access = PL0_R|PL1_W, .type = ARM_CP_BANKED_64BIT, .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0), .resetfn = arm_cp_reset_ignore }, { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0, - .access = PL1_RW, + .access = PL1_RW, .type = ARM_CP_BANKED_64BIT, .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el1), .resetvalue = 0 }, REGINFO_SENTINEL }; @@ -1263,7 +1279,7 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) * fault. */ } - env->cp15.par_el1 = par64; + A32_MAPPED_EL3_REG_SET(env, par, par64); } else { /* ret is a DFSR/IFSR value for the short descriptor * translation table format (with WnR always clear). @@ -1273,14 +1289,15 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) /* We do not set any attribute bits in the PAR */ if (page_size == (1 << 24) && arm_feature(env, ARM_FEATURE_V7)) { - env->cp15.par_el1 = (phys_addr & 0xff000000) | 1 << 1; + A32_MAPPED_EL3_REG_SET(env, par, + (phys_addr & 0xff000000) | 1 << 1); } else { - env->cp15.par_el1 = phys_addr & 0xfffff000; + A32_MAPPED_EL3_REG_SET(env, par, phys_addr & 0xfffff000); } } else { - env->cp15.par_el1 = ((ret & (1 << 10)) >> 5) | + A32_MAPPED_EL3_REG_SET(env, par, ((ret & (1 << 10)) >> 5) | ((ret & (1 << 12)) >> 6) | - ((ret & 0xf) << 1) | 1; + ((ret & 0xf) << 1) | 1); } } } @@ -1288,9 +1305,13 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) static const ARMCPRegInfo vapa_cp_reginfo[] = { { .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .resetvalue = 0, + .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_NONSECURE, .fieldoffset = offsetoflow32(CPUARMState, cp15.par_el1), .writefn = par_write }, + { .name = "PAR(S)", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0, + .access = PL3_RW, .resetvalue = 0, .type = ARM_CP_SECURE, + .fieldoffset = offsetoflow32(CPUARMState, cp15.par_el3), + .writefn = par_write }, #ifndef CONFIG_USER_ONLY { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, .accessfn = ats_access, @@ -1476,23 +1497,39 @@ static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, static const ARMCPRegInfo vmsa_cp_reginfo[] = { { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, + .access = PL1_RW, .type = ARM_CP_NO_MIGRATE | ARM_CP_NONSECURE, .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1), .resetfn = arm_cp_reset_ignore, }, + { .name = "DFSR(S)", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_SECURE, .resetvalue = 0, + .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el3) }, { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, + .access = PL1_RW, .type = ARM_CP_BANKED, .fieldoffset = offsetof(CPUARMState, cp15.ifsr_el2), .resetvalue = 0, }, { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el1), .resetvalue = 0, }, + { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64, .crn = 5, .crm = 2, + .opc0 = 3, .opc1 = 6, .opc2 = 0, .access = PL3_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.esr_el3) }, { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1), + .access = PL1_RW, .type = ARM_CP_NONSECURE, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1), + .writefn = vmsa_ttbr_write, .resetvalue = 0 }, + { .name = "TTBR0(S)", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3), .writefn = vmsa_ttbr_write, .resetvalue = 0 }, { .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1), + .access = PL1_RW, .type = ARM_CP_NONSECURE, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1), + .writefn = vmsa_ttbr_write, .resetvalue = 0 }, + { .name = "TTBR1(S)", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL3_RW, .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3), .writefn = vmsa_ttbr_write, .resetvalue = 0 }, { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, @@ -1500,14 +1537,18 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = { .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, .fieldoffset = offsetof(CPUARMState, cp15.c2_control) }, { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .writefn = vmsa_ttbcr_write, - .resetfn = arm_cp_reset_ignore, .raw_writefn = vmsa_ttbcr_raw_write, + .access = PL1_RW, .type = ARM_CP_NO_MIGRATE | ARM_CP_BANKED_64BIT, + .writefn = vmsa_ttbcr_write, .resetfn = arm_cp_reset_ignore, + .raw_writefn = vmsa_ttbcr_raw_write, .fieldoffset = offsetoflow32(CPUARMState, cp15.c2_control) }, /* 64-bit FAR; this entry also gives us the AArch32 DFAR */ - { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH, + { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH, .type = ARM_CP_NONSECURE, .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el1), .resetvalue = 0, }, + { .name = "DFAR(S)", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_SECURE, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.far_el3)}, REGINFO_SENTINEL }; @@ -1545,9 +1586,15 @@ static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri, static const ARMCPRegInfo omap_cp_reginfo[] = { { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY, - .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, + .type = ARM_CP_OVERRIDE | ARM_CP_NONSECURE, .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1), .resetvalue = 0, }, + { .name = "DFSR(S)", .cp = 15, .crn = 5, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL3_RW, + .type = ARM_CP_OVERRIDE | ARM_CP_SECURE, + .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el3), + .resetvalue = 0, }, { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP }, { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, @@ -1730,7 +1777,13 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = { { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0, .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 }, { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0, - .access = PL1_RW, .type = ARM_CP_64BIT, + .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NONSECURE, + .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0 }, + { .name = "PAR(S)", .cp = 15, .crm = 7, .opc1 = 0, + .access = PL3_RW, .type = ARM_CP_64BIT | ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.par_el3), .resetvalue = 0 }, + { .name = "PAR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .crn = 7, .crm = 4, .opc2 = 0, .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0 }, { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0, .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE, @@ -2131,6 +2184,10 @@ static const ARMCPRegInfo tz_cp_reginfo[] = { { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr), .resetvalue = 0, }, + { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .crn = 6, .crm = 1, .opc1 = 0, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr), + .resetvalue = 0 }, { .name = "SDER", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 1, .access = PL3_RW, .resetvalue = 0, .fieldoffset = offsetof(CPUARMState, cp15.c1_sder) }, @@ -3469,22 +3526,25 @@ void arm_cpu_do_interrupt(CPUState *cs) env->exception.fsr = 2; /* Fall through to prefetch abort. */ case EXCP_PREFETCH_ABORT: - env->cp15.ifsr_el2 = env->exception.fsr; - env->cp15.far_el1 = deposit64(env->cp15.far_el1, 32, 32, - env->exception.vaddress); + A32_BANKED_CURRENT_REG_SET(env, ifsr_el2, env->exception.fsr); + A32_MAPPED_EL3_CURRENT_REG_SET(env, far, + deposit64(A32_MAPPED_EL3_CURRENT_REG_GET(env, far), 32, 32, + env->exception.vaddress)); qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n", - env->cp15.ifsr_el2, (uint32_t)env->exception.vaddress); + A32_BANKED_CURRENT_REG_GET(env, ifsr_el2), + (uint32_t)env->exception.vaddress); new_mode = ARM_CPU_MODE_ABT; addr = 0x0c; mask = CPSR_A | CPSR_I; offset = 4; break; case EXCP_DATA_ABORT: - env->cp15.esr_el1 = env->exception.fsr; - env->cp15.far_el1 = deposit64(env->cp15.far_el1, 0, 32, - env->exception.vaddress); + A32_MAPPED_EL3_CURRENT_REG_SET(env, esr, env->exception.fsr); + A32_MAPPED_EL3_CURRENT_REG_SET(env, far, + deposit64(A32_MAPPED_EL3_CURRENT_REG_GET(env, far), 0, 32, + env->exception.vaddress)); qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n", - (uint32_t)env->cp15.esr_el1, + (uint32_t)A32_MAPPED_EL3_CURRENT_REG_GET(env, esr), (uint32_t)env->exception.vaddress); new_mode = ARM_CPU_MODE_ABT; addr = 0x10; @@ -3521,7 +3581,7 @@ void arm_cpu_do_interrupt(CPUState *cs) * and is never in monitor mode this feature is always active. * Note: only bits 31:5 are valid. */ - addr += env->cp15.c12_vbar; + addr += A32_MAPPED_EL3_CURRENT_REG_GET(env, c12_vbar); } switch_mode (env, new_mode); env->spsr = cpsr_read(env); @@ -3601,9 +3661,10 @@ static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address) uint32_t table; if (address & env->cp15.c2_mask) - table = env->cp15.ttbr1_el1 & 0xffffc000; + table = A32_MAPPED_EL3_CURRENT_REG_GET(env, ttbr1) & 0xffffc000; else - table = env->cp15.ttbr0_el1 & env->cp15.c2_base_mask; + table = + A32_MAPPED_EL3_CURRENT_REG_GET(env, ttbr0) & env->cp15.c2_base_mask; table |= (address >> 18) & 0x3ffc; return table; @@ -3737,7 +3798,7 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type, /* Page or Section. */ domain = (desc >> 5) & 0x0f; } - domain_prot = (env->cp15.c3 >> (domain * 2)) & 3; + domain_prot = (A32_BANKED_CURRENT_REG_GET(env, c3) >> (domain * 2)) & 3; if (domain_prot == 0 || domain_prot == 2) { if (type != 1) { code = 9; /* Section domain fault. */ @@ -3863,12 +3924,14 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address, * This is a Non-secure PL0/1 stage 1 translation, so controlled by * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32: */ - uint32_t t0sz = extract32(env->cp15.c2_control, 0, 6); + uint32_t t0sz = extract32( + A32_BANKED_CURRENT_REG_GET(env, c2_control), 0, 6); if (arm_el_is_aa64(env, 1)) { t0sz = MIN(t0sz, 39); t0sz = MAX(t0sz, 16); } - uint32_t t1sz = extract32(env->cp15.c2_control, 16, 6); + uint32_t t1sz = extract32( + A32_BANKED_CURRENT_REG_GET(env, c2_control), 16, 6); if (arm_el_is_aa64(env, 1)) { t1sz = MIN(t1sz, 39); t1sz = MAX(t1sz, 16); @@ -3899,8 +3962,8 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address, * we will always flush the TLB any time the ASID is changed). */ if (ttbr_select == 0) { - ttbr = env->cp15.ttbr0_el1; - epd = extract32(env->cp15.c2_control, 7, 1); + ttbr = A32_MAPPED_EL3_CURRENT_REG_GET(env, ttbr0); + epd = extract32(A32_BANKED_CURRENT_REG_GET(env, c2_control), 7, 1); tsz = t0sz; tg = extract32(env->cp15.c2_control, 14, 2); @@ -3911,8 +3974,8 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address, granule_sz = 11; } } else { - ttbr = env->cp15.ttbr1_el1; - epd = extract32(env->cp15.c2_control, 23, 1); + ttbr = A32_MAPPED_EL3_CURRENT_REG_GET(env, ttbr1); + epd = extract32(A32_BANKED_CURRENT_REG_GET(env, c2_control), 23, 1); tsz = t1sz; tg = extract32(env->cp15.c2_control, 30, 2); @@ -4132,7 +4195,7 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address, { /* Fast Context Switch Extension. */ if (address < 0x02000000) - address += env->cp15.c13_fcse; + address += A32_BANKED_CURRENT_REG_GET(env, c13_fcse); if ((arm_current_sctlr(env) & SCTLR_M) == 0) { /* MMU/MPU disabled. */ -- 1.8.3.2