NSACR allows to control non-secure access to coprocessor interfaces 0-13 and CPACR bits.
Signed-off-by: Sergey Fedorov <s.fedo...@samsung.com> Signed-off-by: Fabian Aggeler <aggel...@ethz.ch> --- target-arm/cpu.h | 1 + target-arm/helper.c | 29 +++++++++++++++++++++++++++++ target-arm/translate.c | 7 +++++++ 3 files changed, 37 insertions(+) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index f86a101..fb72cfa 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -173,6 +173,7 @@ typedef struct CPUARMState { uint64_t c1_coproc; /* Coprocessor access register. */ uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */ uint32_t c1_scr; /* secure config register. */ + uint32_t c1_nsacr; /* Non-secure access control register. */ uint64_t ttbr0_el1; /* MMU translation table base 0. */ uint64_t ttbr1_el1; /* MMU translation table base 1. */ uint64_t c2_control; /* MMU translation table base control. */ diff --git a/target-arm/helper.c b/target-arm/helper.c index 4e82259..2c600ef 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -483,6 +483,23 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, mask |= 0x00f00000; /* VFP coprocessor: cp10 & cp11 */ } value &= mask; + /* In an implementation that includes Security Extensions access to CPACR + * can be restricted by NSACR. + */ + if (arm_feature(env, ARM_FEATURE_SECURITY_EXTENSIONS) + && !arm_is_secure(env)) { + int cpnum; + mask = 0; + for (cpnum = 0; cpnum < 14; ++cpnum) { + if (env->cp15.c1_nsacr & (1 << cpnum)) { + /* Bits [20:21] of CPACR control access to cp10 + * Bits [23:22] of CPACR control access to cp11 */ + mask |= (3 << (cpnum * 2)); + } + } + value &= mask; + value |= env->cp15.c1_coproc & ~mask; + } if (env->cp15.c1_coproc != value) { env->cp15.c1_coproc = value; /* ??? Is this safe when called from within a TB? */ @@ -2100,11 +2117,23 @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, tlb_flush(CPU(cpu), 1); } +#ifndef CONFIG_USER_ONLY + +static void nsacr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.c1_nsacr = value & 0x3fff; +} +#endif + static const ARMCPRegInfo tz_cp_reginfo[] = { #ifndef CONFIG_USER_ONLY { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr), .resetvalue = 0, }, + { .name = "NSACR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 2, + .access = PL3_RW | PL1_R, .resetvalue = 0, .writefn = nsacr_write, + .fieldoffset = offsetof(CPUARMState, cp15.c1_nsacr) }, #endif REGINFO_SENTINEL }; diff --git a/target-arm/translate.c b/target-arm/translate.c index c815fb3..4ebd9f7 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -6872,6 +6872,13 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn) return 1; } } else { + /* If Security Extensions are implemented NSACR controls non-secure + * access to cp10/cp11 (Bits [11:10]) */ + if (arm_feature(env, ARM_FEATURE_SECURITY_EXTENSIONS) && IS_NS(s) + && (~env->cp15.c1_nsacr & (1 << cpnum))) { + return 1; + } + /* Bits [20:21] of CPACR control access to cp10 * Bits [23:22] of CPACR control access to cp11 */ switch ((env->cp15.c1_coproc >> (cpnum * 2)) & 3) { -- 1.8.3.2