target/arm: Update arm_sctlr for VHE
Use the correct sctlr for EL2&0 regime. Due to header ordering, and where arm_mmu_idx_el is declared, we need to move the function out of line. Use the function in many more places in order to select the correct control. Tested-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200206105448.4726-23-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
6003d9800e
commit
aaec143212
|
@ -3141,15 +3141,7 @@ static inline bool arm_sctlr_b(CPUARMState *env)
|
||||||
(env->cp15.sctlr_el[1] & SCTLR_B) != 0;
|
(env->cp15.sctlr_el[1] & SCTLR_B) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t arm_sctlr(CPUARMState *env, int el)
|
uint64_t arm_sctlr(CPUARMState *env, int el);
|
||||||
{
|
|
||||||
if (el == 0) {
|
|
||||||
/* FIXME: ARMv8.1-VHE S2 translation regime. */
|
|
||||||
return env->cp15.sctlr_el[1];
|
|
||||||
} else {
|
|
||||||
return env->cp15.sctlr_el[el];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
|
static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
|
||||||
bool sctlr_b)
|
bool sctlr_b)
|
||||||
|
|
|
@ -70,7 +70,7 @@ static void daif_check(CPUARMState *env, uint32_t op,
|
||||||
uint32_t imm, uintptr_t ra)
|
uint32_t imm, uintptr_t ra)
|
||||||
{
|
{
|
||||||
/* DAIF update to PSTATE. This is OK from EL0 only if UMA is set. */
|
/* DAIF update to PSTATE. This is OK from EL0 only if UMA is set. */
|
||||||
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
|
if (arm_current_el(env) == 0 && !(arm_sctlr(env, 0) & SCTLR_UMA)) {
|
||||||
raise_exception_ra(env, EXCP_UDEF,
|
raise_exception_ra(env, EXCP_UDEF,
|
||||||
syn_aa64_sysregtrap(0, extract32(op, 0, 3),
|
syn_aa64_sysregtrap(0, extract32(op, 0, 3),
|
||||||
extract32(op, 3, 3), 4,
|
extract32(op, 3, 3), 4,
|
||||||
|
|
|
@ -3913,7 +3913,7 @@ static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
bool isread)
|
bool isread)
|
||||||
{
|
{
|
||||||
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
|
if (arm_current_el(env) == 0 && !(arm_sctlr(env, 0) & SCTLR_UMA)) {
|
||||||
return CP_ACCESS_TRAP;
|
return CP_ACCESS_TRAP;
|
||||||
}
|
}
|
||||||
return CP_ACCESS_OK;
|
return CP_ACCESS_OK;
|
||||||
|
@ -3932,7 +3932,7 @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
|
||||||
/* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
|
/* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
|
||||||
* SCTLR_EL1.UCI is set.
|
* SCTLR_EL1.UCI is set.
|
||||||
*/
|
*/
|
||||||
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCI)) {
|
if (arm_current_el(env) == 0 && !(arm_sctlr(env, 0) & SCTLR_UCI)) {
|
||||||
return CP_ACCESS_TRAP;
|
return CP_ACCESS_TRAP;
|
||||||
}
|
}
|
||||||
return CP_ACCESS_OK;
|
return CP_ACCESS_OK;
|
||||||
|
@ -8738,14 +8738,24 @@ static uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
uint64_t arm_sctlr(CPUARMState *env, int el)
|
||||||
|
{
|
||||||
|
/* Only EL0 needs to be adjusted for EL1&0 or EL2&0. */
|
||||||
|
if (el == 0) {
|
||||||
|
ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, 0);
|
||||||
|
el = (mmu_idx == ARMMMUIdx_E20_0 ? 2 : 1);
|
||||||
|
}
|
||||||
|
return env->cp15.sctlr_el[el];
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the SCTLR value which controls this address translation regime */
|
/* Return the SCTLR value which controls this address translation regime */
|
||||||
static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
|
static inline uint64_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||||
{
|
{
|
||||||
return env->cp15.sctlr_el[regime_el(env, mmu_idx)];
|
return env->cp15.sctlr_el[regime_el(env, mmu_idx)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
|
||||||
/* Return true if the specified stage of address translation is disabled */
|
/* Return true if the specified stage of address translation is disabled */
|
||||||
static inline bool regime_translation_disabled(CPUARMState *env,
|
static inline bool regime_translation_disabled(CPUARMState *env,
|
||||||
ARMMMUIdx mmu_idx)
|
ARMMMUIdx mmu_idx)
|
||||||
|
@ -11484,7 +11494,7 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
|
||||||
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
|
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
sctlr = arm_sctlr(env, el);
|
sctlr = regime_sctlr(env, stage1);
|
||||||
|
|
||||||
if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
|
if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
|
||||||
flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
|
flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
|
||||||
|
|
|
@ -386,14 +386,7 @@ static void pauth_check_trap(CPUARMState *env, int el, uintptr_t ra)
|
||||||
|
|
||||||
static bool pauth_key_enabled(CPUARMState *env, int el, uint32_t bit)
|
static bool pauth_key_enabled(CPUARMState *env, int el, uint32_t bit)
|
||||||
{
|
{
|
||||||
uint32_t sctlr;
|
return (arm_sctlr(env, el) & bit) != 0;
|
||||||
if (el == 0) {
|
|
||||||
/* FIXME: ARMv8.1-VHE S2 translation regime. */
|
|
||||||
sctlr = env->cp15.sctlr_el[1];
|
|
||||||
} else {
|
|
||||||
sctlr = env->cp15.sctlr_el[el];
|
|
||||||
}
|
|
||||||
return (sctlr & bit) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t HELPER(pacia)(CPUARMState *env, uint64_t x, uint64_t y)
|
uint64_t HELPER(pacia)(CPUARMState *env, uint64_t x, uint64_t y)
|
||||||
|
|
Loading…
Reference in a new issue