Commit in reactos/ntoskrnl/ke/i386 on MAIN
fpu.c+17-71.16 -> 1.17
tskswitch.S+30-51.20 -> 1.21
+47-12
2 modified files
Multiprocessor support for FPU/SSE state saving.

reactos/ntoskrnl/ke/i386
fpu.c 1.16 -> 1.17
diff -u -r1.16 -r1.17
--- fpu.c	21 Nov 2004 13:33:34 -0000	1.16
+++ fpu.c	25 Nov 2004 13:22:54 -0000	1.17
@@ -1,4 +1,4 @@
-/* $Id: fpu.c,v 1.16 2004/11/21 13:33:34 blight Exp $
+/* $Id: fpu.c,v 1.17 2004/11/25 13:22:54 blight Exp $
  *
  *  ReactOS kernel
  *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
@@ -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);
         }
 

reactos/ntoskrnl/ke/i386
tskswitch.S 1.20 -> 1.21
diff -u -r1.20 -r1.21
--- tskswitch.S	20 Nov 2004 23:46:36 -0000	1.20
+++ tskswitch.S	25 Nov 2004 13:22:54 -0000	1.21
@@ -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
+	testb	$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:
+	movb	$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@4
 
 	cmpl	$0, _PiNrThreadsAwaitingReaping
-	je	4f
+	je	5f
 	call	_PiWakeupReaperThread@0
-4:
+5:
 
 	/*
 	 * Restore the saved register and exit
CVSspam 0.2.8