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.c151
1 files changed, 76 insertions, 75 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index b0375f0351..fc6412ece4 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -415,6 +415,15 @@ static int tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
return 0;
}
+static int sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+{
+ env->cp15.c1_sys = value;
+ /* ??? Lots of these bits are not implemented. */
+ /* This may enable/disable the MMU, so do a TLB flush. */
+ tlb_flush(env, 1);
+ return 0;
+}
+
static const ARMCPRegInfo cp_reginfo[] = {
/* DBGDIDR: just RAZ. In particular this means the "debug architecture
* version" bits will read as a reserved value, which should cause
@@ -455,6 +464,13 @@ static const ARMCPRegInfo cp_reginfo[] = {
REGINFO_SENTINEL
};
+static ARMCPRegInfo sctlr_cp_reginfo[] = {
+ { .name = "SCTLR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_sys),
+ .writefn = sctlr_write },
+ REGINFO_SENTINEL
+};
+
static const ARMCPRegInfo not_v6_cp_reginfo[] = {
/* Not all pre-v6 cores implemented this WFI, so this is slightly
* over-broad.
@@ -483,6 +499,16 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
REGINFO_SENTINEL
};
+static int cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+{
+ if (env->cp15.c1_coproc != value) {
+ env->cp15.c1_coproc = value;
+ /* ??? Is this safe when called from within a TB? */
+ tb_flush(env);
+ }
+ return 0;
+}
+
static const ARMCPRegInfo v6_cp_reginfo[] = {
/* prefetch by MVA in v6, NOP in v7 */
{ .name = "MVA_prefetch",
@@ -502,6 +528,9 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
*/
{ .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, },
+ { .name = "CPACR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2,
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_coproc),
+ .resetvalue = 0, .writefn = cpacr_write },
REGINFO_SENTINEL
};
@@ -575,6 +604,9 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
.resetvalue = 0,
.writefn = pmintenclr_write },
+ { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr),
+ .resetvalue = 0, },
REGINFO_SENTINEL
};
@@ -782,6 +814,26 @@ static const ARMCPRegInfo arm1026_cp_reginfo[] = {
{ .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
.resetvalue = 0, },
+ { .name = "AUXCR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1,
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 1, },
+ REGINFO_SENTINEL
+};
+
+static const ARMCPRegInfo arm1136_cp_reginfo[] = {
+ { .name = "AUXCR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1,
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 7, },
+ REGINFO_SENTINEL
+};
+
+static const ARMCPRegInfo arm1176_cp_reginfo[] = {
+ { .name = "AUXCR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1,
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 7, },
+ REGINFO_SENTINEL
+};
+
+static const ARMCPRegInfo arm11mpcore_cp_reginfo[] = {
+ { .name = "AUXCR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1,
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 1, },
REGINFO_SENTINEL
};
@@ -907,6 +959,10 @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
.cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c15_cpar), .resetvalue = 0,
.writefn = xscale_cpar_write, },
+ { .name = "XSCALE_AUXCR",
+ .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW,
+ .fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr),
+ .resetvalue = 0, },
REGINFO_SENTINEL
};
@@ -944,6 +1000,8 @@ static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
.access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
{ .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2,
.access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
+ { .name = "AUXCR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1,
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, },
REGINFO_SENTINEL
};
@@ -952,6 +1010,8 @@ static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "AUXCR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1,
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 2, },
REGINFO_SENTINEL
};
@@ -971,6 +1031,8 @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
.writefn = arm_cp_write_ignore, },
{ .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "AUXCR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1,
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, },
REGINFO_SENTINEL
};
@@ -1086,11 +1148,25 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(env, dummy_c15_cp_reginfo);
}
+ /* Generic registers whose values depend on the implementation */
+ sctlr_cp_reginfo[0].resetvalue = cpu->reset_sctlr;
+ define_arm_cp_regs(env, sctlr_cp_reginfo);
+
/* Some cp15 registers are truly implementation specific */
switch (ARM_CPUID(env)) {
case ARM_CPUID_ARM1026:
define_arm_cp_regs(env, arm1026_cp_reginfo);
break;
+ case ARM_CPUID_ARM1136:
+ case ARM_CPUID_ARM1136_R2:
+ define_arm_cp_regs(env, arm1136_cp_reginfo);
+ break;
+ case ARM_CPUID_ARM1176:
+ define_arm_cp_regs(env, arm1176_cp_reginfo);
+ break;
+ case ARM_CPUID_ARM11MPCORE:
+ define_arm_cp_regs(env, arm11mpcore_cp_reginfo);
+ break;
case ARM_CPUID_CORTEXA8:
define_arm_cp_regs(env, cortexa8_cp_reginfo);
break;
@@ -2162,42 +2238,6 @@ void HELPER(set_cp15)(CPUARMState *env, uint32_t insn, uint32_t val)
break;
}
goto bad_reg;
- case 1: /* System configuration. */
- if (arm_feature(env, ARM_FEATURE_V7)
- && op1 == 0 && crm == 1 && op2 == 0) {
- env->cp15.c1_scr = val;
- break;
- }
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0:
- if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
- env->cp15.c1_sys = val;
- /* ??? Lots of these bits are not implemented. */
- /* This may enable/disable the MMU, so do a TLB flush. */
- tlb_flush(env, 1);
- break;
- case 1: /* Auxiliary control register. */
- if (arm_feature(env, ARM_FEATURE_XSCALE)) {
- env->cp15.c1_xscaleauxcr = val;
- break;
- }
- /* Not implemented. */
- break;
- case 2:
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- goto bad_reg;
- if (env->cp15.c1_coproc != val) {
- env->cp15.c1_coproc = val;
- /* ??? Is this safe when called from within a TB? */
- tb_flush(env);
- }
- break;
- default:
- goto bad_reg;
- }
- break;
case 4: /* Reserved. */
goto bad_reg;
case 12: /* Reserved. */
@@ -2298,45 +2338,6 @@ uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
default:
goto bad_reg;
}
- case 1: /* System configuration. */
- if (arm_feature(env, ARM_FEATURE_V7)
- && op1 == 0 && crm == 1 && op2 == 0) {
- return env->cp15.c1_scr;
- }
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0: /* Control register. */
- return env->cp15.c1_sys;
- case 1: /* Auxiliary control register. */
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- return env->cp15.c1_xscaleauxcr;
- if (!arm_feature(env, ARM_FEATURE_AUXCR))
- goto bad_reg;
- switch (ARM_CPUID(env)) {
- case ARM_CPUID_ARM1026:
- return 1;
- case ARM_CPUID_ARM1136:
- case ARM_CPUID_ARM1136_R2:
- case ARM_CPUID_ARM1176:
- return 7;
- case ARM_CPUID_ARM11MPCORE:
- return 1;
- case ARM_CPUID_CORTEXA8:
- return 2;
- case ARM_CPUID_CORTEXA9:
- case ARM_CPUID_CORTEXA15:
- return 0;
- default:
- goto bad_reg;
- }
- case 2: /* Coprocessor access register. */
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- goto bad_reg;
- return env->cp15.c1_coproc;
- default:
- goto bad_reg;
- }
case 4: /* Reserved. */
goto bad_reg;
case 11: /* TCM DMA control. */