x86: Introduce CPU_INTERRUPT_NMI
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 13 Apr 2008 16:08:15 +0000 (16:08 +0000)
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 13 Apr 2008 16:08:15 +0000 (16:08 +0000)
(Jan Kiszka)

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4205 c046a42c-6fe2-441c-8c8c-71466251a162

cpu-all.h
cpu-exec.c
target-i386/cpu.h
target-i386/exec.h
target-i386/helper.c

index 21ed731a598b412b1f5c286bd4462903fe50281c..a4dee2196dd7731d8bec0f6bdec9fe20d0e52f92 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -753,6 +753,7 @@ extern int code_copy_enabled;
 #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);
index a17ea2f739fde40172e4759216e462a60d0c32d5..25dcf2b12517e76f63955a4e6ef9a927a389a8f1 100644 (file)
@@ -444,6 +444,12 @@ int cpu_exec(CPUState *env1)
                         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)) {
index 1c49b3691b7a9cebfb8549418aaf539c79384f75..152b673ee9355575c2070359c96765390611cc36 100644 (file)
 #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)
 #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)
index 37fcdc01b7f8e76bf08948de972d7ee9aa9986a1..11d12c9b0088bf56b6bcb1561814a708fb33ba1c 100644 (file)
@@ -593,8 +593,9 @@ static inline int cpu_halted(CPUState *env) {
     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;
     }
index 69c2051f7c0dfdc24c6709d951525fa25d0f1d45..b2c829926ccf3295ddb5dbb67b3d161ef0f0f97a 100644 (file)
@@ -2383,6 +2383,7 @@ void helper_iret_real(int shift)
     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 @@ void helper_iret_protected(int shift, int next_eip)
     } 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;