summaryrefslogtreecommitdiffstats
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.c52
1 files changed, 24 insertions, 28 deletions
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index c4bd668870..c5bde1cfcc 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -28,6 +28,21 @@
#define SIGNBIT (uint32_t)0x80000000
#define SIGNBIT64 ((uint64_t)1 << 63)
+int exception_target_el(CPUARMState *env)
+{
+ int target_el = MAX(1, arm_current_el(env));
+
+ /*
+ * No such thing as secure EL1 if EL3 is aarch32,
+ * so update the target EL to EL3 in this case.
+ */
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) {
+ target_el = 3;
+ }
+
+ return target_el;
+}
+
void raise_exception(CPUARMState *env, uint32_t excp,
uint32_t syndrome, uint32_t target_el)
{
@@ -366,7 +381,7 @@ void HELPER(yield)(CPUARMState *env)
* those EXCP values which are special cases for QEMU to interrupt
* execution and not to be used for exceptions which are passed to
* the guest (those must all have syndrome information and thus should
- * use exception_with_syndrome).
+ * use exception_with_syndrome*).
*/
void HELPER(exception_internal)(CPUARMState *env, uint32_t excp)
{
@@ -378,39 +393,20 @@ void HELPER(exception_internal)(CPUARMState *env, uint32_t excp)
}
/* Raise an exception with the specified syndrome register value */
-void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
- uint32_t syndrome, uint32_t target_el)
+void HELPER(exception_with_syndrome_el)(CPUARMState *env, uint32_t excp,
+ uint32_t syndrome, uint32_t target_el)
{
raise_exception(env, excp, syndrome, target_el);
}
-/* Raise an EXCP_BKPT with the specified syndrome register value,
- * targeting the correct exception level for debug exceptions.
+/*
+ * Raise an exception with the specified syndrome register value
+ * to the default target el.
*/
-void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
+void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
+ uint32_t syndrome)
{
- int debug_el = arm_debug_target_el(env);
- int cur_el = arm_current_el(env);
-
- /* FSR will only be used if the debug target EL is AArch32. */
- env->exception.fsr = arm_debug_exception_fsr(env);
- /* FAR is UNKNOWN: clear vaddress to avoid potentially exposing
- * values to the guest that it shouldn't be able to see at its
- * exception/security level.
- */
- env->exception.vaddress = 0;
- /*
- * Other kinds of architectural debug exception are ignored if
- * they target an exception level below the current one (in QEMU
- * this is checked by arm_generate_debug_exceptions()). Breakpoint
- * instructions are special because they always generate an exception
- * to somewhere: if they can't go to the configured debug exception
- * level they are taken to the current exception level.
- */
- if (debug_el < cur_el) {
- debug_el = cur_el;
- }
- raise_exception(env, EXCP_BKPT, syndrome, debug_el);
+ raise_exception(env, excp, syndrome, exception_target_el(env));
}
uint32_t HELPER(cpsr_read)(CPUARMState *env)