diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h index 1759d9defb..fbf5798069 100644 --- a/target/arm/cpregs.h +++ b/target/arm/cpregs.h @@ -331,6 +331,7 @@ typedef enum CPAccessResult { * 0xc or 0x18). */ CP_ACCESS_TRAP = (1 << 2), + CP_ACCESS_TRAP_EL1 = CP_ACCESS_TRAP | 1, CP_ACCESS_TRAP_EL2 = CP_ACCESS_TRAP | 2, CP_ACCESS_TRAP_EL3 = CP_ACCESS_TRAP | 3, diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c index 1ba727e8e9..c427118655 100644 --- a/target/arm/tcg/op_helper.c +++ b/target/arm/tcg/op_helper.c @@ -781,7 +781,7 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key, * the other trap takes priority. So we take the "check HSTR_EL2" path * for all of those cases.) */ - if (res != CP_ACCESS_OK && ((res & CP_ACCESS_EL_MASK) == 0) && + if (res != CP_ACCESS_OK && ((res & CP_ACCESS_EL_MASK) < 2) && arm_current_el(env) == 0) { goto fail; } @@ -887,6 +887,9 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key, case 0: target_el = exception_target_el(env); break; + case 1: + assert(arm_current_el(env) < 2); + break; case 2: assert(arm_current_el(env) != 3); assert(arm_is_el2_enabled(env)); @@ -895,7 +898,6 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key, assert(arm_feature(env, ARM_FEATURE_EL3)); break; default: - /* No "direct" traps to EL1 */ g_assert_not_reached(); }