ReactOS 0.4.15-dev-7994-gb388cb6
thrdini.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for thrdini.c:

Go to the source code of this file.

Classes

struct  _KSWITCHFRAME
 
struct  _KSTART_FRAME
 
struct  _KUINIT_FRAME
 
struct  _KKINIT_FRAME
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _KSWITCHFRAME KSWITCHFRAME
 
typedef struct _KSWITCHFRAMEPKSWITCHFRAME
 
typedef struct _KSTART_FRAME KSTART_FRAME
 
typedef struct _KSTART_FRAMEPKSTART_FRAME
 
typedef struct _KUINIT_FRAME KUINIT_FRAME
 
typedef struct _KUINIT_FRAMEPKUINIT_FRAME
 
typedef struct _KKINIT_FRAME KKINIT_FRAME
 
typedef struct _KKINIT_FRAMEPKKINIT_FRAME
 

Functions

VOID FASTCALL KiSwitchThreads (IN PKTHREAD OldThread, IN PKTHREAD NewThread)
 
VOID FASTCALL KiRetireDpcListInDpcStack (IN PKPRCB Prcb, IN PVOID DpcStack)
 
VOID NTAPI KiThreadStartup (VOID)
 
VOID NTAPI KiInitializeContextThread (IN PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, IN PCONTEXT ContextPointer)
 
DECLSPEC_NORETURN VOID KiIdleLoop (VOID)
 
BOOLEAN FASTCALL KiSwapContextExit (IN PKTHREAD OldThread, IN PKSWITCHFRAME SwitchFrame)
 
VOID FASTCALL KiSwapContextEntry (IN PKSWITCHFRAME SwitchFrame, IN ULONG_PTR OldThreadAndApcFlag)
 
VOID NTAPI KiDispatchInterrupt (VOID)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file thrdini.c.

Typedef Documentation

◆ KKINIT_FRAME

◆ KSTART_FRAME

◆ KSWITCHFRAME

◆ KUINIT_FRAME

◆ PKKINIT_FRAME

◆ PKSTART_FRAME

◆ PKSWITCHFRAME

◆ PKUINIT_FRAME

Function Documentation

◆ KiDispatchInterrupt()

VOID NTAPI KiDispatchInterrupt ( VOID  )

Definition at line 460 of file thrdini.c.

461{
462 PKIPCR Pcr = (PKIPCR)KeGetPcr();
463 PKPRCB Prcb = &Pcr->PrcbData;
464 PVOID OldHandler;
465 PKTHREAD NewThread, OldThread;
466
467 /* Disable interrupts */
468 _disable();
469
470 /* Check for pending timers, pending DPCs, or pending ready threads */
471 if ((Prcb->DpcData[0].DpcQueueDepth) ||
472 (Prcb->TimerRequest) ||
474 {
475 /* Switch to safe execution context */
476 OldHandler = Pcr->NtTib.ExceptionList;
478
479 /* Retire DPCs while under the DPC stack */
481
482 /* Restore context */
483 Pcr->NtTib.ExceptionList = OldHandler;
484 }
485
486 /* Re-enable interrupts */
487 _enable();
488
489 /* Check for quantum end */
490 if (Prcb->QuantumEnd)
491 {
492 /* Handle quantum end */
493 Prcb->QuantumEnd = FALSE;
494 KiQuantumEnd();
495 }
496 else if (Prcb->NextThread)
497 {
498 /* Acquire the PRCB lock */
499 KiAcquirePrcbLock(Prcb);
500
501 /* Capture current thread data */
502 OldThread = Prcb->CurrentThread;
503 NewThread = Prcb->NextThread;
504
505 /* Set new thread data */
506 Prcb->NextThread = NULL;
507 Prcb->CurrentThread = NewThread;
508
509 /* The thread is now running */
510 NewThread->State = Running;
511 OldThread->WaitReason = WrDispatchInt;
512
513 /* Make the old thread ready */
514 KxQueueReadyThread(OldThread, Prcb);
515
516 /* Swap to the new thread */
517 KiSwapContext(APC_LEVEL, OldThread);
518 }
519}
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define APC_LEVEL
Definition: env_spec_w32.h:695
VOID FASTCALL KiRetireDpcListInDpcStack(IN PKPRCB Prcb, IN PVOID DpcStack)
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
FORCEINLINE VOID KiAcquirePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:220
struct _KIPCR * PKIPCR
#define KeGetPcr()
Definition: ketypes.h:81
@ Running
Definition: ketypes.h:390
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
BOOLEAN FASTCALL KiSwapContext(IN KIRQL WaitIrql, IN PKTHREAD CurrentThread)
VOID NTAPI KiQuantumEnd(VOID)
volatile ULONG DpcQueueDepth
Definition: ketypes.h:858
KPRCB PrcbData
Definition: ketypes.h:830
NT_TIB NtTib
Definition: ketypes.h:944
UCHAR QuantumEnd
Definition: ketypes.h:780
KDPC_DATA DpcData[2]
Definition: ketypes.h:760
struct _KTHREAD * CurrentThread
Definition: ketypes.h:650
struct _KTHREAD * NextThread
Definition: ketypes.h:651
UINT64 TimerRequest
Definition: ketypes.h:775
SINGLE_LIST_ENTRY DeferredReadyListHead
Definition: ketypes.h:712
PVOID DpcStack
Definition: ketypes.h:761
UCHAR WaitReason
Definition: ketypes.h:1964
volatile UCHAR State
Definition: ketypes.h:1789
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:711
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
@ WrDispatchInt
Definition: ketypes.h:446

◆ KiIdleLoop()

DECLSPEC_NORETURN VOID KiIdleLoop ( VOID  )

Definition at line 260 of file thrdini.c.

261{
262 PKPRCB Prcb = KeGetCurrentPrcb();
263 PKTHREAD OldThread, NewThread;
264
265 /* Now loop forever */
266 while (TRUE)
267 {
268 /* Start of the idle loop: disable interrupts */
269 _enable();
272 _disable();
273
274 /* Check for pending timers, pending DPCs, or pending ready threads */
275 if ((Prcb->DpcData[0].DpcQueueDepth) ||
276 (Prcb->TimerRequest) ||
278 {
279 /* Quiesce the DPC software interrupt */
281
282 /* Handle it */
283 KiRetireDpcList(Prcb);
284 }
285
286 /* Check if a new thread is scheduled for execution */
287 if (Prcb->NextThread)
288 {
289 /* Enable interrupts */
290 _enable();
291
292 /* Capture current thread data */
293 OldThread = Prcb->CurrentThread;
294 NewThread = Prcb->NextThread;
295
296 /* Set new thread data */
297 Prcb->NextThread = NULL;
298 Prcb->CurrentThread = NewThread;
299
300 /* The thread is now running */
301 NewThread->State = Running;
302
303#ifdef CONFIG_SMP
304 /* Do the swap at SYNCH_LEVEL */
306#endif
307
308 /* Switch away from the idle thread */
309 KiSwapContext(APC_LEVEL, OldThread);
310
311#ifdef CONFIG_SMP
312 /* Go back to DISPATCH_LEVEL */
314#endif
315 }
316 else
317 {
318 /* Continue staying idle. Note the HAL returns with interrupts on */
319 Prcb->PowerState.IdleFunction(&Prcb->PowerState);
320 }
321 }
322}
#define TRUE
Definition: types.h:120
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:282
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1161
VOID FASTCALL KiRetireDpcList(IN PKPRCB Prcb)
Definition: dpc.c:562
#define YieldProcessor
Definition: ke.h:48
PROCESSOR_POWER_STATE PowerState
Definition: ketypes.h:879
PPROCESSOR_IDLE_FUNCTION IdleFunction
Definition: potypes.h:68

Referenced by KiInitializeSystem(), and KiSystemStartupBootStack().

◆ KiInitializeContextThread()

VOID NTAPI KiInitializeContextThread ( IN PKTHREAD  Thread,
IN PKSYSTEM_ROUTINE  SystemRoutine,
IN PKSTART_ROUTINE  StartRoutine,
IN PVOID  StartContext,
IN PCONTEXT  ContextPointer 
)

Definition at line 92 of file thrdini.c.

97{
98 PFX_SAVE_AREA FxSaveArea;
99 PFXSAVE_FORMAT FxSaveFormat;
100 PKSTART_FRAME StartFrame;
101 PKSWITCHFRAME CtxSwitchFrame;
102 PKTRAP_FRAME TrapFrame;
103 CONTEXT LocalContext;
105 ULONG ContextFlags;
106
107 /* Check if this is a With-Context Thread */
108 if (ContextPointer)
109 {
110 /* Set up the Initial Frame */
111 PKUINIT_FRAME InitFrame;
112 InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
113 sizeof(KUINIT_FRAME));
114
115 /* Copy over the context we got */
116 RtlCopyMemory(&LocalContext, ContextPointer, sizeof(CONTEXT));
117 Context = &LocalContext;
118 ContextFlags = CONTEXT_CONTROL;
119
120 /* Zero out the trap frame and save area */
121 RtlZeroMemory(&InitFrame->TrapFrame,
123
124 /* Setup the Fx Area */
125 FxSaveArea = &InitFrame->FxSaveArea;
126
127 /* Check if we support FXsr */
129 {
130 /* Get the FX Save Format Area */
131 FxSaveFormat = (PFXSAVE_FORMAT)Context->ExtendedRegisters;
132
133 /* Set an initial state */
134 FxSaveFormat->ControlWord = 0x27F;
135 FxSaveFormat->StatusWord = 0;
136 FxSaveFormat->TagWord = 0;
137 FxSaveFormat->ErrorOffset = 0;
138 FxSaveFormat->ErrorSelector = 0;
139 FxSaveFormat->DataOffset = 0;
140 FxSaveFormat->DataSelector = 0;
141 FxSaveFormat->MXCsr = 0x1F80;
142 }
143 else
144 {
145 /* Setup the regular save area */
146 Context->FloatSave.ControlWord = 0x27F;
147 Context->FloatSave.StatusWord = 0;
148 Context->FloatSave.TagWord = -1;
149 Context->FloatSave.ErrorOffset = 0;
150 Context->FloatSave.ErrorSelector = 0;
151 Context->FloatSave.DataOffset =0;
152 Context->FloatSave.DataSelector = 0;
153 }
154
155 /* Set an intial NPX State */
156 Context->FloatSave.Cr0NpxState = 0;
157 FxSaveArea->Cr0NpxState = 0;
158 FxSaveArea->NpxSavedCpu = 0;
159
160 /* Now set the context flags depending on XMM support */
162
163 /* Set the Thread's NPX State */
164 Thread->NpxState = NPX_STATE_NOT_LOADED;
165 Thread->Header.NpxIrql = PASSIVE_LEVEL;
166
167 /* Disable any debug registers */
168 Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
169
170 /* Setup the Trap Frame */
171 TrapFrame = &InitFrame->TrapFrame;
172
173 /* Set up a trap frame from the context. */
175 NULL,
176 TrapFrame,
177 Context->ContextFlags | ContextFlags,
178 UserMode);
179
180 /* Set SS, DS, ES's RPL Mask properly */
181 TrapFrame->HardwareSegSs |= RPL_MASK;
182 TrapFrame->SegDs |= RPL_MASK;
183 TrapFrame->SegEs |= RPL_MASK;
184 TrapFrame->Dr7 = 0;
185
186 /* Set the debug mark */
187 TrapFrame->DbgArgMark = 0xBADB0D00;
188
189 /* Set the previous mode as user */
190 TrapFrame->PreviousPreviousMode = UserMode;
191
192 /* Terminate the Exception Handler List */
194
195 /* Setup the Stack for KiThreadStartup and Context Switching */
196 StartFrame = &InitFrame->StartFrame;
197 CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
198
199 /* Tell the thread it will run in User Mode */
200 Thread->PreviousMode = UserMode;
201
202 /* Tell KiThreadStartup of that too */
203 StartFrame->UserThread = TRUE;
204 }
205 else
206 {
207 /* Set up the Initial Frame for the system thread */
208 PKKINIT_FRAME InitFrame;
209 InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
210 sizeof(KKINIT_FRAME));
211
212 /* Setup the Fx Area */
213 FxSaveArea = &InitFrame->FxSaveArea;
214 RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA));
215
216 /* Check if we have Fxsr support */
218 {
219 /* Set the stub FX area */
220 FxSaveArea->U.FxArea.ControlWord = 0x27F;
221 FxSaveArea->U.FxArea.MXCsr = 0x1F80;
222 }
223 else
224 {
225 /* Set the stub FN area */
226 FxSaveArea->U.FnArea.ControlWord = 0x27F;
227 FxSaveArea->U.FnArea.TagWord = -1;
228 }
229
230 /* No NPX State */
231 Thread->NpxState = NPX_STATE_NOT_LOADED;
232
233 /* Setup the Stack for KiThreadStartup and Context Switching */
234 StartFrame = &InitFrame->StartFrame;
235 CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
236
237 /* Tell the thread it will run in Kernel Mode */
238 Thread->PreviousMode = KernelMode;
239
240 /* Tell KiThreadStartup of that too */
241 StartFrame->UserThread = FALSE;
242 }
243
244 /* Now setup the remaining data for KiThreadStartup */
245 StartFrame->StartContext = StartContext;
246 StartFrame->StartRoutine = StartRoutine;
247 StartFrame->SystemRoutine = SystemRoutine;
248
249 /* And set up the Context Switch Frame */
250 CtxSwitchFrame->RetAddr = KiThreadStartup;
251 CtxSwitchFrame->ApcBypassDisable = TRUE;
252 CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;
253
254 /* Save back the new value of the kernel stack. */
255 Thread->KernelStack = (PVOID)CtxSwitchFrame;
256}
struct _KUINIT_FRAME * PKUINIT_FRAME
struct _KKINIT_FRAME * PKKINIT_FRAME
struct _KKINIT_FRAME KKINIT_FRAME
struct _KUINIT_FRAME KUINIT_FRAME
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
__in PVOID ContextPointer
Definition: handleapi.cpp:679
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
#define KTRAP_FRAME_LENGTH
Definition: asm.h:126
#define RPL_MASK
Definition: ketypes.h:130
#define NPX_STATE_NOT_LOADED
Definition: asm.h:265
struct _FXSAVE_FORMAT * PFXSAVE_FORMAT
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
#define CONTEXT_FLOATING_POINT
Definition: nt_native.h:1372
ULONG KeI386FxsrPresent
Definition: cpu.c:33
VOID NTAPI KiThreadStartup(VOID)
Definition: thrdini.c:63
VOID NTAPI KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame, ULONG ContextFlags, KPROCESSOR_MODE PreviousMode)
#define CONTEXT_EXTENDED_REGISTERS
ULONG TagWord
Definition: ketypes.h:471
ULONG ControlWord
Definition: ketypes.h:469
ULONG DataSelector
Definition: ketypes.h:488
ULONG ErrorOffset
Definition: ketypes.h:485
ULONG MXCsr
Definition: ketypes.h:489
USHORT ControlWord
Definition: ketypes.h:481
USHORT TagWord
Definition: ketypes.h:483
ULONG DataOffset
Definition: ketypes.h:487
USHORT StatusWord
Definition: ketypes.h:482
ULONG ErrorSelector
Definition: ketypes.h:486
FNSAVE_FORMAT FnArea
Definition: ketypes.h:501
ULONG NpxSavedCpu
Definition: ketypes.h:504
union _FX_SAVE_AREA::@2455 U
ULONG Cr0NpxState
Definition: ketypes.h:505
FXSAVE_FORMAT FxArea
Definition: ketypes.h:502
FX_SAVE_AREA FxSaveArea
Definition: thrdini.c:42
KSWITCH_FRAME CtxSwitchFrame
Definition: thrdini.c:31
KSTART_FRAME StartFrame
Definition: thrdini.c:32
PKSYSTEM_ROUTINE SystemRoutine
Definition: thrdini.c:24
PVOID StartContext
Definition: thrdini.c:26
PKSTART_ROUTINE StartRoutine
Definition: thrdini.c:25
BOOLEAN UserThread
Definition: thrdini.c:27
PVOID ExceptionList
Definition: thrdini.c:19
BOOLEAN ApcBypassDisable
Definition: thrdini.c:20
PVOID RetAddr
Definition: thrdini.c:21
ULONG HardwareSegSs
Definition: ketypes.h:325
ULONG PreviousPreviousMode
Definition: ketypes.h:313
UINT64 Dr7
Definition: ketypes.h:432
ULONG DbgArgMark
Definition: ketypes.h:297
USHORT SegEs
Definition: ketypes.h:450
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:314
USHORT SegDs
Definition: ketypes.h:449
KTRAP_FRAME TrapFrame
Definition: thrdini.c:25
KSTART_FRAME StartFrame
Definition: thrdini.c:23
FX_SAVE_AREA FxSaveArea
Definition: thrdini.c:35
KSWITCH_FRAME CtxSwitchFrame
Definition: thrdini.c:22
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine
Definition: psfuncs.h:91

◆ KiRetireDpcListInDpcStack()

VOID FASTCALL KiRetireDpcListInDpcStack ( IN PKPRCB  Prcb,
IN PVOID  DpcStack 
)

Referenced by KiDispatchInterrupt().

◆ KiSwapContextEntry()

VOID FASTCALL KiSwapContextEntry ( IN PKSWITCHFRAME  SwitchFrame,
IN ULONG_PTR  OldThreadAndApcFlag 
)

Definition at line 413 of file thrdini.c.

415{
416 PKIPCR Pcr = (PKIPCR)KeGetPcr();
417 PKTHREAD OldThread, NewThread;
418 ULONG Cr0, NewCr0;
419
420 /* Save APC bypass disable */
421 SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3;
422 SwitchFrame->ExceptionList = Pcr->NtTib.ExceptionList;
423
424 /* Increase context switch count and check if tracing is enabled */
425 Pcr->ContextSwitches++;
426 if (Pcr->PerfGlobalGroupMask)
427 {
428 /* We don't support this yet on x86 either */
429 DPRINT1("WMI Tracing not supported\n");
430 ASSERT(FALSE);
431 }
432
433 /* Get thread pointers */
434 OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3);
435 NewThread = Pcr->PrcbData.CurrentThread;
436
437 /* Get the old thread and set its kernel stack */
438 OldThread->KernelStack = SwitchFrame;
439
440 /* Set swapbusy to false for the new thread */
441 NewThread->SwapBusy = FALSE;
442
443 /* ISRs can change FPU state, so disable interrupts while checking */
444 _disable();
445
446 /* Get current and new CR0 and check if they've changed */
447 Cr0 = __readcr0();
448 NewCr0 = NewThread->NpxState |
449 (Cr0 & ~(CR0_MP | CR0_EM | CR0_TS)) |
451 if (Cr0 != NewCr0) __writecr0(NewCr0);
452
453 /* Now enable interrupts and do the switch */
454 _enable();
455 KiSwitchThreads(OldThread, NewThread->KernelStack);
456}
VOID FASTCALL KiSwitchThreads(IN PKTHREAD OldThread, IN PKTHREAD NewThread)
#define DPRINT1
Definition: precomp.h:8
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1804
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1789
#define ASSERT(a)
Definition: mode.c:44
#define CR0_MP
Definition: asm.h:246
#define CR0_EM
Definition: asm.h:247
#define CR0_TS
Definition: asm.h:248
struct _KTHREAD * PKTHREAD
Definition: nt_native.h:28
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:712
ULONG ContextSwitches
Definition: ketypes.h:979
PVOID PerfGlobalGroupMask
Definition: ketypes.h:798
ULONG64 NpxState
Definition: ketypes.h:2068
PVOID KernelStack
Definition: ketypes.h:1675

◆ KiSwapContextExit()

BOOLEAN FASTCALL KiSwapContextExit ( IN PKTHREAD  OldThread,
IN PKSWITCHFRAME  SwitchFrame 
)

Definition at line 326 of file thrdini.c.

328{
329 PKIPCR Pcr = (PKIPCR)KeGetPcr();
330 PKPROCESS OldProcess, NewProcess;
331 PKTHREAD NewThread;
332
333 /* We are on the new thread stack now */
334 NewThread = Pcr->PrcbData.CurrentThread;
335
336 /* Now we are the new thread. Check if it's in a new process */
337 OldProcess = OldThread->ApcState.Process;
338 NewProcess = NewThread->ApcState.Process;
339 if (OldProcess != NewProcess)
340 {
341 /* Check if there is a different LDT */
342 if (*(PULONGLONG)&OldProcess->LdtDescriptor != *(PULONGLONG)&NewProcess->LdtDescriptor)
343 {
344 if (NewProcess->LdtDescriptor.LimitLow)
345 {
347 ((PULONG)&NewProcess->LdtDescriptor)[0],
348 ((PULONG)&NewProcess->LdtDescriptor)[1]);
349 Ke386SetLocalDescriptorTable(KGDT_LDT);
350 }
351 else
352 {
353 Ke386SetLocalDescriptorTable(0);
354 }
355 }
356
357 /* Switch address space and flush TLB */
358 __writecr3(NewProcess->DirectoryTableBase[0]);
359 }
360
361 /* Clear GS */
362 Ke386SetGs(0);
363
364 /* Set the TEB */
365 KiSetTebBase((PKPCR)Pcr, &NewThread->Teb->NtTib);
366
367 /* Set new TSS fields */
368 Pcr->TSS->Esp0 = (ULONG_PTR)NewThread->InitialStack;
369 if (!((KeGetTrapFrame(NewThread))->EFlags & EFLAGS_V86_MASK))
370 {
371 Pcr->TSS->Esp0 -= sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, V86Es);
372 }
373 Pcr->TSS->Esp0 -= NPX_FRAME_LENGTH;
374 Pcr->TSS->IoMapBase = NewProcess->IopmOffset;
375
376 /* Increase thread context switches */
377 NewThread->ContextSwitches++;
378
379 /* Load data from switch frame */
380 Pcr->NtTib.ExceptionList = SwitchFrame->ExceptionList;
381
382 /* DPCs shouldn't be active */
383 if (Pcr->PrcbData.DpcRoutineActive)
384 {
385 /* Crash the machine */
386 KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC,
387 (ULONG_PTR)OldThread,
388 (ULONG_PTR)NewThread,
389 (ULONG_PTR)OldThread->InitialStack,
390 0);
391 }
392
393 /* Kernel APCs may be pending */
394 if (NewThread->ApcState.KernelApcPending)
395 {
396 /* Are APCs enabled? */
397 if (!NewThread->SpecialApcDisable)
398 {
399 /* Request APC delivery */
400 if (SwitchFrame->ApcBypassDisable)
402 else
403 return TRUE;
404 }
405 }
406
407 /* Return stating that no kernel APCs are pending*/
408 return FALSE;
409}
#define ULONG_PTR
Definition: config.h:101
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1794
VOID KeSetGdtSelector(ULONG Entry, ULONG Value1, ULONG Value2)
Definition: ldt.c:107
if(dx< 0)
Definition: linetemp.h:194
struct _KTRAP_FRAME KTRAP_FRAME
#define EFLAGS_V86_MASK
Definition: ketypes.h:193
#define NPX_FRAME_LENGTH
Definition: asm.h:247
#define KGDT_LDT
Definition: ketypes.h:131
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
#define KeGetTrapFrame(Thread)
Definition: ke.h:208
FORCEINLINE VOID KiSetTebBase(PKPCR Pcr, PNT_TIB TebAddress)
Definition: ke.h:424
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
struct _KTSS * TSS
Definition: ketypes.h:814
Definition: ke.h:294
UCHAR DpcRoutineActive
Definition: ketypes.h:772
USHORT IopmOffset
Definition: ketypes.h:2096
ULONG_PTR DirectoryTableBase
Definition: ketypes.h:2087
PVOID InitialStack
Definition: ketypes.h:1664
SHORT SpecialApcDisable
Definition: ketypes.h:1881
PVOID Teb
Definition: ketypes.h:1807
ULONG ContextSwitches
Definition: ketypes.h:1788
KAPC_STATE ApcState
Definition: ketypes.h:1778
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

◆ KiSwitchThreads()

VOID FASTCALL KiSwitchThreads ( IN PKTHREAD  OldThread,
IN PKTHREAD  NewThread 
)

◆ KiThreadStartup()

VOID NTAPI KiThreadStartup ( VOID  )

Definition at line 63 of file thrdini.c.

64{
65 PKTRAP_FRAME TrapFrame;
66 PKSTART_FRAME StartFrame;
67 PKUINIT_FRAME InitFrame;
68
69 /* Get the start and trap frames */
70 InitFrame = KeGetCurrentThread()->KernelStack;
71 StartFrame = &InitFrame->StartFrame;
72 TrapFrame = &InitFrame->TrapFrame;
73
74 /* Lower to APC level */
76
77 /* Call the system routine */
78 StartFrame->SystemRoutine(StartFrame->StartRoutine, StartFrame->StartContext);
79
80 /* If we returned, we better be a user thread */
81 if (!StartFrame->UserThread)
82 {
83 KeBugCheck(NO_USER_MODE_CONTEXT);
84 }
85
86 /* Exit to user-mode */
87 KiServiceExit2(TrapFrame);
88}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1430
VOID FASTCALL KfLowerIrql(IN KIRQL NewIrql)
Definition: pic.c:232
#define KeGetCurrentThread
Definition: hal.h:55
#define KiServiceExit2
Definition: ke.h:5

Referenced by KiInitializeContextThread().