Commit 9332f9da authored by Fabrice Bellard's avatar Fabrice Bellard
Browse files

ARM CPU suspend/halt (Paul Brook)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1663 c046a42c-6fe2-441c-8c8c-71466251a162
parent e8ebb8a8
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -274,6 +274,17 @@ int cpu_exec(CPUState *env1)
            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; 
+1 −1
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ typedef struct CPUARMState {
    int exception_index;
    int interrupt_request;
    int user_mode_only;
    uint32_t address;
    int halted;

    /* VFP coprocessor state.  */
    struct {
+7 −0
Original line number Diff line number Diff line
@@ -878,6 +878,13 @@ void OPPROTO op_debug(void)
    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.  */
+9 −0
Original line number Diff line number Diff line
@@ -496,6 +496,15 @@ static int disas_cp15_insn(DisasContext *s, uint32_t insn)
    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);