- 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.
svn path=/trunk/; revision=20887
#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
#define KPCR_NPX_THREAD 0x2F4
#define KPCR_DR6 0x428
#define KPCR_DR7 0x42C
+#define KPCR_SYSTEM_CALLS 0x6B8
//
// KGDTENTRY Offsets
#define SIZEOF_FX_SAVE_AREA 528
#define NPX_FRAME_LENGTH 0x210
+//
+// NPX States
+//
+#define NPX_STATE_NOT_LOADED 0xA
+#define NPX_STATE_LOADED 0x0
+
//
// Trap Frame Offsets
//
extern PVOID KeRaiseUserExceptionDispatcher;
extern LARGE_INTEGER SystemBootTime;
extern ULONG_PTR KERNEL_BASE;
+extern ULONG KeI386NpxPresent;
+extern ULONG KeI386XMMIPresent;
+extern ULONG KeI386FxsrPresent;
/* MACROS *************************************************************************/
NTAPI
KeGetStackTopThread(struct _ETHREAD* Thread);
-BOOLEAN
+VOID
STDCALL
KeContextToTrapFrame(
PCONTEXT Context,
PKEXCEPTION_FRAME ExeptionFrame,
PKTRAP_FRAME TrapFrame,
+ ULONG ContextFlags,
KPROCESSOR_MODE PreviousMode
);
KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
- KeContextToTrapFrame(&Context, NULL, TrapFrame, KernelMode);
+ KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags, KernelMode);
KeLowerIrql(OldIrql);
Context = &LocalContext;\r
\r
/* Convert the context into Exception/Trap Frames */\r
- KeContextToTrapFrame(&LocalContext, ExceptionFrame, TrapFrame, UserMode);\r
+ KeContextToTrapFrame(&LocalContext,\r
+ ExceptionFrame,\r
+ TrapFrame,\r
+ LocalContext.ContextFlags,\r
+ UserMode);\r
}\r
\r
NTSTATUS\r
else\r
{\r
/* Convert the context into Exception/Trap Frames */\r
- KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame, KernelMode);\r
+ KeContextToTrapFrame(Context,\r
+ ExceptionFrame,\r
+ TrapFrame,\r
+ Context->ContextFlags,\r
+ KernelMode);\r
}\r
}\r
_SEH_HANDLE\r
if (NT_SUCCESS(Status))\r
{\r
/* Convert the context record */\r
- KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame, PreviousMode);\r
+ KeContextToTrapFrame(Context,\r
+ ExceptionFrame,\r
+ TrapFrame,\r
+ Context->ContextFlags,\r
+ PreviousMode);\r
\r
/* Dispatch the exception */\r
KiDispatchException(ExceptionRecord,\r
/*
* 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@cwcom.net)
+ * PURPOSE: Exception Support Code
+ * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
+ * Gregor Anich
+ * David Welch (welch@cwcom.net)
* Skywing (skywing@valhallalegends.com)
*/
/*
* FIXMES:
- * - Put back VEH.
* - Clean up file.
* - Sanitize some context fields.
* - Add PSEH handler when an exception occurs in an exception (KiCopyExceptionRecord).
}
}
-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) !=
}
/* 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;
}
/* 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)
}
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;
}
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;
}
}
+ /* 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;
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
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)
{
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;
}
}
}
/* 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 */
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;
+
+ /* Get the old EIP */
+ OldEip = Thread->TrapFrame->Eip;
+
+ /* Change it to the user-mode dispatcher */
+ Thread->TrapFrame->Eip = (ULONG_PTR)KeRaiseUserExceptionDispatcher;
- OldEip = Thread->TrapFrame->Eip;
- Thread->TrapFrame->Eip = (ULONG_PTR)KeRaiseUserExceptionDispatcher;
- return((NTSTATUS)OldEip);
+ /* Return the old EIP */
+ return((NTSTATUS)OldEip);
}
-/* $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@mcmail.com)
+ * Gregor Anich
*/
/* INCLUDES *****************************************************************/
/* 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 *****************************************************************/
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;
STATIC VOID
KiFloatingSaveAreaToFxSaveArea(PFX_SAVE_AREA FxSaveArea, FLOATING_SAVE_AREA *FloatingSaveArea)
{
- if (FxsrSupport)
+ if (KeI386FxsrPresent)
{
KiFnsaveToFxsaveFormat(&FxSaveArea->U.FxArea, (PFNSAVE_FORMAT)FloatingSaveArea);
}
VOID
KiFxSaveAreaToFloatingSaveArea(FLOATING_SAVE_AREA *FloatingSaveArea, CONST PFX_SAVE_AREA FxSaveArea)
{
- if (FxsrSupport)
+ if (KeI386FxsrPresent)
{
KiFxsaveToFnsaveFormat((PFNSAVE_FORMAT)FloatingSaveArea, &FxSaveArea->U.FxArea);
}
/* 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;
Ke386SaveFlags(Flags);
Ke386DisableInterrupts();
- HardwareMathSupport = 0;
- FxsrSupport = 0;
- XmmSupport = 0;
+ KeI386NpxPresent = 0;
+ KeI386FxsrPresent = 0;
+ KeI386XMMIPresent = 0;
cr0 = Ke386GetCr0();
cr0 |= X86_CR0_NE | X86_CR0_MP;
#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)
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));
Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);
/* enable SSE */
- XmmSupport = 1;
+ KeI386XMMIPresent = 1;
}
Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
Cr0 = Ke386GetCr0();
asm volatile("clts");
- if (FxsrSupport)
+ if (KeI386FxsrPresent)
asm volatile("fxsave %0" : : "m"(FxSaveArea->U.FxArea));
else
{
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));
}
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));
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;
}
ASSERT_IRQL(DISPATCH_LEVEL);
/* check if we are doing software emulation */
- if (!HardwareMathSupport)
+ if (!KeI386NpxPresent)
{
return STATUS_ILLEGAL_FLOAT_CONTEXT;
}
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;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/thread.c
* PURPOSE: i386 Thread Context Creation
- *
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
+ * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ****************************************************************/
#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;
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)
+ {
+ /* 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_VALID;
+ /* 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;
+ }
+
+ /* 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
{
- Thread->NpxState = NPX_STATE_INVALID;
+ /* We'll use emulation */
+ FxSaveArea->Cr0NpxState = CR0_EM;
+ Thread->NpxState = NPX_STATE_NOT_LOADED &~ CR0_MP;
}
- /* 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);
+ /* 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;
}
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;
KeTrapFrameToContext(TrapFrame, NULL, Context);
} else {
/* Set the Context */
- KeContextToTrapFrame(Context, NULL, TrapFrame, Mode);
+ KeContextToTrapFrame(Context, NULL, TrapFrame, Context->ContextFlags, Mode);
}
GetSetContext->Status = STATUS_SUCCESS;
}
* 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 {