From: Juha Riihimäki <juha.riihim...@nokia.com> Signed-Off-By: Riku Voipio <riku.voi...@nokia.com> Signed-Off-By: Juha Riihimäki <juha.riihim...@nokia.com>
--- target-arm/cpu.h | 7 +- target-arm/helper.c | 330 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 220 insertions(+), 117 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 3892db4..3c5e181 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -110,6 +110,9 @@ typedef struct CPUARMState { uint32_t c1_sys; /* System control register. */ uint32_t c1_coproc; /* Coprocessor access register. */ uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */ + uint32_t c1_secfg; /* Secure configuration register. */ + uint32_t c1_sedbg; /* Secure debug enable register. */ + uint32_t c1_nseac; /* Non-secure access control register. */ uint32_t c2_base0; /* MMU translation table base 0. */ uint32_t c2_base1; /* MMU translation table base 1. */ uint32_t c2_control; /* MMU translation table base control. */ @@ -345,7 +348,8 @@ enum arm_features { ARM_FEATURE_DIV, ARM_FEATURE_M, /* Microcontroller profile. */ ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */ - ARM_FEATURE_THUMB2EE + ARM_FEATURE_THUMB2EE, + ARM_FEATURE_TRUSTZONE /* TrustZone Security Extensions. */ }; static inline int arm_feature(CPUARMState *env, int feature) @@ -392,6 +396,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, #define ARM_CPUID_ARM1136_R2 0x4107b362 #define ARM_CPUID_ARM11MPCORE 0x410fb022 #define ARM_CPUID_CORTEXA8 0x410fc080 +#define ARM_CPUID_CORTEXA8_R2 0x412fc083 #define ARM_CPUID_CORTEXA9 0x410fc090 #define ARM_CPUID_CORTEXM3 0x410fc231 #define ARM_CPUID_ANY 0xffffffff diff --git a/target-arm/helper.c b/target-arm/helper.c index 18e22b1..99c5b12 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -21,6 +21,9 @@ static uint32_t cortexa8_cp15_c0_c1[8] = static uint32_t cortexa8_cp15_c0_c2[8] = { 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 }; +static uint32_t cortexa8r2_cp15_c0_c2[8] = +{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00011142, 0, 0, 0 }; + static uint32_t mpcore_cp15_c0_c1[8] = { 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 }; @@ -96,6 +99,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) set_feature(env, ARM_FEATURE_VFP3); set_feature(env, ARM_FEATURE_NEON); set_feature(env, ARM_FEATURE_THUMB2EE); + set_feature(env, ARM_FEATURE_TRUSTZONE); env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100; @@ -107,6 +111,28 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */ env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */ break; + case ARM_CPUID_CORTEXA8_R2: + set_feature(env, ARM_FEATURE_V6); + set_feature(env, ARM_FEATURE_V6K); + set_feature(env, ARM_FEATURE_V7); + set_feature(env, ARM_FEATURE_AUXCR); + set_feature(env, ARM_FEATURE_THUMB2); + set_feature(env, ARM_FEATURE_VFP); + set_feature(env, ARM_FEATURE_VFP3); + set_feature(env, ARM_FEATURE_NEON); + set_feature(env, ARM_FEATURE_THUMB2EE); + set_feature(env, ARM_FEATURE_TRUSTZONE); + env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c2; + env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; + env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011111; + memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t)); + memcpy(env->cp15.c0_c2, cortexa8r2_cp15_c0_c2, 8 * sizeof(uint32_t)); + env->cp15.c0_cachetype = 0x82048004; + env->cp15.c0_clid = (1 << 27) | (2 << 24) | (4 << 3) | 3; + env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */ + env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */ + env->cp15.c0_ccsid[2] = 0xf03fe03a; /* 256k L2 cache. */ + break; case ARM_CPUID_CORTEXA9: set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_V6K); @@ -118,6 +144,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) set_feature(env, ARM_FEATURE_VFP_FP16); set_feature(env, ARM_FEATURE_NEON); set_feature(env, ARM_FEATURE_THUMB2EE); + set_feature(env, ARM_FEATURE_TRUSTZONE); env->vfp.xregs[ARM_VFP_FPSID] = 0x41034000; /* Guess */ env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x01111111; @@ -314,6 +341,7 @@ static const struct arm_cpu_t arm_cpu_names[] = { { ARM_CPUID_ARM11MPCORE, "arm11mpcore"}, { ARM_CPUID_CORTEXM3, "cortex-m3"}, { ARM_CPUID_CORTEXA8, "cortex-a8"}, + { ARM_CPUID_CORTEXA8_R2, "cortex-a8-r2"}, { ARM_CPUID_CORTEXA9, "cortex-a9"}, { ARM_CPUID_TI925T, "ti925t" }, { ARM_CPUID_PXA250, "pxa250" }, @@ -1003,7 +1031,7 @@ static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type, table = get_level1_table_address(env, address); desc = ldl_phys(table); type = (desc & 3); - if (type == 0) { + if (type == 0 || type == 3) { /* Section translation fault. */ code = 5; domain = 0; @@ -1295,30 +1323,60 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) } goto bad_reg; case 1: /* System configuration. */ - if (arm_feature(env, ARM_FEATURE_OMAPCP)) - op2 = 0; - switch (op2) { + switch (crm) { 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 cotrol register. */ - if (arm_feature(env, ARM_FEATURE_XSCALE)) { - env->cp15.c1_xscaleauxcr = val; + if (arm_feature(env, ARM_FEATURE_OMAPCP)) + op2 = 0; + switch (op2) { + case 0: + if (!arm_feature(env, ARM_FEATURE_XSCALE)) + 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 cotrol 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; } - /* Not implemented. */ break; - case 2: - if (arm_feature(env, ARM_FEATURE_XSCALE)) + case 1: + if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) + || (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) + goto bad_reg; + switch (op2) { + case 0: /* Secure configuration register. */ + if (env->cp15.c1_secfg & 1) + goto bad_reg; + env->cp15.c1_secfg = val; + break; + case 1: /* Secure debug enable register. */ + if (env->cp15.c1_secfg & 1) + goto bad_reg; + env->cp15.c1_sedbg = val; + break; + case 2: /* Nonsecure access control register. */ + if (env->cp15.c1_secfg & 1) + goto bad_reg; + env->cp15.c1_nseac = val; + break; + default: 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: @@ -1338,22 +1396,22 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) goto bad_reg; } } else { - switch (op2) { - case 0: - env->cp15.c2_base0 = val; - break; - case 1: - env->cp15.c2_base1 = val; - break; - case 2: + switch (op2) { + case 0: + env->cp15.c2_base0 = val; + break; + case 1: + env->cp15.c2_base1 = val; + break; + case 2: val &= 7; env->cp15.c2_control = val; - env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val); + env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val); env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val); - break; - default: - goto bad_reg; - } + break; + default: + goto bad_reg; + } } break; case 3: /* MMU Domain access control / MPU write buffer control. */ @@ -1441,26 +1499,26 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) break; switch (crm) { case 0: /* Cache lockdown. */ - switch (op1) { - case 0: /* L1 cache. */ - switch (op2) { - case 0: - env->cp15.c9_data = val; - break; - case 1: - env->cp15.c9_insn = val; - break; - default: - goto bad_reg; - } - break; - case 1: /* L2 cache. */ - /* Ignore writes to L2 lockdown/auxiliary registers. */ - break; - default: - goto bad_reg; - } - break; + switch (op1) { + case 0: /* L1 cache. */ + switch (op2) { + case 0: + env->cp15.c9_data = val; + break; + case 1: + env->cp15.c9_insn = val; + break; + default: + goto bad_reg; + } + break; + case 1: /* L2 cache. */ + /* Ignore writes to L2 lockdown/auxiliary registers. */ + break; + default: + goto bad_reg; + } + break; case 1: /* TCM memory region registers. */ /* Not implemented. */ goto bad_reg; @@ -1561,7 +1619,7 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) case 0: /* Device ID. */ return env->cp15.c0_cpuid; case 1: /* Cache Type. */ - return env->cp15.c0_cachetype; + return env->cp15.c0_cachetype; case 2: /* TCM status. */ return 0; case 3: /* TLB type register. */ @@ -1588,6 +1646,7 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) default: goto bad_reg; } + break; case 1: /* These registers aren't documented on arm11 cores. However Linux looks at them anyway. */ @@ -1614,39 +1673,68 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) default: goto bad_reg; } + break; case 1: /* System configuration. */ - 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: - return 7; - case ARM_CPUID_ARM11MPCORE: - return 1; - case ARM_CPUID_CORTEXA8: - return 2; - case ARM_CPUID_CORTEXA9: - return 0; + switch (crm) { + case 0: + 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: + return 7; + case ARM_CPUID_ARM11MPCORE: + return 1; + case ARM_CPUID_CORTEXA8: + case ARM_CPUID_CORTEXA8_R2: + return 2; + case ARM_CPUID_CORTEXA9: + return 0; + default: + goto bad_reg; + } + break; + 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 2: /* Coprocessor access register. */ - if (arm_feature(env, ARM_FEATURE_XSCALE)) + break; + case 1: + if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) + || (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) goto bad_reg; - return env->cp15.c1_coproc; + switch (op2) { + case 0: /* Secure configuration register. */ + if (env->cp15.c1_secfg & 1) + goto bad_reg; + return env->cp15.c1_secfg; + case 1: /* Secure debug enable register. */ + if (env->cp15.c1_secfg & 1) + goto bad_reg; + return env->cp15.c1_sedbg; + case 2: /* Nonsecure access control register. */ + return env->cp15.c1_nseac; + default: + goto bad_reg; + } + break; default: goto bad_reg; } + break; case 2: /* MMU Page table control / MPU cache control. */ if (arm_feature(env, ARM_FEATURE_MPU)) { switch (op2) { @@ -1660,17 +1748,17 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) goto bad_reg; } } else { - switch (op2) { - case 0: - return env->cp15.c2_base0; - case 1: - return env->cp15.c2_base1; - case 2: + switch (op2) { + case 0: + return env->cp15.c2_base0; + case 1: + return env->cp15.c2_base1; + case 2: return env->cp15.c2_control; - default: - goto bad_reg; - } - } + default: + goto bad_reg; + } + } case 3: /* MMU Domain access control / MPU write buffer control. */ return env->cp15.c3; case 4: /* Reserved. */ @@ -1706,41 +1794,39 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) } 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; - } + 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. */ + } + /* 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; + } + goto bad_reg; + default: + goto bad_reg; + } } case 7: /* Cache control. */ - /* FIXME: Should only clear Z flag if destination is r15. */ - env->ZF = 0; + if (((insn >> 12) & 0xf) == 0xf) /* clear ZF only if destination is r15 */ + env->ZF = 0; return 0; case 8: /* MMU TLB control. */ goto bad_reg; case 9: /* Cache lockdown. */ switch (op1) { case 0: /* L1 cache. */ - if (arm_feature(env, ARM_FEATURE_OMAPCP)) - return 0; + if (arm_feature(env, ARM_FEATURE_OMAPCP)) + return 0; switch (op2) { case 0: return env->cp15.c9_data; @@ -1762,6 +1848,18 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) return 0; case 11: /* TCM DMA control. */ case 12: /* Reserved. */ + if (!op1) { + switch (crm) { + case 0: /* secure or nonsecure vector base address */ + if (arm_feature(env, ARM_FEATURE_TRUSTZONE)) { + /* FIXME: implement true vector base addressing */ + return 0; /* reset value according to ARM Cortex-A8 TRM */ + } + break; + default: + break; + } + } goto bad_reg; case 13: /* Process ID. */ switch (op2) { -- 1.6.5