aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2012-03-20 17:25:57 +0000
committerPeter Maydell <peter.maydell@linaro.org>2012-03-23 13:44:12 +0000
commitc08ee9c451655cc2d748c8963380ac8e63bf9a44 (patch)
tree9e37bc542ddc70ba83294256920b6c83390e5a62
parent1ecd97401531f96269d29e89b2a8c3b1501061a1 (diff)
downloadqemu-arm-c08ee9c451655cc2d748c8963380ac8e63bf9a44.tar.gz
target-arm: Convert cp15 crn=6 registers
Convert the cp15 crn=6 registers to the new scheme. Note that this includes some minor tidyup: drop an unnecessary underdecoding of op2 on OMAPCP cores, and only implement the pre-v6 c6,c0,0,1 IFAR on the 1026 and not on the other ARMv5 cores, which didn't have it. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--target-arm/helper.c99
1 files changed, 46 insertions, 53 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index dec142f31c..b6e10fd98c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -499,6 +499,14 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
.access = PL0_W, .type = ARM_CP_NOP },
{ .name = "ISB", .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, .fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
+ .resetvalue = 0, },
+ /* Watchpoint Fault Address Register : should actually only be present
+ * for 1136, 1176, 11MPCore.
+ */
+ { .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, },
REGINFO_SENTINEL
};
@@ -726,6 +734,26 @@ static int pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
return 0;
}
+static int arm946_prbs_read(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t *value)
+{
+ if (ri->crm > 8) {
+ return EXCP_UDEF;
+ }
+ *value = env->cp15.c6_region[ri->crm];
+ return 0;
+}
+
+static int arm946_prbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ if (ri->crm > 8) {
+ return EXCP_UDEF;
+ }
+ env->cp15.c6_region[ri->crm] = value;
+ return 0;
+}
+
static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
{ .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW,
@@ -747,6 +775,18 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
{ .name = "ICACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
.access = PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c2_insn), .resetvalue = 0, },
+ /* Protection region base and size registers */
+ { .name = "946_PRBS", .cp = 15, .crn = 6, .crm = CP_ANY, .opc1 = 0,
+ .opc2 = CP_ANY, .access = PL1_RW,
+ .readfn = arm946_prbs_read, .writefn = arm946_prbs_write, },
+ REGINFO_SENTINEL
+};
+
+static const ARMCPRegInfo arm1026_cp_reginfo[] = {
+ /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
+ { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
+ .resetvalue = 0, },
REGINFO_SENTINEL
};
@@ -776,6 +816,9 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
{ .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
.access = PL1_RW, .writefn = vmsa_ttbcr_write,
.fieldoffset = offsetof(CPUARMState, cp15.c2_control), .resetvalue = 0, },
+ { .name = "DFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c6_data),
+ .resetvalue = 0, },
REGINFO_SENTINEL
};
@@ -1009,6 +1052,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
/* 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_CORTEXA9:
define_arm_cp_regs(env, cortexa9_cp_reginfo);
break;
@@ -2112,27 +2158,6 @@ void HELPER(set_cp15)(CPUARMState *env, uint32_t insn, uint32_t val)
break;
case 4: /* Reserved. */
goto bad_reg;
- case 6: /* MMU Fault address / MPU base/size. */
- if (arm_feature(env, ARM_FEATURE_MPU)) {
- if (crm >= 8)
- goto bad_reg;
- env->cp15.c6_region[crm] = val;
- } else {
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0:
- env->cp15.c6_data = val;
- break;
- case 1: /* ??? This is WFAR on armv6 */
- case 2:
- env->cp15.c6_insn = val;
- break;
- default:
- goto bad_reg;
- }
- }
- break;
case 9:
if (arm_feature(env, ARM_FEATURE_OMAPCP))
break;
@@ -2306,38 +2331,6 @@ uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
}
case 4: /* Reserved. */
goto bad_reg;
- case 6: /* MMU Fault address. */
- if (arm_feature(env, ARM_FEATURE_MPU)) {
- if (crm >= 8)
- goto bad_reg;
- return env->cp15.c6_region[crm];
- } else {
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0:
- return env->cp15.c6_data;
- case 1:
- if (arm_feature(env, ARM_FEATURE_V6)) {
- /* Watchpoint Fault Adrress. */
- return 0; /* Not implemented. */
- } else {
- /* Instruction Fault Adrress. */
- /* Arm9 doesn't have an IFAR, but implementing it anyway
- shouldn't do any harm. */
- return env->cp15.c6_insn;
- }
- case 2:
- if (arm_feature(env, ARM_FEATURE_V6)) {
- /* Instruction Fault Adrress. */
- return env->cp15.c6_insn;
- } else {
- goto bad_reg;
- }
- default:
- goto bad_reg;
- }
- }
case 9:
switch (crm) {
case 0: /* Cache lockdown */