qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 1/3] x86: Introduce CPU_INTERRUPT_NMI
@ 2008-04-12 16:12 Jan Kiszka
  2008-04-12 16:48 ` [Qemu-devel] " Jan Kiszka
  2008-04-14 10:16 ` Andi Kleen
  0 siblings, 2 replies; 6+ messages in thread
From: Jan Kiszka @ 2008-04-12 16:12 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 4193 bytes --]

[ This patch obsoletes
  http://permalink.gmane.org/gmane.comp.emulators.qemu/22989. ]

The x86 emulation yet lacks proper NMI support. This patch introduces
CPU_INTERRUPT_NMI and the required handling logic so that hardware
emulation drivers can simply call

	cpu_interrupt(env, CPU_INTERRUPT_NMI);

to raise an NMI on this arch.

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>

---
 cpu-all.h            |    1 +
 cpu-exec.c           |    6 ++++++
 target-i386/cpu.h    |    2 ++
 target-i386/exec.h   |    5 +++--
 target-i386/helper.c |    2 ++
 5 files changed, 14 insertions(+), 2 deletions(-)

Index: b/cpu-all.h
===================================================================
--- 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: b/cpu-exec.c
===================================================================
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -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: b/target-i386/cpu.h
===================================================================
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -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)
Index: b/target-i386/helper.c
===================================================================
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -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, in
     } 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;
Index: b/target-i386/exec.h
===================================================================
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -593,8 +593,9 @@ static inline int cpu_halted(CPUState *e
     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;
     }


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 254 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-04-14 16:38 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-12 16:12 [Qemu-devel] [PATCH 1/3] x86: Introduce CPU_INTERRUPT_NMI Jan Kiszka
2008-04-12 16:48 ` [Qemu-devel] " Jan Kiszka
2008-04-14 10:16 ` Andi Kleen
2008-04-14 16:13   ` Jan Kiszka
2008-04-14 16:17     ` Andi Kleen
2008-04-14 16:38       ` Jan Kiszka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).