ARM CPU suspend/halt (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1663 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
e8ebb8a8d7
commit
9332f9dafa
11
cpu-exec.c
11
cpu-exec.c
@ -274,6 +274,17 @@ int cpu_exec(CPUState *env1)
|
|||||||
return EXCP_HALTED;
|
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
|
#endif
|
||||||
|
|
||||||
cpu_single_env = env1;
|
cpu_single_env = env1;
|
||||||
|
@ -90,7 +90,7 @@ typedef struct CPUARMState {
|
|||||||
int exception_index;
|
int exception_index;
|
||||||
int interrupt_request;
|
int interrupt_request;
|
||||||
int user_mode_only;
|
int user_mode_only;
|
||||||
uint32_t address;
|
int halted;
|
||||||
|
|
||||||
/* VFP coprocessor state. */
|
/* VFP coprocessor state. */
|
||||||
struct {
|
struct {
|
||||||
|
@ -878,6 +878,13 @@ void OPPROTO op_debug(void)
|
|||||||
cpu_loop_exit();
|
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:
|
/* VFP support. We follow the convention used for VFP instrunctions:
|
||||||
Single precition routines have a "s" suffix, double precision a
|
Single precition routines have a "s" suffix, double precision a
|
||||||
"d" suffix. */
|
"d" suffix. */
|
||||||
|
@ -496,6 +496,15 @@ static int disas_cp15_insn(DisasContext *s, uint32_t insn)
|
|||||||
if (IS_USER(s)) {
|
if (IS_USER(s)) {
|
||||||
return 1;
|
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;
|
rd = (insn >> 12) & 0xf;
|
||||||
if (insn & (1 << 20)) {
|
if (insn & (1 << 20)) {
|
||||||
gen_op_movl_T0_cp15(insn);
|
gen_op_movl_T0_cp15(insn);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user