Commit 474ea8494ae389fce546fdf3459e2a1c2ff22ac7
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
Showing
5 changed files
with
14 additions
and
2 deletions
cpu-all.h
... | ... | @@ -753,6 +753,7 @@ extern int code_copy_enabled; |
753 | 753 | #define CPU_INTERRUPT_SMI 0x40 /* (x86 only) SMI interrupt pending */ |
754 | 754 | #define CPU_INTERRUPT_DEBUG 0x80 /* Debug event occured. */ |
755 | 755 | #define CPU_INTERRUPT_VIRQ 0x100 /* virtual interrupt pending. */ |
756 | +#define CPU_INTERRUPT_NMI 0x200 /* NMI pending. */ | |
756 | 757 | |
757 | 758 | void cpu_interrupt(CPUState *s, int mask); |
758 | 759 | void cpu_reset_interrupt(CPUState *env, int mask); | ... | ... |
cpu-exec.c
... | ... | @@ -444,6 +444,12 @@ int cpu_exec(CPUState *env1) |
444 | 444 | env->interrupt_request &= ~CPU_INTERRUPT_SMI; |
445 | 445 | do_smm_enter(); |
446 | 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 | 453 | } else if ((interrupt_request & CPU_INTERRUPT_HARD) && |
448 | 454 | (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && |
449 | 455 | !(env->hflags & HF_INHIBIT_IRQ_MASK)) { | ... | ... |
target-i386/cpu.h
... | ... | @@ -148,6 +148,7 @@ |
148 | 148 | #define HF_SMM_SHIFT 19 /* CPU in SMM mode */ |
149 | 149 | #define HF_GIF_SHIFT 20 /* if set CPU takes interrupts */ |
150 | 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 | 153 | #define HF_CPL_MASK (3 << HF_CPL_SHIFT) |
153 | 154 | #define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT) |
... | ... | @@ -167,6 +168,7 @@ |
167 | 168 | #define HF_SMM_MASK (1 << HF_SMM_SHIFT) |
168 | 169 | #define HF_GIF_MASK (1 << HF_GIF_SHIFT) |
169 | 170 | #define HF_HIF_MASK (1 << HF_HIF_SHIFT) |
171 | +#define HF_NMI_MASK (1 << HF_NMI_SHIFT) | |
170 | 172 | |
171 | 173 | #define CR0_PE_MASK (1 << 0) |
172 | 174 | #define CR0_MP_MASK (1 << 1) | ... | ... |
target-i386/exec.h
... | ... | @@ -593,8 +593,9 @@ static inline int cpu_halted(CPUState *env) { |
593 | 593 | if (!(env->hflags & HF_HALTED_MASK)) |
594 | 594 | return 0; |
595 | 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 | 599 | env->hflags &= ~HF_HALTED_MASK; |
599 | 600 | return 0; |
600 | 601 | } | ... | ... |
target-i386/helper.c
... | ... | @@ -2383,6 +2383,7 @@ void helper_iret_real(int shift) |
2383 | 2383 | if (shift == 0) |
2384 | 2384 | eflags_mask &= 0xffff; |
2385 | 2385 | load_eflags(new_eflags, eflags_mask); |
2386 | + env->hflags &= ~HF_NMI_MASK; | |
2386 | 2387 | } |
2387 | 2388 | |
2388 | 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 | 2635 | } else { |
2635 | 2636 | helper_ret_protected(shift, 1, 0); |
2636 | 2637 | } |
2638 | + env->hflags &= ~HF_NMI_MASK; | |
2637 | 2639 | #ifdef USE_KQEMU |
2638 | 2640 | if (kqemu_is_ok(env)) { |
2639 | 2641 | CC_OP = CC_OP_EFLAGS; | ... | ... |