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