aboutsummaryrefslogtreecommitdiff
path: root/target/arm/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm/helper.c')
-rw-r--r--target/arm/helper.c373
1 files changed, 258 insertions, 115 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6be9ffa09e..f91e5d5345 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -530,6 +530,49 @@ static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
return CP_ACCESS_OK;
}
+/* Check for traps from EL1 due to HCR_EL2.TVM and HCR_EL2.TRVM. */
+static CPAccessResult access_tvm_trvm(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ if (arm_current_el(env) == 1) {
+ uint64_t trap = isread ? HCR_TRVM : HCR_TVM;
+ if (arm_hcr_el2_eff(env) & trap) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ }
+ return CP_ACCESS_OK;
+}
+
+/* Check for traps from EL1 due to HCR_EL2.TSW. */
+static CPAccessResult access_tsw(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TSW)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ return CP_ACCESS_OK;
+}
+
+/* Check for traps from EL1 due to HCR_EL2.TACR. */
+static CPAccessResult access_tacr(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TACR)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ return CP_ACCESS_OK;
+}
+
+/* Check for traps from EL1 due to HCR_EL2.TTLB. */
+static CPAccessResult access_ttlb(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TTLB)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ return CP_ACCESS_OK;
+}
+
static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
ARMCPU *cpu = env_archcpu(env);
@@ -785,12 +828,14 @@ static const ARMCPRegInfo cp_reginfo[] = {
*/
{ .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
- .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .secure = ARM_CP_SECSTATE_NS,
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
{ .name = "CONTEXTIDR_S", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
- .access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .secure = ARM_CP_SECSTATE_S,
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
REGINFO_SENTINEL
@@ -803,7 +848,7 @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
/* MMU Domain access control / MPU write buffer control */
{ .name = "DACR",
.cp = 15, .opc1 = CP_ANY, .crn = 3, .crm = CP_ANY, .opc2 = CP_ANY,
- .access = PL1_RW, .resetvalue = 0,
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
.writefn = dacr_write, .raw_writefn = raw_write,
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
offsetoflow32(CPUARMState, cp15.dacr_ns) } },
@@ -996,7 +1041,7 @@ 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, .accessfn = access_tvm_trvm,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
offsetof(CPUARMState, cp15.ifar_ns) },
.resetvalue = 0, },
@@ -2208,16 +2253,19 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
*/
{ .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
/* MAIR can just read-as-written because we don't implement caches
* and so don't need to care about memory attributes.
*/
{ .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
.resetvalue = 0 },
{ .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0,
@@ -2231,12 +2279,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
* handled in the field definitions.
*/
{ .name = "MAIR0", .state = ARM_CP_STATE_AA32,
- .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW,
+ .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s),
offsetof(CPUARMState, cp15.mair0_ns) },
.resetfn = arm_cp_reset_ignore },
{ .name = "MAIR1", .state = ARM_CP_STATE_AA32,
- .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW,
+ .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s),
offsetof(CPUARMState, cp15.mair1_ns) },
.resetfn = arm_cp_reset_ignore },
@@ -2245,41 +2295,53 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
.type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read },
/* 32 bit ITLB invalidates */
{ .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbiall_write },
{ .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbimva_write },
{ .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbiasid_write },
/* 32 bit DTLB invalidates */
{ .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbiall_write },
{ .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbimva_write },
{ .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbiasid_write },
/* 32 bit TLB invalidates */
{ .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbiall_write },
{ .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbimva_write },
{ .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbiasid_write },
{ .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbimvaa_write },
REGINFO_SENTINEL
};
static const ARMCPRegInfo v7mp_cp_reginfo[] = {
/* 32 bit TLB invalidates, Inner Shareable */
{ .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_is_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbiall_is_write },
{ .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbimva_is_write },
{ .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
- .type = ARM_CP_NO_RAW, .access = PL1_W,
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
.writefn = tlbiasid_is_write },
{ .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
- .type = ARM_CP_NO_RAW, .access = PL1_W,
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
.writefn = tlbimvaa_is_write },
REGINFO_SENTINEL
};
@@ -3886,20 +3948,21 @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
{ .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_ALIAS,
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .type = ARM_CP_ALIAS,
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s),
offsetoflow32(CPUARMState, cp15.dfsr_ns) }, },
{ .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
- .access = PL1_RW, .resetvalue = 0,
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s),
offsetoflow32(CPUARMState, cp15.ifsr_ns) } },
{ .name = "DFAR", .cp = 15, .opc1 = 0, .crn = 6, .crm = 0, .opc2 = 0,
- .access = PL1_RW, .resetvalue = 0,
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s),
offsetof(CPUARMState, cp15.dfar_ns) } },
{ .name = "FAR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
.resetvalue = 0, },
REGINFO_SENTINEL
};
@@ -3907,25 +3970,29 @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
static const ARMCPRegInfo vmsa_cp_reginfo[] = {
{ .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
.fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
- .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .writefn = vmsa_ttbr_write, .resetvalue = 0,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
offsetof(CPUARMState, cp15.ttbr0_ns) } },
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
- .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .writefn = vmsa_ttbr_write, .resetvalue = 0,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
offsetof(CPUARMState, cp15.ttbr1_ns) } },
{ .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
- .access = PL1_RW, .writefn = vmsa_tcr_el12_write,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .writefn = vmsa_tcr_el12_write,
.resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
.fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) },
{ .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
- .access = PL1_RW, .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write,
.raw_writefn = vmsa_ttbcr_raw_write,
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]),
offsetoflow32(CPUARMState, cp15.tcr_el[1])} },
@@ -3937,7 +4004,8 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
*/
static const ARMCPRegInfo ttbcr2_reginfo = {
.name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3,
- .access = PL1_RW, .type = ARM_CP_ALIAS,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .type = ARM_CP_ALIAS,
.bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]),
offsetofhigh32(CPUARMState, cp15.tcr_el[1]) },
};
@@ -4157,23 +4225,25 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
/* NOP AMAIR0/1 */
{ .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST,
- .resetvalue = 0 },
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
/* AMAIR1 is mapped to AMAIR_EL1[63:32] */
{ .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
- .access = PL1_RW, .type = ARM_CP_CONST,
- .resetvalue = 0 },
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
.access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
offsetof(CPUARMState, cp15.par_ns)} },
{ .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
- .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .type = ARM_CP_64BIT | ARM_CP_ALIAS,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
offsetof(CPUARMState, cp15.ttbr0_ns) },
.writefn = vmsa_ttbr_write, },
{ .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
- .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .type = ARM_CP_64BIT | ARM_CP_ALIAS,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
offsetof(CPUARMState, cp15.ttbr1_ns) },
.writefn = vmsa_ttbr_write, },
@@ -4253,15 +4323,46 @@ static const ARMCPRegInfo uao_reginfo = {
.readfn = aa64_uao_read, .writefn = aa64_uao_write
};
-static CPAccessResult aa64_cacheop_access(CPUARMState *env,
- const ARMCPRegInfo *ri,
- bool isread)
+static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
+ const ARMCPRegInfo *ri,
+ bool isread)
{
- /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
- * SCTLR_EL1.UCI is set.
- */
- if (arm_current_el(env) == 0 && !(arm_sctlr(env, 0) & SCTLR_UCI)) {
- return CP_ACCESS_TRAP;
+ /* Cache invalidate/clean to Point of Coherency or Persistence... */
+ switch (arm_current_el(env)) {
+ case 0:
+ /* ... EL0 must UNDEF unless SCTLR_EL1.UCI is set. */
+ if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
+ return CP_ACCESS_TRAP;
+ }
+ /* fall through */
+ case 1:
+ /* ... EL1 must trap to EL2 if HCR_EL2.TPCP is set. */
+ if (arm_hcr_el2_eff(env) & HCR_TPCP) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ break;
+ }
+ return CP_ACCESS_OK;
+}
+
+static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env,
+ const ARMCPRegInfo *ri,
+ bool isread)
+{
+ /* Cache invalidate/clean to Point of Unification... */
+ switch (arm_current_el(env)) {
+ case 0:
+ /* ... EL0 must UNDEF unless SCTLR_EL1.UCI is set. */
+ if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
+ return CP_ACCESS_TRAP;
+ }
+ /* fall through */
+ case 1:
+ /* ... EL1 must trap to EL2 if HCR_EL2.TPU is set. */
+ if (arm_hcr_el2_eff(env) & HCR_TPU) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ break;
}
return CP_ACCESS_OK;
}
@@ -4663,86 +4764,89 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
/* Cache ops: all NOPs since we don't emulate caches */
{ .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
- .access = PL1_W, .type = ARM_CP_NOP },
+ .access = PL1_W, .type = ARM_CP_NOP,
+ .accessfn = aa64_cacheop_pou_access },
{ .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
- .access = PL1_W, .type = ARM_CP_NOP },
+ .access = PL1_W, .type = ARM_CP_NOP,
+ .accessfn = aa64_cacheop_pou_access },
{ .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
.access = PL0_W, .type = ARM_CP_NOP,
- .accessfn = aa64_cacheop_access },
+ .accessfn = aa64_cacheop_pou_access },
{ .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
- .access = PL1_W, .type = ARM_CP_NOP },
+ .access = PL1_W, .accessfn = aa64_cacheop_poc_access,
+ .type = ARM_CP_NOP },
{ .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
- .access = PL1_W, .type = ARM_CP_NOP },
+ .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
{ .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
.access = PL0_W, .type = ARM_CP_NOP,
- .accessfn = aa64_cacheop_access },
+ .accessfn = aa64_cacheop_poc_access },
{ .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
- .access = PL1_W, .type = ARM_CP_NOP },
+ .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
{ .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
.access = PL0_W, .type = ARM_CP_NOP,
- .accessfn = aa64_cacheop_access },
+ .accessfn = aa64_cacheop_pou_access },
{ .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
.access = PL0_W, .type = ARM_CP_NOP,
- .accessfn = aa64_cacheop_access },
+ .accessfn = aa64_cacheop_poc_access },
{ .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
- .access = PL1_W, .type = ARM_CP_NOP },
+ .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
/* TLBI operations */
{ .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vmalle1is_write },
{ .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vae1is_write },
{ .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vmalle1is_write },
{ .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vae1is_write },
{ .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vae1is_write },
{ .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vae1is_write },
{ .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vmalle1_write },
{ .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vae1_write },
{ .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vmalle1_write },
{ .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vae1_write },
{ .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vae1_write },
{ .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
- .access = PL1_W, .type = ARM_CP_NO_RAW,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
.writefn = tlbi_aa64_vae1_write },
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
@@ -4828,14 +4932,17 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
#endif
/* TLB invalidate last level of translation table walk */
{ .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbimva_is_write },
{ .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
- .type = ARM_CP_NO_RAW, .access = PL1_W,
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
.writefn = tlbimvaa_is_write },
{ .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbimva_write },
{ .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+ .writefn = tlbimvaa_write },
{ .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
.type = ARM_CP_NO_RAW, .access = PL2_W,
.writefn = tlbimva_hyp_write },
@@ -4861,34 +4968,34 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
.writefn = tlbiipas2_is_write },
/* 32 bit cache operations */
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
{ .name = "BPIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 6,
.type = ARM_CP_NOP, .access = PL1_W },
{ .name = "ICIALLU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
{ .name = "ICIMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 1,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
{ .name = "BPIALL", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 6,
.type = ARM_CP_NOP, .access = PL1_W },
{ .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7,
.type = ARM_CP_NOP, .access = PL1_W },
{ .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
{ .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
{ .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
{ .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
{ .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
{ .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
{ .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
- .type = ARM_CP_NOP, .access = PL1_W },
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
/* MMU Domain access control / MPU write buffer control */
{ .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
- .access = PL1_RW, .resetvalue = 0,
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
.writefn = dacr_write, .raw_writefn = raw_write,
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
offsetoflow32(CPUARMState, cp15.dacr_ns) } },
@@ -5086,11 +5193,15 @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
{
ARMCPU *cpu = env_archcpu(env);
- /* Begin with bits defined in base ARMv8.0. */
- uint64_t valid_mask = MAKE_64BIT_MASK(0, 34);
+
+ if (arm_feature(env, ARM_FEATURE_V8)) {
+ valid_mask |= MAKE_64BIT_MASK(0, 34); /* ARMv8.0 */
+ } else {
+ valid_mask |= MAKE_64BIT_MASK(0, 28); /* ARMv7VE */
+ }
if (arm_feature(env, ARM_FEATURE_EL3)) {
valid_mask &= ~HCR_HCD;
@@ -5104,14 +5215,17 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
*/
valid_mask &= ~HCR_TSC;
}
- if (cpu_isar_feature(aa64_vh, cpu)) {
- valid_mask |= HCR_E2H;
- }
- if (cpu_isar_feature(aa64_lor, cpu)) {
- valid_mask |= HCR_TLOR;
- }
- if (cpu_isar_feature(aa64_pauth, cpu)) {
- valid_mask |= HCR_API | HCR_APK;
+
+ if (arm_feature(env, ARM_FEATURE_AARCH64)) {
+ if (cpu_isar_feature(aa64_vh, cpu)) {
+ valid_mask |= HCR_E2H;
+ }
+ if (cpu_isar_feature(aa64_lor, cpu)) {
+ valid_mask |= HCR_TLOR;
+ }
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
+ valid_mask |= HCR_API | HCR_APK;
+ }
}
/* Clear RES0 bits. */
@@ -5143,12 +5257,17 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
arm_cpu_update_vfiq(cpu);
}
+static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+{
+ do_hcr_write(env, value, 0);
+}
+
static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
/* Handle HCR2 write, i.e. write to high half of HCR_EL2 */
value = deposit64(env->cp15.hcr_el2, 32, 32, value);
- hcr_write(env, NULL, value);
+ do_hcr_write(env, value, MAKE_64BIT_MASK(0, 32));
}
static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -5156,7 +5275,7 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
{
/* Handle HCR write, i.e. write to low half of HCR_EL2 */
value = deposit64(env->cp15.hcr_el2, 0, 32, value);
- hcr_write(env, NULL, value);
+ do_hcr_write(env, value, MAKE_64BIT_MASK(32, 32));
}
/*
@@ -5184,14 +5303,37 @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
* Since the v8.4 language applies to the entire register, and
* appears to be backward compatible, use that.
*/
- ret = 0;
- } else if (ret & HCR_TGE) {
- /* These bits are up-to-date as of ARMv8.4. */
+ return 0;
+ }
+
+ /*
+ * For a cpu that supports both aarch64 and aarch32, we can set bits
+ * in HCR_EL2 (e.g. via EL3) that are RES0 when we enter EL2 as aa32.
+ * Ignore all of the bits in HCR+HCR2 that are not valid for aarch32.
+ */
+ if (!arm_el_is_aa64(env, 2)) {
+ uint64_t aa32_valid;
+
+ /*
+ * These bits are up-to-date as of ARMv8.6.
+ * For HCR, it's easiest to list just the 2 bits that are invalid.
+ * For HCR2, list those that are valid.
+ */
+ aa32_valid = MAKE_64BIT_MASK(0, 32) & ~(HCR_RW | HCR_TDZ);
+ aa32_valid |= (HCR_CD | HCR_ID | HCR_TERR | HCR_TEA | HCR_MIOCNCE |
+ HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_TTLBIS);
+ ret &= aa32_valid;
+ }
+
+ if (ret & HCR_TGE) {
+ /* These bits are up-to-date as of ARMv8.6. */
if (ret & HCR_E2H) {
ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
- HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE);
+ HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE |
+ HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_ENSCXT |
+ HCR_TTLBIS | HCR_TTLBOS | HCR_TID5);
} else {
ret |= HCR_FMO | HCR_IMO | HCR_AMO;
}
@@ -6667,7 +6809,7 @@ static const ARMCPRegInfo dcpop_reg[] = {
{ .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
- .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
+ .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
REGINFO_SENTINEL
};
@@ -6675,7 +6817,7 @@ static const ARMCPRegInfo dcpodp_reg[] = {
{ .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
- .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
+ .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
REGINFO_SENTINEL
};
#endif /*CONFIG_USER_ONLY*/
@@ -6888,8 +7030,8 @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
{ .name = "ACTLR2", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 3,
- .access = PL1_RW, .type = ARM_CP_CONST,
- .resetvalue = 0 },
+ .access = PL1_RW, .accessfn = access_tacr,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
.access = PL2_RW, .type = ARM_CP_CONST,
@@ -7645,8 +7787,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
ARMCPRegInfo auxcr_reginfo[] = {
{ .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1,
- .access = PL1_RW, .type = ARM_CP_CONST,
- .resetvalue = cpu->reset_auxcr },
+ .access = PL1_RW, .accessfn = access_tacr,
+ .type = ARM_CP_CONST, .resetvalue = cpu->reset_auxcr },
{ .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1,
.access = PL2_RW, .type = ARM_CP_CONST,
@@ -7730,7 +7872,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
ARMCPRegInfo sctlr = {
.name = "SCTLR", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
- .access = PL1_RW,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
offsetof(CPUARMState, cp15.sctlr_ns) },
.writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
@@ -10316,7 +10458,8 @@ static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
} else if (mmu_idx == ARMMMUIdx_Stage2) {
return 0; /* VTCR_EL2 */
} else {
- return extract32(tcr, 20, 1);
+ /* Replicate the single TBI bit so we always have 2 bits. */
+ return extract32(tcr, 20, 1) * 3;
}
}
@@ -10327,7 +10470,8 @@ static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
} else if (mmu_idx == ARMMMUIdx_Stage2) {
return 0; /* VTCR_EL2 */
} else {
- return extract32(tcr, 29, 1);
+ /* Replicate the single TBID bit so we always have 2 bits. */
+ return extract32(tcr, 29, 1) * 3;
}
}
@@ -10591,6 +10735,10 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
/* Now we can extract the actual base address from the TTBR */
descaddr = extract64(ttbr, 0, 48);
+ /*
+ * We rely on this masking to clear the RES0 bits at the bottom of the TTBR
+ * and also to mask out CnP (bit 0) which could validly be non-zero.
+ */
descaddr &= ~indexmask;
/* The address field in the descriptor goes up to bit 39 for ARMv7
@@ -12126,11 +12274,6 @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
return arm_mmu_idx_el(env, arm_current_el(env));
}
-int cpu_mmu_index(CPUARMState *env, bool ifetch)
-{
- return arm_to_core_mmu_idx(arm_mmu_idx(env));
-}
-
#ifndef CONFIG_USER_ONLY
ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
{