Sync with trunk (48237)
[reactos.git] / 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
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
45 /* FUNCTIONS *****************************************************************/
46
47 VOID
48 NTAPI
49 KiInitializeContextThread(IN PKTHREAD Thread,
50 IN PKSYSTEM_ROUTINE SystemRoutine,
51 IN PKSTART_ROUTINE StartRoutine,
52 IN PVOID StartContext,
53 IN PCONTEXT ContextPointer)
54 {
55 //PFX_SAVE_AREA FxSaveArea;
56 //PFXSAVE_FORMAT FxSaveFormat;
57 PKSTART_FRAME StartFrame;
58 PKSWITCHFRAME CtxSwitchFrame;
59 PKTRAP_FRAME TrapFrame;
60 CONTEXT LocalContext;
61 PCONTEXT Context = NULL;
62 ULONG ContextFlags;
63
64 /* Check if this is a With-Context Thread */
65 if (ContextPointer)
66 {
67 /* Set up the Initial Frame */
68 PKUINIT_FRAME InitFrame;
69 InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
70 sizeof(KUINIT_FRAME));
71
72 /* Copy over the context we got */
73 RtlCopyMemory(&LocalContext, ContextPointer, sizeof(CONTEXT));
74 Context = &LocalContext;
75 ContextFlags = CONTEXT_CONTROL;
76
77 /* Zero out the trap frame and save area */
78 RtlZeroMemory(&InitFrame->TrapFrame,
79 KTRAP_FRAME_LENGTH);
80
81 /* Setup the Fx Area */
82 //FxSaveArea = &InitFrame->FxSaveArea;
83
84 // /* Get the FX Save Format Area */
85 // FxSaveFormat = (PFXSAVE_FORMAT)Context->ExtendedRegisters;
86 //
87 // /* Set an initial state */
88 // FxSaveFormat->ControlWord = 0x27F;
89 // FxSaveFormat->StatusWord = 0;
90 // FxSaveFormat->TagWord = 0;
91 // FxSaveFormat->ErrorOffset = 0;
92 // FxSaveFormat->ErrorSelector = 0;
93 // FxSaveFormat->DataOffset = 0;
94 // FxSaveFormat->DataSelector = 0;
95 // FxSaveFormat->MXCsr = 0x1F80;
96
97 /* Set an intial NPX State */
98 //Context->FloatSave.Cr0NpxState = 0;
99 //FxSaveArea->Cr0NpxState = 0;
100 //FxSaveArea->NpxSavedCpu = 0;
101
102 /* Now set the context flags depending on XMM support */
103 //ContextFlags |= (KeI386FxsrPresent) ? CONTEXT_EXTENDED_REGISTERS :
104 // CONTEXT_FLOATING_POINT;
105
106 /* Set the Thread's NPX State */
107 Thread->NpxState = 0xA;
108 Thread->DispatcherHeader.NpxIrql = PASSIVE_LEVEL;
109
110 /* Disable any debug regiseters */
111 Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
112
113 /* Setup the Trap Frame */
114 TrapFrame = &InitFrame->TrapFrame;
115
116 /* Set up a trap frame from the context. */
117 KeContextToTrapFrame(Context,
118 NULL,
119 TrapFrame,
120 Context->ContextFlags | ContextFlags,
121 UserMode);
122
123 /* Set SS, DS, ES's RPL Mask properly */
124 TrapFrame->SegSs |= RPL_MASK;
125 TrapFrame->SegDs |= RPL_MASK;
126 TrapFrame->SegEs |= RPL_MASK;
127 TrapFrame->Dr7 = 0;
128
129 /* Set the previous mode as user */
130 TrapFrame->PreviousMode = UserMode;
131
132 /* Terminate the Exception Handler List */
133 TrapFrame->ExceptionFrame = 0;
134
135 /* Setup the Stack for KiThreadStartup and Context Switching */
136 StartFrame = &InitFrame->StartFrame;
137 CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
138
139 /* Tell the thread it will run in User Mode */
140 Thread->PreviousMode = UserMode;
141
142 /* Tell KiThreadStartup of that too */
143 StartFrame->UserThread = TRUE;
144 }
145 else
146 {
147 /* Set up the Initial Frame for the system thread */
148 PKKINIT_FRAME InitFrame;
149 InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
150 sizeof(KKINIT_FRAME));
151
152 /* Setup the Fx Area */
153 //FxSaveArea = &InitFrame->FxSaveArea;
154 //RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA));
155
156 /* Check if we have Fxsr support */
157 DPRINT1("FxsrPresent but did nothing\n");
158 // /* Set the stub FX area */
159 // FxSaveArea->U.FxArea.ControlWord = 0x27F;
160 // FxSaveArea->U.FxArea.MXCsr = 0x1F80;
161
162 /* No NPX State */
163 Thread->NpxState = 0xA;
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 Kernel Mode */
170 Thread->PreviousMode = KernelMode;
171
172 /* Tell KiThreadStartup of that too */
173 StartFrame->UserThread = FALSE;
174 }
175
176 /* Now setup the remaining data for KiThreadStartup */
177 StartFrame->StartContext = StartContext;
178 StartFrame->StartRoutine = StartRoutine;
179 StartFrame->SystemRoutine = SystemRoutine;
180
181 /* And set up the Context Switch Frame */
182 CtxSwitchFrame->RetAddr = KiThreadStartup;
183 CtxSwitchFrame->ApcBypassDisable = TRUE;
184 CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;;
185
186 /* Save back the new value of the kernel stack. */
187 Thread->KernelStack = (PVOID)CtxSwitchFrame;
188
189 }
190
191 /* EOF */
192
193