mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
- 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. svn path=/trunk/; revision=20887
This commit is contained in:
parent
1b8586982f
commit
20e6dde401
9 changed files with 310 additions and 94 deletions
|
@ -110,6 +110,7 @@ Author:
|
|||
#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 @@ Author:
|
|||
#define KPCR_NPX_THREAD 0x2F4
|
||||
#define KPCR_DR6 0x428
|
||||
#define KPCR_DR7 0x42C
|
||||
#define KPCR_SYSTEM_CALLS 0x6B8
|
||||
|
||||
//
|
||||
// KGDTENTRY Offsets
|
||||
|
@ -142,6 +144,12 @@ Author:
|
|||
#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
|
||||
//
|
||||
|
|
|
@ -41,6 +41,9 @@ extern PVOID KeUserExceptionDispatcher;
|
|||
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 @@ PULONG
|
|||
NTAPI
|
||||
KeGetStackTopThread(struct _ETHREAD* Thread);
|
||||
|
||||
BOOLEAN
|
||||
VOID
|
||||
STDCALL
|
||||
KeContextToTrapFrame(
|
||||
PCONTEXT Context,
|
||||
PKEXCEPTION_FRAME ExeptionFrame,
|
||||
PKTRAP_FRAME TrapFrame,
|
||||
ULONG ContextFlags,
|
||||
KPROCESSOR_MODE PreviousMode
|
||||
);
|
||||
|
||||
|
|
|
@ -1720,7 +1720,7 @@ GspBreakIn(PKINTERRUPT Interrupt,
|
|||
|
||||
KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
|
||||
|
||||
KeContextToTrapFrame(&Context, NULL, TrapFrame, KernelMode);
|
||||
KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags, KernelMode);
|
||||
|
||||
KeLowerIrql(OldIrql);
|
||||
|
||||
|
|
|
@ -28,7 +28,11 @@ KiContinuePreviousModeUser(IN PCONTEXT Context,
|
|||
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 @@ KiContinue(IN PCONTEXT Context,
|
|||
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 @@ KiRaiseException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
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,
|
||||
|
|
|
@ -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 @@ KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame,
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
}
|
||||
|
||||
/* 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 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
}
|
||||
|
||||
/* 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 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
}
|
||||
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 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
}
|
||||
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 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
}
|
||||
}
|
||||
|
||||
/* 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 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
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 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
|
|||
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 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
|
|||
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 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
/* 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 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,9 +38,11 @@
|
|||
|
||||
/* 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 *****************************************************************/
|
||||
|
||||
|
@ -122,7 +123,7 @@ KiFnsaveToFxsaveFormat(PFXSAVE_FORMAT FxSave, PFNSAVE_FORMAT FnSave)
|
|||
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 @@ KiFxsaveToFnsaveFormat(PFNSAVE_FORMAT FnSave, PFXSAVE_FORMAT FxSave)
|
|||
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 @@ KiFloatingSaveAreaToFxSaveArea(PFX_SAVE_AREA FxSaveArea, FLOATING_SAVE_AREA *Flo
|
|||
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 @@ KiContextToFxSaveArea(PFX_SAVE_AREA FxSaveArea, PCONTEXT Context)
|
|||
/* 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 @@ KiCheckFPU(VOID)
|
|||
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 @@ KiCheckFPU(VOID)
|
|||
#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 @@ KiCheckFPU(VOID)
|
|||
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 @@ KiCheckFPU(VOID)
|
|||
Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);
|
||||
|
||||
/* enable SSE */
|
||||
XmmSupport = 1;
|
||||
KeI386XMMIPresent = 1;
|
||||
}
|
||||
|
||||
Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
|
||||
|
@ -338,7 +339,7 @@ KiGetFpuState(PKTHREAD Thread)
|
|||
|
||||
Cr0 = Ke386GetCr0();
|
||||
asm volatile("clts");
|
||||
if (FxsrSupport)
|
||||
if (KeI386FxsrPresent)
|
||||
asm volatile("fxsave %0" : : "m"(FxSaveArea->U.FxArea));
|
||||
else
|
||||
{
|
||||
|
@ -399,7 +400,7 @@ KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
|||
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 @@ KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
|||
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 @@ KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
|||
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 @@ KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
|
|||
ASSERT_IRQL(DISPATCH_LEVEL);
|
||||
|
||||
/* check if we are doing software emulation */
|
||||
if (!HardwareMathSupport)
|
||||
if (!KeI386NpxPresent)
|
||||
{
|
||||
return STATUS_ILLEGAL_FLOAT_CONTEXT;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ BOOLEAN Ke386NoExecute = FALSE;
|
|||
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;
|
||||
|
||||
|
|
|
@ -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,38 +66,112 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
|
|||
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);
|
||||
|
||||
/* Copy over the context we got */
|
||||
RtlMoveMemory(&LocalContext, ContextPointer, sizeof(CONTEXT));
|
||||
Context = &LocalContext;
|
||||
ContextFlags = CONTEXT_CONTROL;
|
||||
|
||||
/* 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
|
||||
{
|
||||
/* 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
|
||||
{
|
||||
/* 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. */
|
||||
if (KeContextToTrapFrame(Context, NULL, TrapFrame, UserMode))
|
||||
{
|
||||
Thread->NpxState = NPX_STATE_VALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread->NpxState = NPX_STATE_INVALID;
|
||||
}
|
||||
KeContextToTrapFrame(Context,
|
||||
NULL,
|
||||
TrapFrame,
|
||||
Context->ContextFlags | ContextFlags,
|
||||
UserMode);
|
||||
|
||||
/* 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);
|
||||
/* 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,19 +191,32 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
|
|||
}
|
||||
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;
|
||||
|
|
|
@ -68,7 +68,7 @@ PspGetOrSetContextKernelRoutine(PKAPC Apc,
|
|||
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 @@ NtSetContextThread(IN HANDLE ThreadHandle,
|
|||
* 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 {
|
||||
|
||||
|
|
Loading…
Reference in a new issue