[ros-dev] RE: [ros-diffs] [CVS reactos] FPU/SSE state saving ontaskswitching, FPU and SSE exception support.

Gregor Anich blight at blight.eu.org
Tue Nov 23 21:55:32 CET 2004


Hello again!

Hartmut Birr wrote:

>I've revert some parts of fpu.c to your first patch. It works now on my smp
>machine. 
>
>  
>
I have attached a patch to this email, maybe you can try if it works 
with this patch. It is a patch against current reactos CVS.

I didn't see diff which you attached to your mail the first time, but it 
looks like it's an old version of the fpu.c which I have modified... 
maybe it doesn't bugcheck but I think it won't work (unless you have 
also reverted tskswitch.S...)

I have also attached a fputest program which tests wether the FPU state 
is preserved or not.

 - blight
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fputest.zip
Type: application/octet-stream
Size: 112893 bytes
Desc: not available
Url : http://reactos.com:8080/pipermail/ros-dev/attachments/20041123/935b91e6/fputest-0001.obj
-------------- next part --------------
Index: ntoskrnl/ke/i386/fpu.c
===================================================================
RCS file: /CVS/ReactOS/reactos/ntoskrnl/ke/i386/fpu.c,v
retrieving revision 1.16
diff -u -r1.16 fpu.c
--- ntoskrnl/ke/i386/fpu.c	21 Nov 2004 13:33:34 -0000	1.16
+++ ntoskrnl/ke/i386/fpu.c	23 Nov 2004 20:36:58 -0000
@@ -28,6 +28,7 @@
 
 /* INCLUDES *****************************************************************/
 
+#include <roscfg.h>
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
@@ -67,7 +68,8 @@
 /* GLOBALS *******************************************************************/
 
 ULONG HardwareMathSupport = 0;
-static ULONG MxcsrFeatureMask = 0, FxsrSupport = 0, XmmSupport = 0;
+static ULONG MxcsrFeatureMask = 0, XmmSupport = 0;
+ULONG FxsrSupport = 0; /* used by Ki386ContextSwitch for MP */
 
 /* FUNCTIONS *****************************************************************/
 
@@ -406,10 +408,14 @@
 {
   if (ExceptionNr == 7) /* device not present */
     {
+      BOOL FpuInitialized = FALSE;
       unsigned int cr0 = Ke386GetCr0();
-      PKTHREAD CurrentThread, NpxThread;
+      PKTHREAD CurrentThread;
       PFX_SAVE_AREA FxSaveArea;
       KIRQL oldIrql;
+#ifndef MP
+      PKTHREAD NpxThread;
+#endif
       
       (void) cr0;
       ASSERT((cr0 & X86_CR0_TS) == X86_CR0_TS);
@@ -422,15 +428,17 @@
       asm volatile("clts");
 
       CurrentThread = KeGetCurrentThread();
+#ifndef MP
       NpxThread = KeGetCurrentKPCR()->PrcbData.NpxThread;
+#endif
 
       ASSERT(CurrentThread != NULL);
-      DPRINT("Device not present exception happened! (Cr0 = 0x%x, NpxState = 0x%x)\n", Ke386GetCr0(), CurrentThread->NpxState);
+      DPRINT("Device not present exception happened! (Cr0 = 0x%x, NpxState = 0x%x)\n", cr0, CurrentThread->NpxState);
 
+#ifndef MP
       /* check if the current thread already owns the FPU */
       if (NpxThread != CurrentThread) /* FIXME: maybe this could be an assertation */
         {
-          BOOL FpuInitialized = FALSE;
           /* save the FPU state into the owner's save area */
           if (NpxThread != NULL)
             {
@@ -448,6 +456,7 @@
                 }
               NpxThread->NpxState = NPX_STATE_VALID;
             }
+#endif /* !MP */
 
           /* restore the state of the current thread */
           ASSERT((CurrentThread->NpxState & NPX_STATE_DIRTY) == 0);
@@ -483,7 +492,9 @@
                 }
             }
           KeGetCurrentKPCR()->PrcbData.NpxThread = CurrentThread;
+#ifndef MP
         }
+#endif
 
       CurrentThread->NpxState |= NPX_STATE_DIRTY;
       KeLowerIrql(oldIrql);
@@ -508,8 +519,8 @@
       CurrentThread = KeGetCurrentThread();
       if (NpxThread == NULL)
         {
-          DPRINT1("!!! Math/Xmm fault ignored! (NpxThread == NULL)\n");
           KeLowerIrql(oldIrql);
+          DPRINT1("!!! Math/Xmm fault ignored! (NpxThread == NULL)\n");
           return STATUS_SUCCESS;
         }
 
@@ -540,7 +551,6 @@
           PFNSAVE_FORMAT FnSave = (PFNSAVE_FORMAT)&Context->FloatSave;
           asm volatile("fnsave %0" : : "m"(*FnSave));
           KeLowerIrql(oldIrql);
-          memset(Context->FloatSave.RegisterArea, 0, sizeof(Context->FloatSave.RegisterArea));
           KiFnsaveToFxsaveFormat((PFXSAVE_FORMAT)Context->ExtendedRegisters, FnSave);
         }
 
Index: ntoskrnl/ke/i386/tskswitch.S
===================================================================
RCS file: /CVS/ReactOS/reactos/ntoskrnl/ke/i386/tskswitch.S,v
retrieving revision 1.20
diff -u -r1.20 tskswitch.S
--- ntoskrnl/ke/i386/tskswitch.S	20 Nov 2004 23:46:36 -0000	1.20
+++ ntoskrnl/ke/i386/tskswitch.S	23 Nov 2004 20:13:31 -0000
@@ -26,6 +26,7 @@
 
 /* INCLUDES ******************************************************************/
 
+#include <roscfg.h>
 #include <internal/i386/segment.h>
 #include <internal/i386/ke.h>
 #include <internal/i386/fpu.h>
@@ -105,8 +106,30 @@
 0:
 	lldtw	%ax
 
+	/*
+	 * Get the pointer to the old thread.
+	 */
 	movl	12(%ebp), %ebx
 
+#ifdef MP
+	/*
+	 * Save FPU state if the thread has used it.
+	 */
+	movl	$0, %fs:KPCR_NPX_THREAD
+	testl	$NPX_STATE_DIRTY, KTHREAD_NPX_STATE(%ebx)
+	jz	3f
+	movl	KTHREAD_INITIAL_STACK(%ebx), %eax
+	cmpl	$0, _FxsrSupport
+	je	1f
+	fxsave	-SIZEOF_FX_SAVE_AREA(%eax)
+	jmp	2f
+1:
+	fnsave	-SIZEOF_FX_SAVE_AREA(%eax)
+2:
+	movl	$NPX_STATE_VALID, KTHREAD_NPX_STATE(%ebx)
+3:
+#endif /* MP */
+
 	/*
 	 * FIXME: Save debugging state.
 	 */
@@ -152,14 +175,16 @@
 
 	/*
 	 * Set TS in cr0 to catch FPU code and load the FPU state when needed
-	 * We do this only if NewThread != KPCR->NpxThread
+	 * For uni-processor we do this only if NewThread != KPCR->NpxThread
 	 */
+#ifndef MP
 	cmpl	%ebx, %fs:KPCR_NPX_THREAD
-	je	1f
+	je	4f
+#endif /* !MP */
 	movl	%cr0, %eax
 	orl	$X86_CR0_TS, %eax
 	movl	%eax, %cr0
-1:
+4:
 
 	/*
 	 * FIXME: Restore debugging state
@@ -174,9 +199,9 @@
 	call	_KeReleaseSpinLockFromDpcLevel at 4
 
 	cmpl	$0, _PiNrThreadsAwaitingReaping
-	je	4f
+	je	5f
 	call	_PiWakeupReaperThread at 0
-4:
+5:
 
 	/*
 	 * Restore the saved register and exit


More information about the Ros-dev mailing list