]> git.proxmox.com Git - mirror_qemu.git/commitdiff
reduced irq latency
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 30 Jun 2003 13:12:32 +0000 (13:12 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 30 Jun 2003 13:12:32 +0000 (13:12 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@296 c046a42c-6fe2-441c-8c8c-71466251a162

cpu-all.h
cpu-exec.c
cpu-i386.h
exec.c
linux-user/signal.c
translate-i386.c

index cc0a4ea33fdb22faeb5e3e8dce46babf1dcd0888..5c414e805fd9fba912ea5e5d7bc4288493514030 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -309,6 +309,10 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size);
 void cpu_abort(CPUState *env, const char *fmt, ...);
 extern CPUState *cpu_single_env;
 
+#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
+#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
+void cpu_interrupt(CPUX86State *s, int mask);
+
 /* gdb stub API */
 extern int gdbstub_fd;
 CPUState *cpu_gdbstub_get_env(void *opaque);
index aa2ee3a9e3e2bfc37dbb200b75630dfaa5427228..4da3641e6fc6f720d1a387e7c1f8b5899abf1972 100644 (file)
@@ -71,7 +71,7 @@ int cpu_exec(CPUState *env1)
 #ifdef __sparc__
     int saved_i7, tmp_T0;
 #endif
-    int code_gen_size, ret;
+    int code_gen_size, ret, interrupt_request;
     void (*gen_func)(void);
     TranslationBlock *tb, **ptb;
     uint8_t *tc_ptr, *cs_base, *pc;
@@ -139,7 +139,6 @@ int cpu_exec(CPUState *env1)
 #else
 #error unsupported target CPU
 #endif
-    env->interrupt_request = 0;
     env->exception_index = -1;
 
     /* prepare setjmp context for exception handling */
@@ -176,28 +175,32 @@ int cpu_exec(CPUState *env1)
                 }
                 env->exception_index = -1;
             }
-#if defined(TARGET_I386)
-            /* if hardware interrupt pending, we execute it */
-            if (env->hard_interrupt_request &&
-                (env->eflags & IF_MASK)) {
-                int intno;
-                intno = cpu_x86_get_pic_interrupt(env);
-                if (loglevel) {
-                    fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
-                }
-                do_interrupt(intno, 0, 0, 0);
-                env->hard_interrupt_request = 0;
-            }
-#endif
             T0 = 0; /* force lookup of first TB */
             for(;;) {
 #ifdef __sparc__
                 /* g1 can be modified by some libc? functions */ 
                 tmp_T0 = T0;
 #endif     
-                if (env->interrupt_request) {
-                    env->exception_index = EXCP_INTERRUPT;
-                    cpu_loop_exit();
+                interrupt_request = env->interrupt_request;
+                if (interrupt_request) {
+#if defined(TARGET_I386)
+                    /* if hardware interrupt pending, we execute it */
+                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
+                        (env->eflags & IF_MASK)) {
+                        int intno;
+                        intno = cpu_x86_get_pic_interrupt(env);
+                        if (loglevel) {
+                            fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
+                        }
+                        do_interrupt(intno, 0, 0, 0);
+                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                    }
+#endif
+                    if (interrupt_request & CPU_INTERRUPT_EXIT) {
+                        env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
+                        env->exception_index = EXCP_INTERRUPT;
+                        cpu_loop_exit();
+                    }
                 }
 #ifdef DEBUG_EXEC
                 if (loglevel) {
@@ -212,7 +215,7 @@ int cpu_exec(CPUState *env1)
                     env->regs[R_EBP] = EBP;
                     env->regs[R_ESP] = ESP;
                     env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
-                    cpu_x86_dump_state(env, logfile, 0);
+                    cpu_x86_dump_state(env, logfile, X86_DUMP_CCOP);
                     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
 #elif defined(TARGET_ARM)
                     cpu_arm_dump_state(env, logfile, 0);
@@ -454,7 +457,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
 {
     TranslationBlock *tb;
     int ret;
-    
+
     if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)
index 6c7afbf6e29c9cacab34b7ef7fa576a5c1f2ea21..4029746c80fc8a66110cead4326edf4c61c3f52c 100644 (file)
@@ -254,10 +254,7 @@ typedef struct CPUX86State {
     struct TranslationBlock *current_tb; /* currently executing TB */
     uint32_t cr[5]; /* NOTE: cr1 is unused */
     uint32_t dr[8]; /* debug registers */
-    int interrupt_request; /* if true, will exit from cpu_exec() ASAP */
-    /* if true, will call cpu_x86_get_pic_interrupt() ASAP to get the
-       request interrupt number */
-    int hard_interrupt_request; 
+    int interrupt_request; 
     int user_mode_only; /* user mode only simulation */
     
     /* user data */
@@ -275,7 +272,6 @@ int cpu_x86_inl(CPUX86State *env, int addr);
 
 CPUX86State *cpu_x86_init(void);
 int cpu_x86_exec(CPUX86State *s);
-void cpu_x86_interrupt(CPUX86State *s);
 void cpu_x86_close(CPUX86State *s);
 int cpu_x86_get_pic_interrupt(CPUX86State *s);
 
diff --git a/exec.c b/exec.c
index 4de0c60f1a013d648853642e70895b1fe6a00438..e7f5081d0bc7aef38456228adde8e57ab8e6a83f 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -617,11 +617,12 @@ static void tb_reset_jump_recursive(TranslationBlock *tb)
     tb_reset_jump_recursive2(tb, 1);
 }
 
-void cpu_interrupt(CPUState *env)
+/* mask must never be zero */
+void cpu_interrupt(CPUState *env, int mask)
 {
     TranslationBlock *tb;
-
-    env->interrupt_request = 1;
+    
+    env->interrupt_request |= mask;
     /* if the cpu is currently executing code, we must unlink it and
        all the potentially executing TB */
     tb = env->current_tb;
index 8c757dd4a1fcad4461fc09ab79b1acac4dbd21ec..74aaeea681650d21627c52353da002ed9860f8de 100644 (file)
@@ -333,7 +333,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
     host_to_target_siginfo_noswap(&tinfo, info);
     if (queue_signal(sig, &tinfo) == 1) {
         /* interrupt the virtual CPU as soon as possible */
-        cpu_interrupt(global_env);
+        cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
     }
 }
 
index b477ac4adb90c26d35293fa996f5d8a4a5995269..8a7147c5563ed9e19f284f861d593c2455a033af 100644 (file)
@@ -3331,12 +3331,14 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
         if (!s->vm86) {
             if (s->cpl <= s->iopl) {
                 gen_op_sti();
+                s->is_jmp = 2; /* give a chance to handle pending irqs */
             } else {
                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             }
         } else {
             if (s->iopl == 3) {
                 gen_op_sti();
+                s->is_jmp = 2; /* give a chance to handle pending irqs */
             } else {
                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             }