Commit 9332f9dafa33b085488a5369333213d549dbdc7f

Authored by bellard
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
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
... ... @@ -90,7 +90,7 @@ typedef struct CPUARMState {
90 90 int exception_index;
91 91 int interrupt_request;
92 92 int user_mode_only;
93   - uint32_t address;
  93 + int halted;
94 94  
95 95 /* VFP coprocessor state. */
96 96 struct {
... ...
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);
... ...