aboutsummaryrefslogtreecommitdiff
path: root/cpu-exec.c
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-11 00:04:49 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-11 00:04:49 +0000
commit9ee6e8bb853bdea7ef6c645a1a07aa55fd206aba (patch)
tree1cd430d3d9ac641c8550cfd8956dbcce1a4b9121 /cpu-exec.c
parentee4e83ed8ddc8dac572a0123398adf78b63014ae (diff)
downloadqemu-9ee6e8bb853bdea7ef6c645a1a07aa55fd206aba.zip
qemu-9ee6e8bb853bdea7ef6c645a1a07aa55fd206aba.tar.gz
qemu-9ee6e8bb853bdea7ef6c645a1a07aa55fd206aba.tar.bz2
ARMv7 support.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3572 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'cpu-exec.c')
-rw-r--r--cpu-exec.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/cpu-exec.c b/cpu-exec.c
index 4ba63fb..aa58cbb 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -173,6 +173,7 @@ static inline TranslationBlock *tb_find_fast(void)
flags |= (1 << 6);
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
flags |= (1 << 7);
+ flags |= (env->condexec_bits << 8);
cs_base = 0;
pc = env->regs[15];
#elif defined(TARGET_SPARC)
@@ -511,8 +512,18 @@ int cpu_exec(CPUState *env1)
env->exception_index = EXCP_FIQ;
do_interrupt(env);
}
+ /* 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 occured at the wrong time.
+ We avoid this by disabling interrupts when
+ pc contains a magic address. */
if (interrupt_request & CPU_INTERRUPT_HARD
- && !(env->uncached_cpsr & CPSR_I)) {
+ && ((IS_M(env) && env->regs[15] < 0xfffffff0)
+ || !(env->uncached_cpsr & CPSR_I))) {
env->exception_index = EXCP_IRQ;
do_interrupt(env);
}