|
From: | Greg Bellows |
Subject: | Re: [Qemu-devel] [PATCH v2 18/23] target-arm: Convert banked coprocessor registers |
Date: | Wed, 14 May 2014 14:47:18 -0500 |
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 <address@hidden>
Signed-off-by: Fabian Aggeler <address@hidden>
---
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
[Prev in Thread] | Current Thread | [Next in Thread] |