diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-08-16 19:03:04 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-08-26 17:02:01 +0100 |
commit | cc7613bfaa1f653a6eb6ff50ac45d5c5fd717052 (patch) | |
tree | 542ec7f1f8e56ec4555ecd4c8fa3c4a173b6632e /target/arm | |
parent | 665cddbe15fdc5f5c66caac62472bd5af1e23e10 (diff) |
target/arm: Implement HSTR.TTEE
In v7, the HSTR register has a TTEE bit which allows EL0/EL1 accesses
to the Thumb2EE TEECR and TEEHBR registers to be trapped to the
hypervisor. Implement these traps.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210816180305.20137-2-peter.maydell@linaro.org
Diffstat (limited to 'target/arm')
-rw-r--r-- | target/arm/cpu.h | 2 | ||||
-rw-r--r-- | target/arm/helper.c | 18 |
2 files changed, 18 insertions, 2 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 1060825c74..0cd3206041 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1541,6 +1541,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) #define SCR_ENSCXT (1U << 25) #define SCR_ATA (1U << 26) +#define HSTR_TTEE (1 << 16) + /* Return the current FPSCR value. */ uint32_t vfp_get_fpscr(CPUARMState *env); void vfp_set_fpscr(CPUARMState *env, uint32_t val); diff --git a/target/arm/helper.c b/target/arm/helper.c index 56c520cf8e..54ac8c54b1 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -2446,20 +2446,34 @@ static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri, env->teecr = value; } +static CPAccessResult teecr_access(CPUARMState *env, const ARMCPRegInfo *ri, + bool isread) +{ + /* + * HSTR.TTEE only exists in v7A, not v8A, but v8A doesn't have T2EE + * at all, so we don't need to check whether we're v8A. + */ + if (arm_current_el(env) < 2 && !arm_is_secure_below_el3(env) && + (env->cp15.hstr_el2 & HSTR_TTEE)) { + return CP_ACCESS_TRAP_EL2; + } + return CP_ACCESS_OK; +} + static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { if (arm_current_el(env) == 0 && (env->teecr & 1)) { return CP_ACCESS_TRAP; } - return CP_ACCESS_OK; + return teecr_access(env, ri, isread); } static const ARMCPRegInfo t2ee_cp_reginfo[] = { { .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0, .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr), .resetvalue = 0, - .writefn = teecr_write }, + .writefn = teecr_write, .accessfn = teecr_access }, { .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0, .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr), .accessfn = teehbr_access, .resetvalue = 0 }, |