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,6 +274,17 @@ int cpu_exec(CPUState *env1) | ||
274 | return EXCP_HALTED; | 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 | #endif | 288 | #endif |
278 | 289 | ||
279 | cpu_single_env = env1; | 290 | cpu_single_env = env1; |
target-arm/cpu.h
@@ -90,7 +90,7 @@ typedef struct CPUARMState { | @@ -90,7 +90,7 @@ typedef struct CPUARMState { | ||
90 | int exception_index; | 90 | int exception_index; |
91 | int interrupt_request; | 91 | int interrupt_request; |
92 | int user_mode_only; | 92 | int user_mode_only; |
93 | - uint32_t address; | 93 | + int halted; |
94 | 94 | ||
95 | /* VFP coprocessor state. */ | 95 | /* VFP coprocessor state. */ |
96 | struct { | 96 | struct { |
target-arm/op.c
@@ -878,6 +878,13 @@ void OPPROTO op_debug(void) | @@ -878,6 +878,13 @@ void OPPROTO op_debug(void) | ||
878 | cpu_loop_exit(); | 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 | /* VFP support. We follow the convention used for VFP instrunctions: | 888 | /* VFP support. We follow the convention used for VFP instrunctions: |
882 | Single precition routines have a "s" suffix, double precision a | 889 | Single precition routines have a "s" suffix, double precision a |
883 | "d" suffix. */ | 890 | "d" suffix. */ |
target-arm/translate.c
@@ -496,6 +496,15 @@ static int disas_cp15_insn(DisasContext *s, uint32_t insn) | @@ -496,6 +496,15 @@ static int disas_cp15_insn(DisasContext *s, uint32_t insn) | ||
496 | if (IS_USER(s)) { | 496 | if (IS_USER(s)) { |
497 | return 1; | 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 | rd = (insn >> 12) & 0xf; | 508 | rd = (insn >> 12) & 0xf; |
500 | if (insn & (1 << 20)) { | 509 | if (insn & (1 << 20)) { |
501 | gen_op_movl_T0_cp15(insn); | 510 | gen_op_movl_T0_cp15(insn); |