2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/i386/thread.c
5 * PURPOSE: i386 Thread Context Creation
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES ******************************************************************/
15 typedef struct _KSWITCHFRAME
18 BOOLEAN ApcBypassDisable
;
20 } KSWITCHFRAME
, *PKSWITCHFRAME
;
22 typedef struct _KSTART_FRAME
24 PKSYSTEM_ROUTINE SystemRoutine
;
25 PKSTART_ROUTINE StartRoutine
;
28 } KSTART_FRAME
, *PKSTART_FRAME
;
30 typedef struct _KUINIT_FRAME
32 KSWITCHFRAME CtxSwitchFrame
;
33 KSTART_FRAME StartFrame
;
34 KTRAP_FRAME TrapFrame
;
35 FX_SAVE_AREA FxSaveArea
;
36 } KUINIT_FRAME
, *PKUINIT_FRAME
;
38 typedef struct _KKINIT_FRAME
40 KSWITCHFRAME CtxSwitchFrame
;
41 KSTART_FRAME StartFrame
;
42 FX_SAVE_AREA FxSaveArea
;
43 } KKINIT_FRAME
, *PKKINIT_FRAME
;
45 /* FUNCTIONS *****************************************************************/
49 Ke386InitThreadWithContext(IN PKTHREAD Thread
,
50 IN PKSYSTEM_ROUTINE SystemRoutine
,
51 IN PKSTART_ROUTINE StartRoutine
,
52 IN PVOID StartContext
,
53 IN PCONTEXT ContextPointer
)
55 FrLdrDbgPrint("Ke386InitThreadWithContext stub\n");
57 PFX_SAVE_AREA FxSaveArea
;
58 PFXSAVE_FORMAT FxSaveFormat
;
59 PKSTART_FRAME StartFrame
;
60 PKSWITCHFRAME CtxSwitchFrame
;
61 PKTRAP_FRAME TrapFrame
;
63 PCONTEXT Context
= NULL
;
66 /* Check if this is a With-Context Thread */
69 /* Set up the Initial Frame */
70 PKUINIT_FRAME InitFrame
;
71 InitFrame
= (PKUINIT_FRAME
)((ULONG_PTR
)Thread
->InitialStack
-
72 sizeof(KUINIT_FRAME
));
74 /* Copy over the context we got */
75 RtlCopyMemory(&LocalContext
, ContextPointer
, sizeof(CONTEXT
));
76 Context
= &LocalContext
;
77 ContextFlags
= CONTEXT_CONTROL
;
79 /* Zero out the trap frame and save area */
80 RtlZeroMemory(&InitFrame
->TrapFrame
,
81 KTRAP_FRAME_LENGTH
+ sizeof(FX_SAVE_AREA
));
83 /* Setup the Fx Area */
84 FxSaveArea
= &InitFrame
->FxSaveArea
;
86 /* Check if we support FXsr */
87 if (KeI386FxsrPresent
)
89 /* Get the FX Save Format Area */
90 FxSaveFormat
= (PFXSAVE_FORMAT
)Context
->ExtendedRegisters
;
92 /* Set an initial state */
93 FxSaveFormat
->ControlWord
= 0x27F;
94 FxSaveFormat
->StatusWord
= 0;
95 FxSaveFormat
->TagWord
= 0;
96 FxSaveFormat
->ErrorOffset
= 0;
97 FxSaveFormat
->ErrorSelector
= 0;
98 FxSaveFormat
->DataOffset
= 0;
99 FxSaveFormat
->DataSelector
= 0;
100 FxSaveFormat
->MXCsr
= 0x1F80;
104 /* Setup the regular save area */
105 Context
->FloatSave
.ControlWord
= 0x27F;
106 Context
->FloatSave
.StatusWord
= 0;
107 Context
->FloatSave
.TagWord
= -1;
108 Context
->FloatSave
.ErrorOffset
= 0;
109 Context
->FloatSave
.ErrorSelector
= 0;
110 Context
->FloatSave
.DataOffset
=0;
111 Context
->FloatSave
.DataSelector
= 0;
114 /* Check if the CPU has NPX */
115 if (KeI386NpxPresent
)
117 /* Set an intial NPX State */
118 Context
->FloatSave
.Cr0NpxState
= 0;
119 FxSaveArea
->Cr0NpxState
= 0;
120 FxSaveArea
->NpxSavedCpu
= 0;
122 /* Now set the context flags depending on XMM support */
123 ContextFlags
|= (KeI386FxsrPresent
) ? CONTEXT_EXTENDED_REGISTERS
:
124 CONTEXT_FLOATING_POINT
;
126 /* Set the Thread's NPX State */
127 Thread
->NpxState
= NPX_STATE_NOT_LOADED
;
128 Thread
->DispatcherHeader
.NpxIrql
= PASSIVE_LEVEL
;
132 /* We'll use emulation */
133 FxSaveArea
->Cr0NpxState
= CR0_EM
;
134 Thread
->NpxState
= NPX_STATE_NOT_LOADED
&~ CR0_MP
;
137 /* Disable any debug regiseters */
138 Context
->ContextFlags
&= ~CONTEXT_DEBUG_REGISTERS
;
140 /* Setup the Trap Frame */
141 TrapFrame
= &InitFrame
->TrapFrame
;
143 /* Set up a trap frame from the context. */
144 KeContextToTrapFrame(Context
,
147 Context
->ContextFlags
| ContextFlags
,
150 /* Set SS, DS, ES's RPL Mask properly */
151 TrapFrame
->HardwareSegSs
|= RPL_MASK
;
152 TrapFrame
->SegDs
|= RPL_MASK
;
153 TrapFrame
->SegEs
|= RPL_MASK
;
156 /* Set the debug mark */
157 TrapFrame
->DbgArgMark
= 0xBADB0D00;
159 /* Set the previous mode as user */
160 TrapFrame
->PreviousPreviousMode
= UserMode
;
162 /* Terminate the Exception Handler List */
163 TrapFrame
->ExceptionList
= EXCEPTION_CHAIN_END
;
165 /* Setup the Stack for KiThreadStartup and Context Switching */
166 StartFrame
= &InitFrame
->StartFrame
;
167 CtxSwitchFrame
= &InitFrame
->CtxSwitchFrame
;
169 /* Tell the thread it will run in User Mode */
170 Thread
->PreviousMode
= UserMode
;
172 /* Tell KiThreadStartup of that too */
173 StartFrame
->UserThread
= TRUE
;
177 /* Set up the Initial Frame for the system thread */
178 PKKINIT_FRAME InitFrame
;
179 InitFrame
= (PKKINIT_FRAME
)((ULONG_PTR
)Thread
->InitialStack
-
180 sizeof(KKINIT_FRAME
));
182 /* Setup the Fx Area */
183 FxSaveArea
= &InitFrame
->FxSaveArea
;
184 RtlZeroMemory(FxSaveArea
, sizeof(FX_SAVE_AREA
));
186 /* Check if we have Fxsr support */
187 if (KeI386FxsrPresent
)
189 /* Set the stub FX area */
190 FxSaveArea
->U
.FxArea
.ControlWord
= 0x27F;
191 FxSaveArea
->U
.FxArea
.MXCsr
= 0x1F80;
195 /* Set the stub FN area */
196 FxSaveArea
->U
.FnArea
.ControlWord
= 0x27F;
197 FxSaveArea
->U
.FnArea
.TagWord
= -1;
201 Thread
->NpxState
= NPX_STATE_NOT_LOADED
;
203 /* Setup the Stack for KiThreadStartup and Context Switching */
204 StartFrame
= &InitFrame
->StartFrame
;
205 CtxSwitchFrame
= &InitFrame
->CtxSwitchFrame
;
207 /* Tell the thread it will run in Kernel Mode */
208 Thread
->PreviousMode
= KernelMode
;
210 /* Tell KiThreadStartup of that too */
211 StartFrame
->UserThread
= FALSE
;
214 /* Now setup the remaining data for KiThreadStartup */
215 StartFrame
->StartContext
= StartContext
;
216 StartFrame
->StartRoutine
= StartRoutine
;
217 StartFrame
->SystemRoutine
= SystemRoutine
;
219 /* And set up the Context Switch Frame */
220 CtxSwitchFrame
->RetAddr
= KiThreadStartup
;
221 CtxSwitchFrame
->ApcBypassDisable
= TRUE
;
222 CtxSwitchFrame
->ExceptionList
= EXCEPTION_CHAIN_END
;;
224 /* Save back the new value of the kernel stack. */
225 Thread
->KernelStack
= (PVOID
)CtxSwitchFrame
;