[ros-diffs] [ion] 20887: - Update KeContextToTrapFrame to support separate ContextFlags parameters in the scenario where we want to convert more then the Context's flag specify

ion at svn.reactos.org ion at svn.reactos.org
Sun Jan 15 10:24:17 CET 2006


- Update KeContextToTrapFrame to support separate ContextFlags
parameters in the scenario where we want to convert more then the
Context's flag specify
- Rename some of the internal FPU flags to external names and make them
global.
- Improve context creation of new threads to initialize the virgin NPX
state for new threads, to clear DR debug registers, to properly convert
the context to a trap frame, to set the right segment registers, to set
the debugging mark in the trap frame, and to properly set the initial
eflags.
- Add stubs for upcoming support for extended/floating point registers
in KeContextToTrapFrame and KeTrapFrameToContext.
Modified: trunk/reactos/include/ndk/asm.h
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
Modified: trunk/reactos/ntoskrnl/kd/wrappers/gdbstub.c
Modified: trunk/reactos/ntoskrnl/ke/exception.c
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
Modified: trunk/reactos/ntoskrnl/ke/i386/fpu.c
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
Modified: trunk/reactos/ntoskrnl/ke/i386/thread.c
Modified: trunk/reactos/ntoskrnl/ps/debug.c
  _____  

Modified: trunk/reactos/include/ndk/asm.h
--- trunk/reactos/include/ndk/asm.h	2006-01-15 09:14:04 UTC (rev
20886)
+++ trunk/reactos/include/ndk/asm.h	2006-01-15 09:23:55 UTC (rev
20887)
@@ -110,6 +110,7 @@

 #define KPCR_TEB                                0x18
 #define KPCR_SELF                               0x1C
 #define KPCR_PRCB                               0x20
+#define KPCR_IRQL                               0x24
 #define KPCR_KD_VERSION_BLOCK                   0x34
 #define KPCR_GDT                                0x3C
 #define KPCR_TSS                                0x40
@@ -121,6 +122,7 @@
 #define KPCR_NPX_THREAD                         0x2F4
 #define KPCR_DR6                                0x428
 #define KPCR_DR7                                0x42C
+#define KPCR_SYSTEM_CALLS                       0x6B8
 
 //
 // KGDTENTRY Offsets
@@ -143,6 +145,12 @@
 #define NPX_FRAME_LENGTH                        0x210
 
 //
+// NPX States
+//
+#define NPX_STATE_NOT_LOADED                    0xA
+#define NPX_STATE_LOADED                        0x0
+
+//
 // Trap Frame Offsets
 //
 #define KTRAP_FRAME_DEBUGEBP                    0x0
  _____  

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
--- trunk/reactos/ntoskrnl/include/internal/ke.h	2006-01-15
09:14:04 UTC (rev 20886)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h	2006-01-15
09:23:55 UTC (rev 20887)
@@ -41,6 +41,9 @@

 extern PVOID KeRaiseUserExceptionDispatcher;
 extern LARGE_INTEGER SystemBootTime;
 extern ULONG_PTR KERNEL_BASE;
+extern ULONG KeI386NpxPresent;
+extern ULONG KeI386XMMIPresent;
+extern ULONG KeI386FxsrPresent;
 
 /* MACROS
************************************************************************
*/
 
@@ -475,12 +478,13 @@
 NTAPI
 KeGetStackTopThread(struct _ETHREAD* Thread);
 
-BOOLEAN
+VOID
 STDCALL
 KeContextToTrapFrame(
     PCONTEXT Context,
     PKEXCEPTION_FRAME ExeptionFrame,
     PKTRAP_FRAME TrapFrame,
+    ULONG ContextFlags,
     KPROCESSOR_MODE PreviousMode
 );
 
  _____  

Modified: trunk/reactos/ntoskrnl/kd/wrappers/gdbstub.c
--- trunk/reactos/ntoskrnl/kd/wrappers/gdbstub.c	2006-01-15
09:14:04 UTC (rev 20886)
+++ trunk/reactos/ntoskrnl/kd/wrappers/gdbstub.c	2006-01-15
09:23:55 UTC (rev 20887)
@@ -1720,7 +1720,7 @@

 
   KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
 
-  KeContextToTrapFrame(&Context, NULL, TrapFrame, KernelMode);
+  KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags,
KernelMode);
 
   KeLowerIrql(OldIrql);
 
  _____  

Modified: trunk/reactos/ntoskrnl/ke/exception.c
--- trunk/reactos/ntoskrnl/ke/exception.c	2006-01-15 09:14:04 UTC
(rev 20886)
+++ trunk/reactos/ntoskrnl/ke/exception.c	2006-01-15 09:23:55 UTC
(rev 20887)
@@ -28,7 +28,11 @@

     Context = &LocalContext;
 
     /* Convert the context into Exception/Trap Frames */
-    KeContextToTrapFrame(&LocalContext, ExceptionFrame, TrapFrame,
UserMode);
+    KeContextToTrapFrame(&LocalContext,
+                         ExceptionFrame,
+                         TrapFrame,
+                         LocalContext.ContextFlags,
+                         UserMode);
 }
 
 NTSTATUS
@@ -62,7 +66,11 @@
         else
         {
             /* Convert the context into Exception/Trap Frames */
-            KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame,
KernelMode);
+            KeContextToTrapFrame(Context,
+                                 ExceptionFrame,
+                                 TrapFrame,
+                                 Context->ContextFlags,
+                                 KernelMode);
         }
     }
     _SEH_HANDLE
@@ -142,7 +150,11 @@
     if (NT_SUCCESS(Status))
     {
         /* Convert the context record */
-        KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame,
PreviousMode);
+        KeContextToTrapFrame(Context,
+                             ExceptionFrame,
+                             TrapFrame,
+                             Context->ContextFlags,
+                             PreviousMode);
 
         /* Dispatch the exception */
         KiDispatchException(ExceptionRecord,
  _____  

Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
--- trunk/reactos/ntoskrnl/ke/i386/exp.c	2006-01-15 09:14:04 UTC
(rev 20886)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c	2006-01-15 09:23:55 UTC
(rev 20887)
@@ -1,10 +1,11 @@

 /*
  * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
+ * PROJECT:         ReactOS Kernel
  * FILE:            ntoskrnl/ke/i386/exp.c
- * PURPOSE:         Handling exceptions
- *
- * PROGRAMMERS:     David Welch (welch at cwcom.net)
+ * PURPOSE:         Exception Support Code
+ * PROGRAMMERS:     Alex Ionescu (alex at relsoft.net)
+ *                  Gregor Anich
+ *                  David Welch (welch at cwcom.net)
  *                  Skywing (skywing at valhallalegends.com)
  */
 
@@ -22,7 +23,6 @@
 
 /*
  * FIXMES:
- *  - Put back VEH.
  *  - Clean up file.
  *  - Sanitize some context fields.
  *  - Add PSEH handler when an exception occurs in an exception
(KiCopyExceptionRecord).
@@ -689,17 +689,20 @@
     }
 }
 
-BOOLEAN
+VOID
 NTAPI
 KeContextToTrapFrame(IN PCONTEXT Context,
                      IN OUT PKEXCEPTION_FRAME ExceptionFrame,
                      IN OUT PKTRAP_FRAME TrapFrame,
+                     IN ULONG ContextFlags,
                      IN KPROCESSOR_MODE PreviousMode)
 {
+    PFX_SAVE_AREA FxSaveArea;
+    //ULONG i; Future Use
     BOOLEAN V86Switch = FALSE;
 
     /* Start with the basic Registers */
-    if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+    if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
     {
         /* Check if we went through a V86 switch */
         if ((Context->EFlags & X86_EFLAGS_VM) !=
@@ -746,7 +749,7 @@
     }
 
     /* Process the Integer Registers */
-    if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+    if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
     {
         TrapFrame->Eax = Context->Eax;
         TrapFrame->Ebx = Context->Ebx;
@@ -757,7 +760,7 @@
     }
 
     /* Process the Context Segments */
-    if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
+    if ((ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
     {
         /* Check if we were in V86 Mode */
         if (TrapFrame->EFlags & X86_EFLAGS_VM)
@@ -770,7 +773,7 @@
         }
         else if (!(TrapFrame->SegCs & MODE_MASK))
         {
-            /* For user mode, write the values directly */
+            /* For kernel mode, write the standard values */
             TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
             TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
             TrapFrame->SegFs = Context->SegFs;
@@ -778,7 +781,7 @@
         }
         else
         {
-            /* For kernel-mode, return the values */
+            /* For user mode, return the values directlry */
             TrapFrame->SegDs = Context->SegDs;
             TrapFrame->SegEs = Context->SegEs;
             TrapFrame->SegFs = Context->SegFs;
@@ -797,8 +800,42 @@
         }
     }
 
+    /* Handle the extended registers */
+    if (((ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
+        CONTEXT_EXTENDED_REGISTERS) &&
+        ((TrapFrame->SegCs & MODE_MASK) == UserMode))
+    {
+        /* Get the FX Area */
+        FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
+
+        /* Check if NPX is present */
+        if (KeI386NpxPresent)
+        {
+            /* Future use */
+        }
+    }
+
+    /* Handle the floating point state */
+    if (((ContextFlags & CONTEXT_FLOATING_POINT) ==
+        CONTEXT_FLOATING_POINT) &&
+        ((TrapFrame->SegCs & MODE_MASK) == UserMode))
+    {
+        /* Get the FX Area */
+        FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
+
+        /* Check if NPX is present */
+        if (KeI386NpxPresent)
+        {
+            /* Future use */
+        }
+        else
+        {
+            /* Future use */
+        }
+    }
+
     /* Handle the Debug Registers */
-    if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
CONTEXT_DEBUG_REGISTERS)
+    if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
CONTEXT_DEBUG_REGISTERS)
     {
         /* FIXME: All these should be sanitized */
         TrapFrame->Dr0 = Context->Dr0;
@@ -812,12 +849,13 @@
         if (PreviousMode != KernelMode)
         {
             /* Set the Debug Flag */
-            KeGetCurrentThread()->DispatcherHeader.DebugActive =
(Context->Dr7 & DR7_ACTIVE);
+            KeGetCurrentThread()->DispatcherHeader.DebugActive =
+                (Context->Dr7 & DR7_ACTIVE);
         }
     }
 
     /* Handle FPU and Extended Registers */
-    return KiContextToFxSaveArea((PFX_SAVE_AREA)(TrapFrame + 1),
Context);
+    KiContextToFxSaveArea((PFX_SAVE_AREA)(TrapFrame + 1), Context);
 }
 
 VOID
@@ -898,15 +936,52 @@
         Context->Edi = TrapFrame->Edi;
     }
 
-    if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
CONTEXT_DEBUG_REGISTERS)
+    /* Handle extended registers */
+    if (((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
+        CONTEXT_EXTENDED_REGISTERS) &&
+        ((TrapFrame->SegCs & MODE_MASK) == UserMode))
     {
-        /*
-         * FIXME: Implement this case
-         */
-        Context->ContextFlags &= (~CONTEXT_DEBUG_REGISTERS) |
CONTEXT_i386;
+        /* Get the FX Save Area */
+        FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
+
+        /* Make sure NPX is present */
+        if (KeI386NpxPresent)
+        {
+            /* Future use */
+        }
+
+        /* Old code */
+        FxSaveArea = KiGetFpuState(KeGetCurrentThread());
+        if (FxSaveArea != NULL)
+        {
+            memcpy(Context->ExtendedRegisters, &FxSaveArea->U.FxArea,
+                   min(sizeof (Context->ExtendedRegisters), sizeof
(FxSaveArea->U.FxArea)) );
+        }
+        else
+        {
+            Context->ContextFlags &= (~CONTEXT_EXTENDED_REGISTERS) |
CONTEXT_i386;
+        }
     }
-    if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
CONTEXT_FLOATING_POINT)
+
+    /* Handle Floating Point */
+    if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
+        CONTEXT_FLOATING_POINT) &&
+        ((TrapFrame->SegCs & MODE_MASK) == UserMode))
     {
+        /* Get the FX Save Area */
+        FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
+
+        /* Make sure we have an NPX */
+        if (KeI386NpxPresent)
+        {
+            /* Future use */
+        }
+        else
+        {
+            /* Future Use */
+        }
+
+        /* Old code */
         FxSaveArea = KiGetFpuState(KeGetCurrentThread());
         if (FxSaveArea != NULL)
         {
@@ -917,18 +992,30 @@
             Context->ContextFlags &= (~CONTEXT_FLOATING_POINT) |
CONTEXT_i386;
         }
     }
-    if ((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
CONTEXT_EXTENDED_REGISTERS)
+
+    /* Handle debug registers */
+    if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
+        CONTEXT_DEBUG_REGISTERS)
     {
-        if (FxSaveArea == NULL)
-            FxSaveArea = KiGetFpuState(KeGetCurrentThread());
-        if (FxSaveArea != NULL)
+        /* Copy the debug registers */
+        Context->Dr0 = TrapFrame->Dr0;
+        Context->Dr1 = TrapFrame->Dr1;
+        Context->Dr2 = TrapFrame->Dr2;
+        Context->Dr3 = TrapFrame->Dr3;
+        Context->Dr6 = TrapFrame->Dr6;
+
+        /* For user-mode, only set DR7 if a debugger is active */
+        if (((TrapFrame->SegCs & MODE_MASK) ||
+            (TrapFrame->EFlags & EFLAGS_V86_MASK)) &&
+            (KeGetCurrentThread()->DispatcherHeader.DebugActive))
         {
-            memcpy(Context->ExtendedRegisters, &FxSaveArea->U.FxArea,
-                   min(sizeof (Context->ExtendedRegisters), sizeof
(FxSaveArea->U.FxArea)) );
+            /* Copy it over */
+            Context->Dr7 = TrapFrame->Dr7;
         }
         else
         {
-            Context->ContextFlags &= (~CONTEXT_EXTENDED_REGISTERS) |
CONTEXT_i386;
+            /* Clear it */
+            Context->Dr7 = 0;
         }
     }
 }
@@ -1187,11 +1274,9 @@
     /* Check if User Mode */
     if (PreviousMode == UserMode)
     {
-        extern ULONG FxsrSupport;
         /* Add the FPU Flag */
         Context.ContextFlags |= CONTEXT_FLOATING_POINT;
-        if (FxsrSupport)
-            Context.ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
+        if (KeI386FxsrPresent) Context.ContextFlags |=
CONTEXT_EXTENDED_REGISTERS;
     }
 
     /* Get a Context */
@@ -1321,27 +1406,42 @@
 
 Handled:
     /* Convert the context back into Trap/Exception Frames */
-    KeContextToTrapFrame(&Context, NULL, TrapFrame, PreviousMode);
+    KeContextToTrapFrame(&Context,
+                         NULL,
+                         TrapFrame,
+                         Context.ContextFlags,
+                         PreviousMode);
     return;
 }
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
 KeRaiseUserException(IN NTSTATUS ExceptionCode)
 {
    ULONG OldEip;
    PKTHREAD Thread = KeGetCurrentThread();
 
-    _SEH_TRY {
+   /* Make sure we can access the TEB */
+    _SEH_TRY
+    {
         Thread->Teb->ExceptionCode = ExceptionCode;
-    } _SEH_HANDLE {
+    }
+    _SEH_HANDLE
+    {
         return(ExceptionCode);
-    } _SEH_END;
+    }
+    _SEH_END;
 
-   OldEip = Thread->TrapFrame->Eip;
-   Thread->TrapFrame->Eip = (ULONG_PTR)KeRaiseUserExceptionDispatcher;
-   return((NTSTATUS)OldEip);
+    /* Get the old EIP */
+    OldEip = Thread->TrapFrame->Eip;
+
+    /* Change it to the user-mode dispatcher */
+    Thread->TrapFrame->Eip = (ULONG_PTR)KeRaiseUserExceptionDispatcher;
+
+    /* Return the old EIP */
+    return((NTSTATUS)OldEip);
 }
 
  _____  

Modified: trunk/reactos/ntoskrnl/ke/i386/fpu.c
--- trunk/reactos/ntoskrnl/ke/i386/fpu.c	2006-01-15 09:14:04 UTC
(rev 20886)
+++ trunk/reactos/ntoskrnl/ke/i386/fpu.c	2006-01-15 09:23:55 UTC
(rev 20887)
@@ -1,11 +1,10 @@

-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/i386/fpu.c
  * PURPOSE:         Handles the FPU
- *
  * PROGRAMMERS:     David Welch (welch at mcmail.com)
+ *                  Gregor Anich
  */
 
 /* INCLUDES
*****************************************************************/
@@ -39,10 +38,12 @@
 
 /* GLOBALS
*******************************************************************/
 
-ULONG HardwareMathSupport = 0;
-static ULONG MxcsrFeatureMask = 0, XmmSupport = 0;
-ULONG FxsrSupport = 0; /* used by Ki386ContextSwitch for SMP */
+extern ULONG KeI386NpxPresent;
+extern ULONG KeI386XMMIPresent;
+extern ULONG KeI386FxsrPresent;
 
+static ULONG MxcsrFeatureMask = 0;
+
 /* FUNCTIONS
*****************************************************************/
 
 STATIC USHORT
@@ -122,7 +123,7 @@
     FxSave->ErrorSelector = FnSave->ErrorSelector & 0x0000ffff;
     FxSave->DataOffset = FnSave->DataOffset;
     FxSave->DataSelector = FnSave->DataSelector & 0x0000ffff;
-    if (XmmSupport)
+    if (KeI386XMMIPresent)
         FxSave->MXCsr = 0x00001f80 & MxcsrFeatureMask;
     else
         FxSave->MXCsr = 0;
@@ -160,7 +161,7 @@
 STATIC VOID
 KiFloatingSaveAreaToFxSaveArea(PFX_SAVE_AREA FxSaveArea,
FLOATING_SAVE_AREA *FloatingSaveArea)
 {
-    if (FxsrSupport)
+    if (KeI386FxsrPresent)
     {
         KiFnsaveToFxsaveFormat(&FxSaveArea->U.FxArea,
(PFNSAVE_FORMAT)FloatingSaveArea);
     }
@@ -176,7 +177,7 @@
 VOID
 KiFxSaveAreaToFloatingSaveArea(FLOATING_SAVE_AREA *FloatingSaveArea,
CONST PFX_SAVE_AREA FxSaveArea)
 {
-    if (FxsrSupport)
+    if (KeI386FxsrPresent)
     {
         KiFxsaveToFnsaveFormat((PFNSAVE_FORMAT)FloatingSaveArea,
&FxSaveArea->U.FxArea);
     }
@@ -203,7 +204,7 @@
     /* Now merge the FX_SAVE_AREA from the context with the destination
area */
     if ((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
CONTEXT_EXTENDED_REGISTERS)
     {
-        if (FxsrSupport)
+        if (KeI386FxsrPresent)
         {
             PFXSAVE_FORMAT src =
(PFXSAVE_FORMAT)Context->ExtendedRegisters;
             PFXSAVE_FORMAT dst = &FxSaveArea->U.FxArea;
@@ -245,9 +246,9 @@
     Ke386SaveFlags(Flags);
     Ke386DisableInterrupts();
 
-    HardwareMathSupport = 0;
-    FxsrSupport = 0;
-    XmmSupport = 0;
+    KeI386NpxPresent = 0;
+    KeI386FxsrPresent = 0;
+    KeI386XMMIPresent = 0;
 
     cr0 = Ke386GetCr0();
     cr0 |= X86_CR0_NE | X86_CR0_MP;
@@ -284,7 +285,7 @@
 #error Unknown compiler for inline assembler
 #endif
 
-    HardwareMathSupport = 1;
+    KeI386NpxPresent = 1;
 
     /* check for and enable MMX/SSE support if possible */
     if ((Prcb->FeatureBits & X86_FEATURE_FXSR) != 0)
@@ -293,7 +294,7 @@
         PFX_SAVE_AREA FxSaveArea;
 
         /* enable FXSR */
-        FxsrSupport = 1;
+        KeI386FxsrPresent = 1;
 
         /* we need a 16 byte aligned FX_SAVE_AREA */
         FxSaveArea = (PFX_SAVE_AREA)(((ULONG_PTR)DummyArea + 0xf) &
(~0x0f));
@@ -313,7 +314,7 @@
         Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);
 
         /* enable SSE */
-        XmmSupport = 1;
+        KeI386XMMIPresent = 1;
     }
 
     Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
@@ -338,7 +339,7 @@
 
             Cr0 = Ke386GetCr0();
             asm volatile("clts");
-            if (FxsrSupport)
+            if (KeI386FxsrPresent)
                 asm volatile("fxsave %0" : :
"m"(FxSaveArea->U.FxArea));
             else
             {
@@ -399,7 +400,7 @@
                 KeGetCurrentPrcb()->NpxThread = NULL;
                 FxSaveArea =
(PFX_SAVE_AREA)((ULONG_PTR)NpxThread->InitialStack - sizeof
(FX_SAVE_AREA));
                 /* the fnsave might raise a delayed #MF exception */
-                if (FxsrSupport)
+                if (KeI386FxsrPresent)
                 {
                     asm volatile("fxsave %0" : :
"m"(FxSaveArea->U.FxArea));
                 }
@@ -417,7 +418,7 @@
             FxSaveArea =
(PFX_SAVE_AREA)((ULONG_PTR)CurrentThread->InitialStack - sizeof
(FX_SAVE_AREA));
             if (CurrentThread->NpxState & NPX_STATE_VALID)
             {
-                if (FxsrSupport)
+                if (KeI386FxsrPresent)
                 {
                     FxSaveArea->U.FxArea.MXCsr &= MxcsrFeatureMask;
                     asm volatile("fxrstor %0" : :
"m"(FxSaveArea->U.FxArea));
@@ -430,11 +431,11 @@
             else /* NpxState & NPX_STATE_INVALID */
             {
                 DPRINT("Setting up clean FPU state\n");
-                if (FxsrSupport)
+                if (KeI386FxsrPresent)
                 {
                     memset(&FxSaveArea->U.FxArea, 0,
sizeof(FxSaveArea->U.FxArea));
                     FxSaveArea->U.FxArea.ControlWord = 0x037f;
-                    if (XmmSupport)
+                    if (KeI386XMMIPresent)
                     {
                         FxSaveArea->U.FxArea.MXCsr = 0x00001f80 &
MxcsrFeatureMask;
                     }
@@ -550,7 +551,7 @@
     ASSERT_IRQL(DISPATCH_LEVEL);
 
     /* check if we are doing software emulation */
-    if (!HardwareMathSupport)
+    if (!KeI386NpxPresent)
     {
         return STATUS_ILLEGAL_FLOAT_CONTEXT;
     }
  _____  

Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
--- trunk/reactos/ntoskrnl/ke/i386/kernel.c	2006-01-15 09:14:04 UTC
(rev 20886)
+++ trunk/reactos/ntoskrnl/ke/i386/kernel.c	2006-01-15 09:23:55 UTC
(rev 20887)
@@ -26,6 +26,9 @@

 BOOLEAN Ke386Pae = FALSE;
 BOOLEAN Ke386GlobalPagesEnabled = FALSE;
 ULONG KiFastSystemCallDisable = 1;
+ULONG KeI386NpxPresent = 0;
+ULONG KeI386XMMIPresent = 0;
+ULONG KeI386FxsrPresent = 0;
 extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
 extern ULONG IdleProcessorMask;
 
  _____  

Modified: trunk/reactos/ntoskrnl/ke/i386/thread.c
--- trunk/reactos/ntoskrnl/ke/i386/thread.c	2006-01-15 09:14:04 UTC
(rev 20886)
+++ trunk/reactos/ntoskrnl/ke/i386/thread.c	2006-01-15 09:23:55 UTC
(rev 20887)
@@ -3,8 +3,7 @@

  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/i386/thread.c
  * PURPOSE:         i386 Thread Context Creation
- *
- * PROGRAMMERS:     Alex Ionescu (alex at relsoft.net)
+ * PROGRAMMER:      Alex Ionescu (alex at relsoft.net)
  */
 
 /* INCLUDES
****************************************************************/
@@ -13,13 +12,15 @@
 #define NDEBUG
 #include <internal/debug.h>
 
-typedef struct _KSHARED_CTXSWITCH_FRAME {
+typedef struct _KSHARED_CTXSWITCH_FRAME
+{
     ULONG Esp0;
     PVOID ExceptionList;
     PVOID RetEip;
 } KSHARED_CTXSWITCH_FRAME, *PKSHARED_CTXSWITCH_FRAME;
 
-typedef struct _KSTART_FRAME {
+typedef struct _KSTART_FRAME
+{
     PKSYSTEM_ROUTINE SystemRoutine;
     PKSTART_ROUTINE StartRoutine;
     PVOID StartContext;
@@ -65,39 +66,113 @@
                            PKSYSTEM_ROUTINE SystemRoutine,
                            PKSTART_ROUTINE StartRoutine,
                            PVOID StartContext,
-                           PCONTEXT Context)
+                           PCONTEXT ContextPointer)
 {
     PFX_SAVE_AREA FxSaveArea;
+    PFXSAVE_FORMAT FxSaveFormat;
     PKSTART_FRAME StartFrame;
     PKSHARED_CTXSWITCH_FRAME CtxSwitchFrame;
-    PKTRAP_FRAME TrapFrame = NULL;
+    PKTRAP_FRAME TrapFrame;
+    CONTEXT LocalContext;
+    PCONTEXT Context = NULL;
+    ULONG ContextFlags;
 
     /* Check if this is a With-Context Thread */
     DPRINT("Ke386InitThreadContext\n");
-    if (Context)
+    if (ContextPointer)
     {
         /* Set up the Initial Frame */
         PKUINIT_FRAME InitFrame;
-        InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
sizeof(KUINIT_FRAME));
-        DPRINT("Setting up a user-mode thread with the Frame at: %x\n",
InitFrame);
+        InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
+                                    sizeof(KUINIT_FRAME));
+        DPRINT("Setting up a user-mode thread. InitFrame at: %p\n",
InitFrame);
 
-        /* Setup the Trap Frame */
-        TrapFrame = &InitFrame->TrapFrame;
+        /* Copy over the context we got */
+        RtlMoveMemory(&LocalContext, ContextPointer, sizeof(CONTEXT));
+        Context = &LocalContext;
+        ContextFlags = CONTEXT_CONTROL;
 
-        /* Set up a trap frame from the context. */
-        if (KeContextToTrapFrame(Context, NULL, TrapFrame, UserMode))
+        /* Setup the Fx Area */
+        FxSaveArea = &InitFrame->FxSaveArea;
+
+        /* Check if we support FXsr */
+        if (KeI386FxsrPresent)
         {
-            Thread->NpxState = NPX_STATE_VALID;
+            /* Get the FX Save Format Area */
+            FxSaveFormat = (PFXSAVE_FORMAT)Context->ExtendedRegisters;
+
+            /* Set an initial state */
+            FxSaveFormat->ControlWord = 0x27F;
+            FxSaveFormat->StatusWord = 0;
+            FxSaveFormat->TagWord = 0;
+            FxSaveFormat->ErrorOffset = 0;
+            FxSaveFormat->ErrorSelector = 0;
+            FxSaveFormat->DataOffset =0;
+            FxSaveFormat->DataSelector = 0;
+            FxSaveFormat->MXCsr = 0x1F80;
         }
         else
         {
-            Thread->NpxState = NPX_STATE_INVALID;
+            /* Setup the regular save area */
+            Context->FloatSave.ControlWord = 0x27F;
+            Context->FloatSave.StatusWord = 0;
+            Context->FloatSave.TagWord = -1;
+            Context->FloatSave.ErrorOffset = 0;
+            Context->FloatSave.ErrorSelector = 0;
+            Context->FloatSave.DataOffset =0;
+            Context->FloatSave.DataSelector = 0;
         }
 
-        /* Enable Interrupts and disable some unsupported flags right
now */
-        TrapFrame->EFlags = Context->EFlags | X86_EFLAGS_IF;
-        TrapFrame->EFlags &= ~(X86_EFLAGS_VM | X86_EFLAGS_NT |
X86_EFLAGS_IOPL);
+        /* Check if the CPU has NPX */
+        if (KeI386NpxPresent)
+        {
+            /* Set an intial NPX State */
+            Context->FloatSave.Cr0NpxState = 0;
+            FxSaveArea->Cr0NpxState = 0;
+            FxSaveArea->NpxSavedCpu = 0;
 
+            /* Now set the context flags depending on XMM support */
+            ContextFlags |= (KeI386XMMIPresent) ?
CONTEXT_EXTENDED_REGISTERS :
+
CONTEXT_FLOATING_POINT;
+
+            /* Set the Thread's NPX State */
+            Thread->NpxState = NPX_STATE_NOT_LOADED;
+            Thread->DispatcherHeader.NpxIrql = PASSIVE_LEVEL;
+        }
+        else
+        {
+            /* We'll use emulation */
+            FxSaveArea->Cr0NpxState = CR0_EM;
+            Thread->NpxState = NPX_STATE_NOT_LOADED &~ CR0_MP;
+        }
+
+        /* Disable any debug regiseters */
+        Context->Dr0 = 0;
+        Context->Dr1 = 0;
+        Context->Dr2 = 0;
+        Context->Dr3 = 0;
+        Context->Dr6 = 0;
+        Context->Dr7 = 0;
+        Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
+
+        /* Setup the Trap Frame */
+        TrapFrame = &InitFrame->TrapFrame;
+
+        /* Set up a trap frame from the context. */
+        KeContextToTrapFrame(Context,
+                             NULL,
+                             TrapFrame,
+                             Context->ContextFlags | ContextFlags,
+                             UserMode);
+
+        /* Set SS, DS, ES's RPL Mask properly */
+        TrapFrame->HardwareSegSs |= RPL_MASK;
+        TrapFrame->SegDs |= RPL_MASK;
+        TrapFrame->SegEs |= RPL_MASK;
+
+        /* Set the debug mark */
+        TrapFrame->DbgArgMark = 0xBADB0D00;
+
         /* Set the previous mode as user */
         TrapFrame->PreviousPreviousMode = UserMode;
 
@@ -116,20 +191,33 @@
     }
     else
     {
-        /* No context Thread, meaning System Thread */
-
-        /* Set up the Initial Frame */
+        /* Set up the Initial Frame for the system thread */
         PKKINIT_FRAME InitFrame;
-        InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
sizeof(KKINIT_FRAME));
-        DPRINT("Setting up a kernel thread with the Frame at: %x\n",
InitFrame);
+        InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
+                                    sizeof(KKINIT_FRAME));
+        DPRINT("Setting up a kernel thread. InitFrame at: %p\n",
InitFrame);
 
         /* Setup the Fx Area */
         FxSaveArea = &InitFrame->FxSaveArea;
-
         RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA));
 
-        Thread->NpxState = NPX_STATE_INVALID;
+        /* Check if we have Fxsr support */
+        if (KeI386FxsrPresent)
+        {
+            /* Set the stub FX area */
+            FxSaveArea->U.FxArea.ControlWord = 0x27F;
+            FxSaveArea->U.FxArea.MXCsr = 0x1F80;
+        }
+        else
+        {
+            /* Set the stub FN area */
+            FxSaveArea->U.FnArea.ControlWord = 0x27F;
+            FxSaveArea->U.FnArea.TagWord = -1;
+        }
 
+        /* No NPX State */
+        Thread->NpxState = NPX_STATE_NOT_LOADED;
+
         /* Setup the Stack for KiThreadStartup and Context Switching */
         StartFrame = &InitFrame->StartFrame;
         CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
  _____  

Modified: trunk/reactos/ntoskrnl/ps/debug.c
--- trunk/reactos/ntoskrnl/ps/debug.c	2006-01-15 09:14:04 UTC (rev
20886)
+++ trunk/reactos/ntoskrnl/ps/debug.c	2006-01-15 09:23:55 UTC (rev
20887)
@@ -68,7 +68,7 @@

             KeTrapFrameToContext(TrapFrame, NULL, Context);
         } else {
             /* Set the Context */
-            KeContextToTrapFrame(Context, NULL, TrapFrame, Mode);
+            KeContextToTrapFrame(Context, NULL, TrapFrame,
Context->ContextFlags, Mode);
         }
         GetSetContext->Status = STATUS_SUCCESS;
     }
@@ -249,7 +249,7 @@
              * I don't know if trying to set your own context makes
much
              * sense but we can handle it more efficently.
              */
-            KeContextToTrapFrame(ThreadContext, NULL,
Thread->Tcb.TrapFrame, PreviousMode);
+            KeContextToTrapFrame(ThreadContext, NULL,
Thread->Tcb.TrapFrame, ThreadContext->ContextFlags, PreviousMode);
 
         } else {
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-diffs/attachments/20060115/09f32822/attachment.html


More information about the Ros-diffs mailing list