aboutsummaryrefslogtreecommitdiff
path: root/target-arm/cpu.h
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-10-30 15:48:51 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-11-04 12:05:23 +0000
commitb5c633c5bd6993df1bf3401d94042fb8a910a92a (patch)
treecdffe89d50200c7f4098a45773d2b1e099b238b7 /target-arm/cpu.h
parentf4df22102a0081ff1bd0df4cb5552411e410eb3e (diff)
target-arm: Separate out M profile cpu_exec_interrupt handling
The M profile cpu_exec_interrupt handling is fairly simple but does include an M profile specific oddity (disabling interrupts for certain PC values). A/R profile handling on the other hand is getting rapidly more complicated with the support for EL2 and EL3. Split the M profile code out into its own implementation of cpu_exec_interrupt to keep these two things out of each others' way. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Message-id: 1414684132-23971-2-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'target-arm/cpu.h')
-rw-r--r--target-arm/cpu.h16
1 files changed, 2 insertions, 14 deletions
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index cb6ec5c59f..97eaf79696 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1251,18 +1251,6 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
bool secure = false;
/* If in EL1/0, Physical IRQ routing to EL2 only happens from NS state. */
bool irq_can_hyp = !secure && cur_el < 2 && target_el == 2;
- /* ARMv7-M interrupt return works by loading a magic value
- * into the PC. On real hardware the load causes the
- * return to occur. The qemu implementation performs the
- * jump normally, then does the exception return when the
- * CPU tries to execute code at the magic address.
- * This will cause the magic PC value to be pushed to
- * the stack if an interrupt occurred at the wrong time.
- * We avoid this by disabling interrupts when
- * pc contains a magic address.
- */
- bool irq_unmasked = !(env->daif & PSTATE_I)
- && (!IS_M(env) || env->regs[15] < 0xfffffff0);
/* Don't take exceptions if they target a lower EL. */
if (cur_el > target_el) {
@@ -1279,7 +1267,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
if (irq_can_hyp && (env->cp15.hcr_el2 & HCR_IMO)) {
return true;
}
- return irq_unmasked;
+ return !(env->daif & PSTATE_I);
case EXCP_VFIQ:
if (!secure && !(env->cp15.hcr_el2 & HCR_FMO)) {
/* VFIQs are only taken when hypervized and non-secure. */
@@ -1291,7 +1279,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
/* VIRQs are only taken when hypervized and non-secure. */
return false;
}
- return irq_unmasked;
+ return !(env->daif & PSTATE_I);
default:
g_assert_not_reached();
}