The attached patch implements Arm CPU suspend/halt.
Paul
=== cpu-exec.c ================================================================== --- cpu-exec.c (revision 1861) +++ cpu-exec.c (local) @@ -274,6 +274,17 @@ return EXCP_HALTED; } } +#elif defined(TARGET_ARM) + if (env1->halted) { + /* An interrupt wakes the CPU even if the I and F CPSR bits are + set. */ + if (env1->interrupt_request + & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD)) { + env1->halted = 0; + } else { + return EXCP_HALTED; + } + } #endif cpu_single_env = env1; === target-arm/cpu.h ================================================================== --- target-arm/cpu.h (revision 1861) +++ target-arm/cpu.h (local) @@ -90,7 +90,7 @@ int exception_index; int interrupt_request; int user_mode_only; - uint32_t address; + int halted; /* VFP coprocessor state. */ struct { === target-arm/op.c ================================================================== --- target-arm/op.c (revision 1861) +++ target-arm/op.c (local) @@ -878,6 +878,13 @@ cpu_loop_exit(); } +void OPPROTO op_wfi(void) +{ + env->exception_index = EXCP_HLT; + env->halted = 1; + cpu_loop_exit(); +} + /* VFP support. We follow the convention used for VFP instrunctions: Single precition routines have a "s" suffix, double precision a "d" suffix. */ === target-arm/translate.c ================================================================== --- target-arm/translate.c (revision 1861) +++ target-arm/translate.c (local) @@ -496,6 +496,15 @@ if (IS_USER(s)) { return 1; } + if ((insn & 0x0fff0fff) == 0x0e070f90 + || (insn & 0x0fff0fff) == 0x0e070f58) { + /* Wait for interrupt. */ + gen_op_movl_T0_im((long)s->pc); + gen_op_movl_reg_TN[0][15](); + gen_op_wfi(); + s->is_jmp = DISAS_JUMP; + return 0; + } rd = (insn >> 12) & 0xf; if (insn & (1 << 20)) { gen_op_movl_T0_cp15(insn);
_______________________________________________ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel