diff options
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r-- | target-arm/helper.c | 143 |
1 files changed, 68 insertions, 75 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index 346c61c089..a7ce44a690 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -430,6 +430,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 @@ -467,6 +476,9 @@ static const ARMCPRegInfo cp_reginfo[] = { /* Cache maintenance ops; some of this space may be overridden later. */ { .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY, .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, .type = ARM_CP_NOP }, + { .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 }; @@ -498,6 +510,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", @@ -517,6 +539,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 }; @@ -590,6 +615,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 }; @@ -797,6 +825,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 }; @@ -922,6 +970,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 }; @@ -959,6 +1011,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 }; @@ -967,6 +1021,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 }; @@ -986,6 +1042,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 }; @@ -1106,6 +1164,16 @@ void register_cp_regs_for_features(ARMCPU *cpu) 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; @@ -2177,42 +2245,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. */ @@ -2313,45 +2345,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. */ |