00081 :
00082
00083 This function initializes
the machine dependent context of a thread object.
00084
00085 N.B. This function does not check
the accessibility of
the context record.
00086 It
is assumed
the the caller of
this routine
is either prepared to
00087 handle access violations or has probed and copied
the context record
00088 as appropriate.
00089
00090 Arguments:
00091
00092 Thread - Supplies a pointer to a dispatcher object of
type thread.
00093
00094 SystemRoutine - Supplies a pointer to
the system function that
is to be
00095 called when
the thread
is first scheduled
for execution.
00096
00097 StartRoutine - Supplies an optional pointer to a function that
is to be
00098 called after
the system has finished initializing
the thread. This
00099 parameter
is specified
if the thread
is a system thread and will
00100 execute totally in kernel mode.
00101
00102 StartContext - Supplies an optional pointer to an arbitrary data structure
00103 which will be passed to
the StartRoutine as a parameter. This
00104 parameter
is specified
if the thread
is a system thread and will
00105 execute totally in kernel mode.
00106
00107 ContextFrame - Supplies an optional pointer a context frame which contains
00108
the initial user mode state of
the thread. This parameter
is specified
00109
if the thread
is a user thread and will execute in user mode. If
this
00110 parameter
is not specified, then
the Teb parameter
is ignored.
00111
00112 Return Value:
00113
00114 None.
00115
00116 --*/
00117
00118 {
00119 PFX_SAVE_AREA NpxFrame;
00120 PKSWITCHFRAME SwitchFrame;
00121 PKTRAP_FRAME TrFrame;
00122 PULONG PSystemRoutine;
00123 PULONG PStartRoutine;
00124 PULONG PStartContext;
00125 PULONG PUserContextFlag;
00126 ULONG ContextFlags;
00127 CONTEXT
Context2;
00128 PCONTEXT ContextFrame2 =
NULL;
00129 PFXSAVE_FORMAT PFxSaveArea;
00130
00131
00132
00133
00134
00135
00136
if (ARGUMENT_PRESENT(ContextFrame)) {
00137
00138 RtlMoveMemory(&Context2, ContextFrame,
sizeof(CONTEXT));
00139 ContextFrame2 = &
Context2;
00140 ContextFlags =
CONTEXT_CONTROL;
00141
00142
00143
00144
00145
00146 NpxFrame = (PFX_SAVE_AREA)(((ULONG)(Thread->InitialStack) -
00147
sizeof(FX_SAVE_AREA)));
00148
00149
00150
00151
00152
00153
if (
KeI386XMMIPresent ==
TRUE) {
00154 PFxSaveArea = (PFXSAVE_FORMAT)ContextFrame2->ExtendedRegisters;
00155
00156 PFxSaveArea->ControlWord = 0x27f;
00157 PFxSaveArea->StatusWord = 0;
00158 PFxSaveArea->TagWord = 0;
00159 PFxSaveArea->ErrorOffset = 0;
00160 PFxSaveArea->ErrorSelector = 0;
00161 PFxSaveArea->DataOffset = 0;
00162 PFxSaveArea->DataSelector = 0;
00163 PFxSaveArea->MXCsr = 0x1f80;
00164 }
else {
00165 ContextFrame2->FloatSave.ControlWord = 0x27f;
00166 ContextFrame2->FloatSave.StatusWord = 0;
00167 ContextFrame2->FloatSave.TagWord = 0xffff;
00168 ContextFrame2->FloatSave.ErrorOffset = 0;
00169 ContextFrame2->FloatSave.ErrorSelector = 0;
00170 ContextFrame2->FloatSave.DataOffset = 0;
00171 ContextFrame2->FloatSave.DataSelector = 0;
00172 }
00173
00174
00175
if (
KeI386NpxPresent) {
00176 ContextFrame2->FloatSave.Cr0NpxState = 0;
00177 NpxFrame->Cr0NpxState = 0;
00178 NpxFrame->NpxSavedCpu = 0;
00179
if (
KeI386XMMIPresent ==
TRUE) {
00180 ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
00181 }
else {
00182 ContextFlags |=
CONTEXT_FLOATING_POINT;
00183 }
00184
00185
00186
00187
00188
00189 Thread->NpxState = NPX_STATE_NOT_LOADED;
00190 Thread->NpxIrql =
PASSIVE_LEVEL;
00191
00192 }
else {
00193 NpxFrame->Cr0NpxState = CR0_EM;
00194
00195
00196
00197
00198
00199
00200
00201 Thread->NpxState = NPX_STATE_NOT_LOADED & ~CR0_MP;
00202 }
00203
00204
00205
00206
00207
00208
00209 ContextFrame2->Dr0 = 0;
00210 ContextFrame2->Dr1 = 0;
00211 ContextFrame2->Dr2 = 0;
00212 ContextFrame2->Dr3 = 0;
00213 ContextFrame2->Dr6 = 0;
00214 ContextFrame2->Dr7 = 0;
00215 ContextFrame2->ContextFlags &= ~(CONTEXT_DEBUG_REGISTERS);
00216
#if 0
00217
00218
00219
00220
00221
00222
if (Thread->AutoAlignment ==
FALSE) {
00223 ContextFrame2->EFlags |= EFLAGS_ALIGN_CHECK;
00224 }
00225
#endif
00226
00227
00228
00229 TrFrame = (PKTRAP_FRAME)(((ULONG)NpxFrame - KTRAP_FRAME_LENGTH));
00230
00231
00232
00233
00234
00235 PUserContextFlag = (PULONG)TrFrame - 1;
00236 PStartContext = PUserContextFlag - 1;
00237 PStartRoutine = PStartContext - 1;
00238 PSystemRoutine = PStartRoutine - 1;
00239
00240 SwitchFrame = (PKSWITCHFRAME)((PUCHAR)PSystemRoutine -
00241
sizeof(KSWITCHFRAME));
00242
00243
00244
00245
00246
00247
00248
KeContextToKframes(TrFrame, NULL, ContextFrame2,
00249 ContextFrame2->ContextFlags | ContextFlags,
00250 UserMode);
00251
00252 TrFrame->HardwareSegSs |= RPL_MASK;
00253 TrFrame->SegDs |= RPL_MASK;
00254 TrFrame->SegEs |= RPL_MASK;
00255
00256
#if DBG
00257
TrFrame->DbgArgMark = 0xBADB0D00;
00258
#endif
00259
00260
00261
00262
00263
00264 *PUserContextFlag = 1;
00265
00266
00267
00268
00269
00270
00271 TrFrame->ExceptionList = EXCEPTION_CHAIN_END;
00272
00273
00274
00275
00276
00277 TrFrame->PreviousPreviousMode =
UserMode;
00278
00279
00280
00281
00282
00283 Thread->PreviousMode =
UserMode;
00284
00285
00286 }
else {
00287
00288
00289
00290
00291
00292
00293
00294 NpxFrame = (PFX_SAVE_AREA)(((ULONG)(Thread->InitialStack) -
00295
sizeof(FX_SAVE_AREA)));
00296
00297
00298
00299
00300 RtlZeroMemory((PVOID)NpxFrame,
sizeof(FX_SAVE_AREA));
00301
00302
if (
KeI386FxsrPresent ==
TRUE) {
00303 NpxFrame->U.FxArea.ControlWord = 0x27f;
00304 NpxFrame->U.FxArea.MXCsr = 0x1f80;
00305 }
else {
00306 NpxFrame->U.FnArea.ControlWord = 0x27f;
00307 NpxFrame->U.FnArea.TagWord = 0xffff;
00308 }
00309
00310
00311
00312
00313
00314 Thread->NpxState = NPX_STATE_NOT_LOADED;
00315
00316
00317
00318
00319
00320
00321
00322
00323 PUserContextFlag = (PULONG)((ULONG)NpxFrame) - 1;
00324
00325 PStartContext = PUserContextFlag - 1;
00326 PStartRoutine = PStartContext - 1;
00327 PSystemRoutine = PStartRoutine - 1;
00328
00329 SwitchFrame = (PKSWITCHFRAME)((PUCHAR)PSystemRoutine -
00330
sizeof(KSWITCHFRAME));
00331
00332
00333
00334
00335
00336
00337 *PUserContextFlag = 0;
00338
00339
00340
00341
00342
00343
00344 Thread->PreviousMode =
KernelMode;
00345 }
00346
00347
00348
00349
00350
00351
00352 *PStartContext = (ULONG)StartContext;
00353 *PStartRoutine = (ULONG)StartRoutine;
00354 *PSystemRoutine = (ULONG)SystemRoutine;
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 SwitchFrame->RetAddr = (ULONG)
KiThreadStartup;
00365
00366 SwitchFrame->Eflags = EFLAGS_INTERRUPT_MASK;
00367
00368
#if 0
00369
00370
00371
00372
00373
00374
if (Thread->AutoAlignment ==
FALSE) {
00375 SwitchFrame->Eflags |= EFLAGS_ALIGN_CHECK;
00376 }
00377
#endif
00378
00379 SwitchFrame->ExceptionList = (ULONG)(EXCEPTION_CHAIN_END);
00380
00381
00382
00383
00384
00385
00386
00387
00388 Thread->KernelStack = (PVOID)SwitchFrame;
00389
return;
00390 }