qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [4205] x86: Introduce CPU_INTERRUPT_NMI


From: Aurelien Jarno
Subject: [Qemu-devel] [4205] x86: Introduce CPU_INTERRUPT_NMI
Date: Sun, 13 Apr 2008 16:08:16 +0000

Revision: 4205
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4205
Author:   aurel32
Date:     2008-04-13 16:08:15 +0000 (Sun, 13 Apr 2008)

Log Message:
-----------
x86: Introduce CPU_INTERRUPT_NMI

(Jan Kiszka)

Modified Paths:
--------------
    trunk/cpu-all.h
    trunk/cpu-exec.c
    trunk/target-i386/cpu.h
    trunk/target-i386/exec.h
    trunk/target-i386/helper.c

Modified: trunk/cpu-all.h
===================================================================
--- trunk/cpu-all.h     2008-04-13 13:25:31 UTC (rev 4204)
+++ trunk/cpu-all.h     2008-04-13 16:08:15 UTC (rev 4205)
@@ -753,6 +753,7 @@
 #define CPU_INTERRUPT_SMI    0x40 /* (x86 only) SMI interrupt pending */
 #define CPU_INTERRUPT_DEBUG  0x80 /* Debug event occured.  */
 #define CPU_INTERRUPT_VIRQ   0x100 /* virtual interrupt pending.  */
+#define CPU_INTERRUPT_NMI    0x200 /* NMI pending. */
 
 void cpu_interrupt(CPUState *s, int mask);
 void cpu_reset_interrupt(CPUState *env, int mask);

Modified: trunk/cpu-exec.c
===================================================================
--- trunk/cpu-exec.c    2008-04-13 13:25:31 UTC (rev 4204)
+++ trunk/cpu-exec.c    2008-04-13 16:08:15 UTC (rev 4205)
@@ -444,6 +444,12 @@
                         env->interrupt_request &= ~CPU_INTERRUPT_SMI;
                         do_smm_enter();
                         BREAK_CHAIN;
+                    } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
+                        !(env->hflags & HF_NMI_MASK)) {
+                        env->interrupt_request &= ~CPU_INTERRUPT_NMI;
+                        env->hflags |= HF_NMI_MASK;
+                        do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
+                        BREAK_CHAIN;
                     } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                         (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&
                         !(env->hflags & HF_INHIBIT_IRQ_MASK)) {

Modified: trunk/target-i386/cpu.h
===================================================================
--- trunk/target-i386/cpu.h     2008-04-13 13:25:31 UTC (rev 4204)
+++ trunk/target-i386/cpu.h     2008-04-13 16:08:15 UTC (rev 4205)
@@ -148,6 +148,7 @@
 #define HF_SMM_SHIFT        19 /* CPU in SMM mode */
 #define HF_GIF_SHIFT        20 /* if set CPU takes interrupts */
 #define HF_HIF_SHIFT        21 /* shadow copy of IF_MASK when in SVM */
+#define HF_NMI_SHIFT        22 /* CPU serving NMI */
 
 #define HF_CPL_MASK          (3 << HF_CPL_SHIFT)
 #define HF_SOFTMMU_MASK      (1 << HF_SOFTMMU_SHIFT)
@@ -167,6 +168,7 @@
 #define HF_SMM_MASK          (1 << HF_SMM_SHIFT)
 #define HF_GIF_MASK          (1 << HF_GIF_SHIFT)
 #define HF_HIF_MASK          (1 << HF_HIF_SHIFT)
+#define HF_NMI_MASK          (1 << HF_NMI_SHIFT)
 
 #define CR0_PE_MASK  (1 << 0)
 #define CR0_MP_MASK  (1 << 1)

Modified: trunk/target-i386/exec.h
===================================================================
--- trunk/target-i386/exec.h    2008-04-13 13:25:31 UTC (rev 4204)
+++ trunk/target-i386/exec.h    2008-04-13 16:08:15 UTC (rev 4205)
@@ -593,8 +593,9 @@
     if (!(env->hflags & HF_HALTED_MASK))
         return 0;
     /* disable halt condition */
-    if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
-        (env->eflags & IF_MASK)) {
+    if (((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+         (env->eflags & IF_MASK)) ||
+        (env->interrupt_request & CPU_INTERRUPT_NMI)) {
         env->hflags &= ~HF_HALTED_MASK;
         return 0;
     }

Modified: trunk/target-i386/helper.c
===================================================================
--- trunk/target-i386/helper.c  2008-04-13 13:25:31 UTC (rev 4204)
+++ trunk/target-i386/helper.c  2008-04-13 16:08:15 UTC (rev 4205)
@@ -2383,6 +2383,7 @@
     if (shift == 0)
         eflags_mask &= 0xffff;
     load_eflags(new_eflags, eflags_mask);
+    env->hflags &= ~HF_NMI_MASK;
 }
 
 static inline void validate_seg(int seg_reg, int cpl)
@@ -2634,6 +2635,7 @@
     } else {
         helper_ret_protected(shift, 1, 0);
     }
+    env->hflags &= ~HF_NMI_MASK;
 #ifdef USE_KQEMU
     if (kqemu_is_ok(env)) {
         CC_OP = CC_OP_EFLAGS;






reply via email to

[Prev in Thread] Current Thread [Next in Thread]