- 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(a)cwcom.net)
+ * PURPOSE: Exception Support Code
+ * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
+ * Gregor Anich
+ * David Welch (welch(a)cwcom.net)
* Skywing (skywing(a)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(a)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(a)relsoft.net)
+ * PROGRAMMER: Alex Ionescu (alex(a)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 {