Commit 474ea8494ae389fce546fdf3459e2a1c2ff22ac7

Authored by aurel32
1 parent 6a0d8a1d

x86: Introduce CPU_INTERRUPT_NMI

(Jan Kiszka)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4205 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
@@ -753,6 +753,7 @@ extern int code_copy_enabled; @@ -753,6 +753,7 @@ extern int code_copy_enabled;
753 #define CPU_INTERRUPT_SMI 0x40 /* (x86 only) SMI interrupt pending */ 753 #define CPU_INTERRUPT_SMI 0x40 /* (x86 only) SMI interrupt pending */
754 #define CPU_INTERRUPT_DEBUG 0x80 /* Debug event occured. */ 754 #define CPU_INTERRUPT_DEBUG 0x80 /* Debug event occured. */
755 #define CPU_INTERRUPT_VIRQ 0x100 /* virtual interrupt pending. */ 755 #define CPU_INTERRUPT_VIRQ 0x100 /* virtual interrupt pending. */
  756 +#define CPU_INTERRUPT_NMI 0x200 /* NMI pending. */
756 757
757 void cpu_interrupt(CPUState *s, int mask); 758 void cpu_interrupt(CPUState *s, int mask);
758 void cpu_reset_interrupt(CPUState *env, int mask); 759 void cpu_reset_interrupt(CPUState *env, int mask);
cpu-exec.c
@@ -444,6 +444,12 @@ int cpu_exec(CPUState *env1) @@ -444,6 +444,12 @@ int cpu_exec(CPUState *env1)
444 env->interrupt_request &= ~CPU_INTERRUPT_SMI; 444 env->interrupt_request &= ~CPU_INTERRUPT_SMI;
445 do_smm_enter(); 445 do_smm_enter();
446 BREAK_CHAIN; 446 BREAK_CHAIN;
  447 + } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
  448 + !(env->hflags & HF_NMI_MASK)) {
  449 + env->interrupt_request &= ~CPU_INTERRUPT_NMI;
  450 + env->hflags |= HF_NMI_MASK;
  451 + do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
  452 + BREAK_CHAIN;
447 } else if ((interrupt_request & CPU_INTERRUPT_HARD) && 453 } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
448 (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && 454 (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&
449 !(env->hflags & HF_INHIBIT_IRQ_MASK)) { 455 !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
target-i386/cpu.h
@@ -148,6 +148,7 @@ @@ -148,6 +148,7 @@
148 #define HF_SMM_SHIFT 19 /* CPU in SMM mode */ 148 #define HF_SMM_SHIFT 19 /* CPU in SMM mode */
149 #define HF_GIF_SHIFT 20 /* if set CPU takes interrupts */ 149 #define HF_GIF_SHIFT 20 /* if set CPU takes interrupts */
150 #define HF_HIF_SHIFT 21 /* shadow copy of IF_MASK when in SVM */ 150 #define HF_HIF_SHIFT 21 /* shadow copy of IF_MASK when in SVM */
  151 +#define HF_NMI_SHIFT 22 /* CPU serving NMI */
151 152
152 #define HF_CPL_MASK (3 << HF_CPL_SHIFT) 153 #define HF_CPL_MASK (3 << HF_CPL_SHIFT)
153 #define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT) 154 #define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT)
@@ -167,6 +168,7 @@ @@ -167,6 +168,7 @@
167 #define HF_SMM_MASK (1 << HF_SMM_SHIFT) 168 #define HF_SMM_MASK (1 << HF_SMM_SHIFT)
168 #define HF_GIF_MASK (1 << HF_GIF_SHIFT) 169 #define HF_GIF_MASK (1 << HF_GIF_SHIFT)
169 #define HF_HIF_MASK (1 << HF_HIF_SHIFT) 170 #define HF_HIF_MASK (1 << HF_HIF_SHIFT)
  171 +#define HF_NMI_MASK (1 << HF_NMI_SHIFT)
170 172
171 #define CR0_PE_MASK (1 << 0) 173 #define CR0_PE_MASK (1 << 0)
172 #define CR0_MP_MASK (1 << 1) 174 #define CR0_MP_MASK (1 << 1)
target-i386/exec.h
@@ -593,8 +593,9 @@ static inline int cpu_halted(CPUState *env) { @@ -593,8 +593,9 @@ static inline int cpu_halted(CPUState *env) {
593 if (!(env->hflags & HF_HALTED_MASK)) 593 if (!(env->hflags & HF_HALTED_MASK))
594 return 0; 594 return 0;
595 /* disable halt condition */ 595 /* disable halt condition */
596 - if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&  
597 - (env->eflags & IF_MASK)) { 596 + if (((env->interrupt_request & CPU_INTERRUPT_HARD) &&
  597 + (env->eflags & IF_MASK)) ||
  598 + (env->interrupt_request & CPU_INTERRUPT_NMI)) {
598 env->hflags &= ~HF_HALTED_MASK; 599 env->hflags &= ~HF_HALTED_MASK;
599 return 0; 600 return 0;
600 } 601 }
target-i386/helper.c
@@ -2383,6 +2383,7 @@ void helper_iret_real(int shift) @@ -2383,6 +2383,7 @@ void helper_iret_real(int shift)
2383 if (shift == 0) 2383 if (shift == 0)
2384 eflags_mask &= 0xffff; 2384 eflags_mask &= 0xffff;
2385 load_eflags(new_eflags, eflags_mask); 2385 load_eflags(new_eflags, eflags_mask);
  2386 + env->hflags &= ~HF_NMI_MASK;
2386 } 2387 }
2387 2388
2388 static inline void validate_seg(int seg_reg, int cpl) 2389 static inline void validate_seg(int seg_reg, int cpl)
@@ -2634,6 +2635,7 @@ void helper_iret_protected(int shift, int next_eip) @@ -2634,6 +2635,7 @@ void helper_iret_protected(int shift, int next_eip)
2634 } else { 2635 } else {
2635 helper_ret_protected(shift, 1, 0); 2636 helper_ret_protected(shift, 1, 0);
2636 } 2637 }
  2638 + env->hflags &= ~HF_NMI_MASK;
2637 #ifdef USE_KQEMU 2639 #ifdef USE_KQEMU
2638 if (kqemu_is_ok(env)) { 2640 if (kqemu_is_ok(env)) {
2639 CC_OP = CC_OP_EFLAGS; 2641 CC_OP = CC_OP_EFLAGS;