NSACR allows to control non-secure access to coprocessor interfaces 0-13 and CPACR bits.
Signed-off-by: Sergey Fedorov <s.fedo...@samsung.com> --- target-arm/cpu.h | 1 + target-arm/helper.c | 21 +++++++++++++++++++++ target-arm/translate.c | 3 +++ 3 files changed, 25 insertions(+) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index f47dbdf..5aeb630 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -150,6 +150,7 @@ typedef struct CPUARMState { uint32_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. */ uint32_t c2_base0; /* MMU translation table base 0. */ uint32_t c2_base0_hi; /* MMU translation table base 0, high 32 bits */ uint32_t c2_base1; /* MMU translation table base 0. */ diff --git a/target-arm/helper.c b/target-arm/helper.c index 19f5830..b6d8a3c 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -424,6 +424,17 @@ static int cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) mask |= 0x00f00000; /* VFP coprocessor: cp10 & cp11 */ } value &= mask; + if (!arm_is_secure(env)) { + int cpnum; + mask = 0; + for (cpnum = 0; cpnum < 14; ++cpnum) { + if (env->cp15.c1_nsacr & (1 << cpnum)) { + 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? */ @@ -1531,6 +1542,13 @@ static int vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, env->cp15.c12_vbar = value & ~0x1Ful; return 0; } + +static int nsacr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.c1_nsacr = value & 0x3fff; + return 0; +} #endif static const ARMCPRegInfo tz_cp_reginfo[] = { @@ -1542,6 +1560,9 @@ static const ARMCPRegInfo tz_cp_reginfo[] = { .access = PL1_RW, .writefn = vbar_write, .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar), .resetvalue = 0 }, + { .name = "NSACR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 2, + .access = PL3_RW | PL2_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 78612c8..b3615fc 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -6290,6 +6290,9 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn) return 1; } } else { + if (IS_NS(s) & ~env->cp15.c1_nsacr & (1 << cpnum)) { + return 1; + } switch ((env->cp15.c1_coproc >> (cpnum * 2)) & 3) { case 0: case 2: -- 1.7.9.5