aboutsummaryrefslogtreecommitdiff
path: root/target-arm/op_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-arm/op_helper.c')
-rw-r--r--target-arm/op_helper.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index a4507df..79e7d10 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -335,6 +335,7 @@ void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
{
const ARMCPRegInfo *ri = rip;
+ int target_el;
if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
&& extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
@@ -349,15 +350,27 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
case CP_ACCESS_OK:
return;
case CP_ACCESS_TRAP:
+ target_el = exception_target_el(env);
+ break;
+ case CP_ACCESS_TRAP_EL2:
+ /* Requesting a trap to EL2 when we're in EL3 or S-EL0/1 is
+ * a bug in the access function.
+ */
+ assert(!arm_is_secure(env) && !arm_current_el(env) == 3);
+ target_el = 2;
+ break;
+ case CP_ACCESS_TRAP_EL3:
+ target_el = 3;
break;
case CP_ACCESS_TRAP_UNCATEGORIZED:
+ target_el = exception_target_el(env);
syndrome = syn_uncategorized();
break;
default:
g_assert_not_reached();
}
- raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
+ raise_exception(env, EXCP_UDEF, syndrome, target_el);
}
void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)