diff options
-rw-r--r-- | cpu-all.h | 2 | ||||
-rw-r--r-- | cpu-exec.c | 5 | ||||
-rw-r--r-- | target-alpha/exec.h | 7 | ||||
-rw-r--r-- | target-arm/exec.h | 9 | ||||
-rw-r--r-- | target-cris/exec.h | 5 | ||||
-rw-r--r-- | target-i386/exec.h | 15 | ||||
-rw-r--r-- | target-m68k/exec.h | 7 | ||||
-rw-r--r-- | target-mips/exec.h | 10 | ||||
-rw-r--r-- | target-ppc/exec.h | 8 | ||||
-rw-r--r-- | target-sh4/exec.h | 7 | ||||
-rw-r--r-- | target-sparc/exec.h | 9 |
11 files changed, 72 insertions, 12 deletions
@@ -775,6 +775,8 @@ void cpu_reset_interrupt(CPUState *env, int mask); void cpu_exit(CPUState *s); +int qemu_cpu_has_work(CPUState *env); + /* Breakpoint/watchpoint flags */ #define BP_MEM_READ 0x01 #define BP_MEM_WRITE 0x02 diff --git a/cpu-exec.c b/cpu-exec.c index 122bdd10b8..90f879bbf8 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -50,6 +50,11 @@ int tb_invalidated_flag; //#define DEBUG_EXEC //#define DEBUG_SIGNAL +int qemu_cpu_has_work(CPUState *env) +{ + return cpu_has_work(env); +} + void cpu_loop_exit(void) { /* NOTE: the register at this point must be saved by hand because diff --git a/target-alpha/exec.h b/target-alpha/exec.h index 9ea70305ef..77eaf53c10 100644 --- a/target-alpha/exec.h +++ b/target-alpha/exec.h @@ -48,10 +48,15 @@ static always_inline void regs_to_env(void) { } +static always_inline int cpu_has_work(CPUState *env) +{ + return (env->interrupt_request & CPU_INTERRUPT_HARD); +} + static always_inline int cpu_halted(CPUState *env) { if (!env->halted) return 0; - if (env->interrupt_request & CPU_INTERRUPT_HARD) { + if (cpu_has_work(env)) { env->halted = 0; return 0; } diff --git a/target-arm/exec.h b/target-arm/exec.h index 3e4083a61b..710a2f9882 100644 --- a/target-arm/exec.h +++ b/target-arm/exec.h @@ -37,14 +37,19 @@ static inline void regs_to_env(void) { } +static inline int cpu_has_work(CPUState *env) +{ + return (env->interrupt_request & + (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB)); +} + static inline int cpu_halted(CPUState *env) { if (!env->halted) return 0; /* An interrupt wakes the CPU even if the I and F CPSR bits are set. We use EXITTB to silently wake CPU without causing an actual interrupt. */ - if (env->interrupt_request & - (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB)) { + if (cpu_has_work(env)) { env->halted = 0; return 0; } diff --git a/target-cris/exec.h b/target-cris/exec.h index 77e4240e89..5f3cc00178 100644 --- a/target-cris/exec.h +++ b/target-cris/exec.h @@ -40,6 +40,11 @@ static inline void regs_to_env(void) void cpu_cris_flush_flags(CPUCRISState *env, int cc_op); void helper_movec(CPUCRISState *env, int reg, uint32_t val); +static inline int cpu_has_work(CPUState *env) +{ + return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI)); +} + static inline int cpu_halted(CPUState *env) { if (!env->halted) return 0; diff --git a/target-i386/exec.h b/target-i386/exec.h index b51667a1f6..fbaf5bc984 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -338,14 +338,23 @@ static inline void regs_to_env(void) #endif } +static inline int cpu_has_work(CPUState *env) +{ + int work; + + work = (env->interrupt_request & CPU_INTERRUPT_HARD) && + (env->eflags & IF_MASK); + work |= env->interrupt_request & CPU_INTERRUPT_NMI; + + return work; +} + static inline int cpu_halted(CPUState *env) { /* handle exit of HALTED state */ if (!env->halted) return 0; /* disable halt condition */ - if (((env->interrupt_request & CPU_INTERRUPT_HARD) && - (env->eflags & IF_MASK)) || - (env->interrupt_request & CPU_INTERRUPT_NMI)) { + if (cpu_has_work(env)) { env->halted = 0; return 0; } diff --git a/target-m68k/exec.h b/target-m68k/exec.h index fba371cf40..3a86b1f891 100644 --- a/target-m68k/exec.h +++ b/target-m68k/exec.h @@ -41,10 +41,15 @@ static inline void regs_to_env(void) #include "softmmu_exec.h" #endif +static inline int cpu_has_work(CPUState *env) +{ + return (env->interrupt_request & (CPU_INTERRUPT_HARD)); +} + static inline int cpu_halted(CPUState *env) { if (!env->halted) return 0; - if (env->interrupt_request & CPU_INTERRUPT_HARD) { + if (cpu_has_work(env)) { env->halted = 0; return 0; } diff --git a/target-mips/exec.h b/target-mips/exec.h index 18765f9679..8a118bb6b3 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -33,12 +33,18 @@ static inline void regs_to_env(void) { } +static inline int cpu_has_work(CPUState *env) +{ + return (env->interrupt_request & + (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)); +} + + static inline int cpu_halted(CPUState *env) { if (!env->halted) return 0; - if (env->interrupt_request & - (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)) { + if (cpu_has_work(env)) { env->halted = 0; return 0; } diff --git a/target-ppc/exec.h b/target-ppc/exec.h index d89698c63a..f6b9ee6c83 100644 --- a/target-ppc/exec.h +++ b/target-ppc/exec.h @@ -44,11 +44,17 @@ static always_inline void regs_to_env (void) { } +static always_inline int cpu_has_work(CPUState *env) +{ + return (msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD)); +} + + static always_inline int cpu_halted (CPUState *env) { if (!env->halted) return 0; - if (msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD)) { + if (cpu_has_work(env)) { env->halted = 0; return 0; } diff --git a/target-sh4/exec.h b/target-sh4/exec.h index ad26990c5e..d2926750b3 100644 --- a/target-sh4/exec.h +++ b/target-sh4/exec.h @@ -28,10 +28,15 @@ register struct CPUSH4State *env asm(AREG0); #include "cpu.h" #include "exec-all.h" +static inline int cpu_has_work(CPUState *env) +{ + return (env->interrupt_request & CPU_INTERRUPT_HARD); +} + static inline int cpu_halted(CPUState *env) { if (!env->halted) return 0; - if (env->interrupt_request & CPU_INTERRUPT_HARD) { + if (cpu_has_work(env)) { env->halted = 0; env->intr_at_halt = 1; return 0; diff --git a/target-sparc/exec.h b/target-sparc/exec.h index 36fd1176fc..f37c8ad994 100644 --- a/target-sparc/exec.h +++ b/target-sparc/exec.h @@ -24,10 +24,17 @@ static inline void regs_to_env(void) /* op_helper.c */ void do_interrupt(CPUState *env); +static inline int cpu_has_work(CPUState *env1) +{ + return (env1->interrupt_request & CPU_INTERRUPT_HARD) && + (env1->psret != 0); +} + + static inline int cpu_halted(CPUState *env1) { if (!env1->halted) return 0; - if ((env1->interrupt_request & CPU_INTERRUPT_HARD) && (env1->psret != 0)) { + if (cpu_has_work(env1)) { env1->halted = 0; return 0; } |