Commit 9332f9dafa33b085488a5369333213d549dbdc7f
1 parent
e8ebb8a8
ARM CPU suspend/halt (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1663 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
28 additions
and
1 deletions
cpu-exec.c
... | ... | @@ -274,6 +274,17 @@ int cpu_exec(CPUState *env1) |
274 | 274 | return EXCP_HALTED; |
275 | 275 | } |
276 | 276 | } |
277 | +#elif defined(TARGET_ARM) | |
278 | + if (env1->halted) { | |
279 | + /* An interrupt wakes the CPU even if the I and F CPSR bits are | |
280 | + set. */ | |
281 | + if (env1->interrupt_request | |
282 | + & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD)) { | |
283 | + env1->halted = 0; | |
284 | + } else { | |
285 | + return EXCP_HALTED; | |
286 | + } | |
287 | + } | |
277 | 288 | #endif |
278 | 289 | |
279 | 290 | cpu_single_env = env1; | ... | ... |
target-arm/cpu.h
target-arm/op.c
... | ... | @@ -878,6 +878,13 @@ void OPPROTO op_debug(void) |
878 | 878 | cpu_loop_exit(); |
879 | 879 | } |
880 | 880 | |
881 | +void OPPROTO op_wfi(void) | |
882 | +{ | |
883 | + env->exception_index = EXCP_HLT; | |
884 | + env->halted = 1; | |
885 | + cpu_loop_exit(); | |
886 | +} | |
887 | + | |
881 | 888 | /* VFP support. We follow the convention used for VFP instrunctions: |
882 | 889 | Single precition routines have a "s" suffix, double precision a |
883 | 890 | "d" suffix. */ | ... | ... |
target-arm/translate.c
... | ... | @@ -496,6 +496,15 @@ static int disas_cp15_insn(DisasContext *s, uint32_t insn) |
496 | 496 | if (IS_USER(s)) { |
497 | 497 | return 1; |
498 | 498 | } |
499 | + if ((insn & 0x0fff0fff) == 0x0e070f90 | |
500 | + || (insn & 0x0fff0fff) == 0x0e070f58) { | |
501 | + /* Wait for interrupt. */ | |
502 | + gen_op_movl_T0_im((long)s->pc); | |
503 | + gen_op_movl_reg_TN[0][15](); | |
504 | + gen_op_wfi(); | |
505 | + s->is_jmp = DISAS_JUMP; | |
506 | + return 0; | |
507 | + } | |
499 | 508 | rd = (insn >> 12) & 0xf; |
500 | 509 | if (insn & (1 << 20)) { |
501 | 510 | gen_op_movl_T0_cp15(insn); | ... | ... |