mirror of https://gitee.com/openkylin/qemu.git
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
This commit is contained in:
parent
665cddbe15
commit
cc7613bfaa
|
@ -1541,6 +1541,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||||
#define SCR_ENSCXT (1U << 25)
|
#define SCR_ENSCXT (1U << 25)
|
||||||
#define SCR_ATA (1U << 26)
|
#define SCR_ATA (1U << 26)
|
||||||
|
|
||||||
|
#define HSTR_TTEE (1 << 16)
|
||||||
|
|
||||||
/* Return the current FPSCR value. */
|
/* Return the current FPSCR value. */
|
||||||
uint32_t vfp_get_fpscr(CPUARMState *env);
|
uint32_t vfp_get_fpscr(CPUARMState *env);
|
||||||
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
|
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
|
||||||
|
|
|
@ -2446,20 +2446,34 @@ static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
env->teecr = value;
|
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,
|
static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
bool isread)
|
bool isread)
|
||||||
{
|
{
|
||||||
if (arm_current_el(env) == 0 && (env->teecr & 1)) {
|
if (arm_current_el(env) == 0 && (env->teecr & 1)) {
|
||||||
return CP_ACCESS_TRAP;
|
return CP_ACCESS_TRAP;
|
||||||
}
|
}
|
||||||
return CP_ACCESS_OK;
|
return teecr_access(env, ri, isread);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ARMCPRegInfo t2ee_cp_reginfo[] = {
|
static const ARMCPRegInfo t2ee_cp_reginfo[] = {
|
||||||
{ .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0,
|
{ .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0,
|
||||||
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr),
|
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr),
|
||||||
.resetvalue = 0,
|
.resetvalue = 0,
|
||||||
.writefn = teecr_write },
|
.writefn = teecr_write, .accessfn = teecr_access },
|
||||||
{ .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
|
{ .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
|
||||||
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
|
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
|
||||||
.accessfn = teehbr_access, .resetvalue = 0 },
|
.accessfn = teehbr_access, .resetvalue = 0 },
|
||||||
|
|
Loading…
Reference in New Issue