Sync to trunk head(r38096)
[reactos.git] / reactos / ntoskrnl / ke / amd64 / thrdini.c
1 /*
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)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 #if 0
15 typedef struct _KSWITCHFRAME
16 {
17 PVOID ExceptionList;
18 BOOLEAN ApcBypassDisable;
19 PVOID RetAddr;
20 } KSWITCHFRAME, *PKSWITCHFRAME;
21
22 typedef struct _KSTART_FRAME
23 {
24 PKSYSTEM_ROUTINE SystemRoutine;
25 PKSTART_ROUTINE StartRoutine;
26 PVOID StartContext;
27 BOOLEAN UserThread;
28 } KSTART_FRAME, *PKSTART_FRAME;
29
30 typedef struct _KUINIT_FRAME
31 {
32 KSWITCHFRAME CtxSwitchFrame;
33 KSTART_FRAME StartFrame;
34 KTRAP_FRAME TrapFrame;
35 FX_SAVE_AREA FxSaveArea;
36 } KUINIT_FRAME, *PKUINIT_FRAME;
37
38 typedef struct _KKINIT_FRAME
39 {
40 KSWITCHFRAME CtxSwitchFrame;
41 KSTART_FRAME StartFrame;
42 FX_SAVE_AREA FxSaveArea;
43 } KKINIT_FRAME, *PKKINIT_FRAME;
44 #endif
45 /* FUNCTIONS *****************************************************************/
46
47 VOID
48 NTAPI
49 Ke386InitThreadWithContext(IN PKTHREAD Thread,
50 IN PKSYSTEM_ROUTINE SystemRoutine,
51 IN PKSTART_ROUTINE StartRoutine,
52 IN PVOID StartContext,
53 IN PCONTEXT ContextPointer)
54 {
55 FrLdrDbgPrint("Ke386InitThreadWithContext stub\n");
56 #if 0
57 PFX_SAVE_AREA FxSaveArea;
58 PFXSAVE_FORMAT FxSaveFormat;
59 PKSTART_FRAME StartFrame;
60 PKSWITCHFRAME CtxSwitchFrame;
61 PKTRAP_FRAME TrapFrame;
62 CONTEXT LocalContext;
63 PCONTEXT Context = NULL;
64 ULONG ContextFlags;
65
66 /* Check if this is a With-Context Thread */
67 if (ContextPointer)
68 {
69 /* Set up the Initial Frame */
70 PKUINIT_FRAME InitFrame;
71 InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
72 sizeof(KUINIT_FRAME));
73
74 /* Copy over the context we got */
75 RtlCopyMemory(&LocalContext, ContextPointer, sizeof(CONTEXT));
76 Context = &LocalContext;
77 ContextFlags = CONTEXT_CONTROL;
78
79 /* Zero out the trap frame and save area */
80 RtlZeroMemory(&InitFrame->TrapFrame,
81 KTRAP_FRAME_LENGTH + sizeof(FX_SAVE_AREA));
82
83 /* Setup the Fx Area */
84 FxSaveArea = &InitFrame->FxSaveArea;
85
86 /* Check if we support FXsr */
87 if (KeI386FxsrPresent)
88 {
89 /* Get the FX Save Format Area */
90 FxSaveFormat = (PFXSAVE_FORMAT)Context->ExtendedRegisters;
91
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;
101 }
102 else
103 {
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;
112 }
113
114 /* Check if the CPU has NPX */
115 if (KeI386NpxPresent)
116 {
117 /* Set an intial NPX State */
118 Context->FloatSave.Cr0NpxState = 0;
119 FxSaveArea->Cr0NpxState = 0;
120 FxSaveArea->NpxSavedCpu = 0;
121
122 /* Now set the context flags depending on XMM support */
123 ContextFlags |= (KeI386FxsrPresent) ? CONTEXT_EXTENDED_REGISTERS :
124 CONTEXT_FLOATING_POINT;
125
126 /* Set the Thread's NPX State */
127 Thread->NpxState = NPX_STATE_NOT_LOADED;
128 Thread->DispatcherHeader.NpxIrql = PASSIVE_LEVEL;
129 }
130 else
131 {
132 /* We'll use emulation */
133 FxSaveArea->Cr0NpxState = CR0_EM;
134 Thread->NpxState = NPX_STATE_NOT_LOADED &~ CR0_MP;
135 }
136
137 /* Disable any debug regiseters */
138 Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
139
140 /* Setup the Trap Frame */
141 TrapFrame = &InitFrame->TrapFrame;
142
143 /* Set up a trap frame from the context. */
144 KeContextToTrapFrame(Context,
145 NULL,
146 TrapFrame,
147 Context->ContextFlags | ContextFlags,
148 UserMode);
149
150 /* Set SS, DS, ES's RPL Mask properly */
151 TrapFrame->HardwareSegSs |= RPL_MASK;
152 TrapFrame->SegDs |= RPL_MASK;
153 TrapFrame->SegEs |= RPL_MASK;
154 TrapFrame->Dr7 = 0;
155
156 /* Set the debug mark */
157 TrapFrame->DbgArgMark = 0xBADB0D00;
158
159 /* Set the previous mode as user */
160 TrapFrame->PreviousPreviousMode = UserMode;
161
162 /* Terminate the Exception Handler List */
163 TrapFrame->ExceptionList = EXCEPTION_CHAIN_END;
164
165 /* Setup the Stack for KiThreadStartup and Context Switching */
166 StartFrame = &InitFrame->StartFrame;
167 CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
168
169 /* Tell the thread it will run in User Mode */
170 Thread->PreviousMode = UserMode;
171
172 /* Tell KiThreadStartup of that too */
173 StartFrame->UserThread = TRUE;
174 }
175 else
176 {
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));
181
182 /* Setup the Fx Area */
183 FxSaveArea = &InitFrame->FxSaveArea;
184 RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA));
185
186 /* Check if we have Fxsr support */
187 if (KeI386FxsrPresent)
188 {
189 /* Set the stub FX area */
190 FxSaveArea->U.FxArea.ControlWord = 0x27F;
191 FxSaveArea->U.FxArea.MXCsr = 0x1F80;
192 }
193 else
194 {
195 /* Set the stub FN area */
196 FxSaveArea->U.FnArea.ControlWord = 0x27F;
197 FxSaveArea->U.FnArea.TagWord = -1;
198 }
199
200 /* No NPX State */
201 Thread->NpxState = NPX_STATE_NOT_LOADED;
202
203 /* Setup the Stack for KiThreadStartup and Context Switching */
204 StartFrame = &InitFrame->StartFrame;
205 CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
206
207 /* Tell the thread it will run in Kernel Mode */
208 Thread->PreviousMode = KernelMode;
209
210 /* Tell KiThreadStartup of that too */
211 StartFrame->UserThread = FALSE;
212 }
213
214 /* Now setup the remaining data for KiThreadStartup */
215 StartFrame->StartContext = StartContext;
216 StartFrame->StartRoutine = StartRoutine;
217 StartFrame->SystemRoutine = SystemRoutine;
218
219 /* And set up the Context Switch Frame */
220 CtxSwitchFrame->RetAddr = KiThreadStartup;
221 CtxSwitchFrame->ApcBypassDisable = TRUE;
222 CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;;
223
224 /* Save back the new value of the kernel stack. */
225 Thread->KernelStack = (PVOID)CtxSwitchFrame;
226 #endif
227 }
228
229 /* EOF */
230
231