ReactOS 0.4.17-dev-683-g0dafdc5
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 469 of file thrdini.c.

470{
471 PKIPCR Pcr = (PKIPCR)KeGetPcr();
472 PKPRCB Prcb = &Pcr->PrcbData;
473 PVOID OldHandler;
474 PKTHREAD NewThread, OldThread;
475
476 /* Disable interrupts */
477 _disable();
478
479 /* Check for pending timers, pending DPCs, or pending ready threads */
480 if ((Prcb->DpcData[0].DpcQueueDepth) ||
481 (Prcb->TimerRequest) ||
483 {
484 /* Switch to safe execution context */
485 OldHandler = Pcr->NtTib.ExceptionList;
487
488 /* Retire DPCs while under the DPC stack */
490
491 /* Restore context */
492 Pcr->NtTib.ExceptionList = OldHandler;
493 }
494
495 /* Re-enable interrupts */
496 _enable();
497
498 /* Check for quantum end */
499 if (Prcb->QuantumEnd)
500 {
501 /* Handle quantum end */
502 Prcb->QuantumEnd = FALSE;
503 KiQuantumEnd();
504 }
505 else if (Prcb->NextThread)
506 {
507 /* Acquire the PRCB lock */
508 KiAcquirePrcbLock(Prcb);
509
510 /* Capture current thread data */
511 OldThread = Prcb->CurrentThread;
512 NewThread = Prcb->NextThread;
513
514 /* Set new thread data */
515 Prcb->NextThread = NULL;
516 Prcb->CurrentThread = NewThread;
517
518 /* The thread is now running */
519 NewThread->State = Running;
520 OldThread->WaitReason = WrDispatchInt;
521
522 /* Make the old thread ready */
523 KxQueueReadyThread(OldThread, Prcb);
524
525 /* Swap to the new thread */
526 KiSwapContext(APC_LEVEL, OldThread);
527 }
528}
#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)
FORCEINLINE VOID KiAcquirePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:220
struct _KIPCR * PKIPCR
#define KeGetPcr()
Definition: ketypes.h:81
@ Running
Definition: ketypes.h:409
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
BOOLEAN FASTCALL KiSwapContext(IN KIRQL WaitIrql, IN PKTHREAD CurrentThread)
VOID NTAPI KiQuantumEnd(VOID)
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
volatile ULONG DpcQueueDepth
Definition: ketypes.h:1002
KPRCB PrcbData
Definition: ketypes.h:840
NT_TIB NtTib
Definition: ketypes.h:971
UINT64 TimerRequest
Definition: ketypes.h:795
KDPC_DATA DpcData[2]
Definition: ketypes.h:780
UCHAR QuantumEnd
Definition: ketypes.h:800
struct _KTHREAD * CurrentThread
Definition: ketypes.h:670
struct _KTHREAD * NextThread
Definition: ketypes.h:671
SINGLE_LIST_ENTRY DeferredReadyListHead
Definition: ketypes.h:732
PVOID DpcStack
Definition: ketypes.h:781
UCHAR WaitReason
Definition: ketypes.h:2111
volatile UCHAR State
Definition: ketypes.h:1936
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:711
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:641
@ WrDispatchInt
Definition: ketypes.h:498

◆ 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:1197
VOID FASTCALL KiRetireDpcList(IN PKPRCB Prcb)
Definition: dpc.c:562
#define YieldProcessor
Definition: ke.h:48
PROCESSOR_POWER_STATE PowerState
Definition: ketypes.h:899
PPROCESSOR_IDLE_FUNCTION IdleFunction
Definition: potypes.h:95

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}
#define RPL_MASK
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:38
#define NPX_STATE_NOT_LOADED
Definition: asm.h:265
#define UserMode
Definition: asm.h:39
#define KTRAP_FRAME_LENGTH
Definition: asm.h:316
struct _FXSAVE_FORMAT * PFXSAVE_FORMAT
#define CONTEXT_CONTROL
Definition: nt_native.h:1372
#define CONTEXT_FLOATING_POINT
Definition: nt_native.h:1375
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
_In_ PVOID Context
Definition: storport.h:2269
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
ULONG Cr0NpxState
Definition: ketypes.h:505
FXSAVE_FORMAT FxArea
Definition: ketypes.h:502
union _FX_SAVE_AREA::@2715 U
FX_SAVE_AREA FxSaveArea
Definition: thrdini.c:42
KSWITCH_FRAME CtxSwitchFrame
Definition: thrdini.c:34
KSTART_FRAME StartFrame
Definition: thrdini.c:35
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
ULONG DbgArgMark
Definition: ketypes.h:297
UINT64 Dr7
Definition: ketypes.h:452
USHORT SegEs
Definition: ketypes.h:470
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:314
USHORT SegDs
Definition: ketypes.h:469
KTRAP_FRAME TrapFrame
Definition: thrdini.c:28
KSTART_FRAME StartFrame
Definition: thrdini.c:26
FX_SAVE_AREA FxSaveArea
Definition: thrdini.c:35
KSWITCH_FRAME CtxSwitchFrame
Definition: thrdini.c:25
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:92

◆ 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 422 of file thrdini.c.

424{
425 PKIPCR Pcr = (PKIPCR)KeGetPcr();
426 PKTHREAD OldThread, NewThread;
427 ULONG Cr0, NewCr0;
428
429 /* Save APC bypass disable */
430 SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3;
431 SwitchFrame->ExceptionList = Pcr->NtTib.ExceptionList;
432
433 /* Increase context switch count and check if tracing is enabled */
434 Pcr->ContextSwitches++;
435 if (Pcr->PerfGlobalGroupMask)
436 {
437 /* We don't support this yet on x86 either */
438 DPRINT1("WMI Tracing not supported\n");
439 ASSERT(FALSE);
440 }
441
442 /* Get thread pointers */
443 OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3);
444 NewThread = Pcr->PrcbData.CurrentThread;
445
446 /* Get the old thread and set its kernel stack */
447 OldThread->KernelStack = SwitchFrame;
448
449 /* Set swapbusy to false for the new thread */
450 NewThread->SwapBusy = FALSE;
451
452 /* ISRs can change FPU state, so disable interrupts while checking */
453 _disable();
454
455 /* Get current and new CR0 and check if they've changed */
456 Cr0 = __readcr0();
457 NewCr0 = NewThread->NpxState |
458 (Cr0 & ~(CR0_MP | CR0_EM | CR0_TS)) |
460 if (Cr0 != NewCr0) __writecr0(NewCr0);
461
462 /* Now enable interrupts and do the switch */
463 _enable();
464 KiSwitchThreads(OldThread, NewThread->KernelStack);
465}
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:1836
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1821
#define ASSERT(a)
Definition: mode.c:44
#define CR0_MP
Definition: ketypes.h:140
#define CR0_EM
Definition: ketypes.h:141
#define CR0_TS
Definition: ketypes.h:142
struct _KTHREAD * PKTHREAD
Definition: nt_native.h:28
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:769
ULONG ContextSwitches
Definition: ketypes.h:1006
PVOID PerfGlobalGroupMask
Definition: ketypes.h:808
ULONG64 NpxState
Definition: ketypes.h:2215
PVOID KernelStack
Definition: ketypes.h:1822

◆ 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 ULONG64 CurrentCycleTime, ElapsedCycles, NewCycleTime;
333
334 /* We are on the new thread stack now */
335 NewThread = Pcr->PrcbData.CurrentThread;
336
337 /* Now we are the new thread. Check if it's in a new process */
338 OldProcess = OldThread->ApcState.Process;
339 NewProcess = NewThread->ApcState.Process;
340 if (OldProcess != NewProcess)
341 {
342 /* Check if there is a different LDT */
343 if (*(PULONGLONG)&OldProcess->LdtDescriptor != *(PULONGLONG)&NewProcess->LdtDescriptor)
344 {
345 if (NewProcess->LdtDescriptor.LimitLow)
346 {
348 ((PULONG)&NewProcess->LdtDescriptor)[0],
349 ((PULONG)&NewProcess->LdtDescriptor)[1]);
350 Ke386SetLocalDescriptorTable(KGDT_LDT);
351 }
352 else
353 {
354 Ke386SetLocalDescriptorTable(0);
355 }
356 }
357
358 /* Switch address space and flush TLB */
359 __writecr3(NewProcess->DirectoryTableBase[0]);
360 }
361
362 /* Update the old thread's cycle time */
363 CurrentCycleTime = __rdtsc();
364 ElapsedCycles = CurrentCycleTime - Pcr->PrcbData.StartCycles;
365 NewCycleTime = ((PETHREAD)OldThread)->CycleTime + ElapsedCycles;
366 KiWriteThreadCycleTime(OldThread, NewCycleTime);
367 InterlockedAdd64((PLONG64)&((PEPROCESS)OldProcess)->CycleTime, ElapsedCycles);
368 Pcr->PrcbData.StartCycles = CurrentCycleTime;
369
370 /* Clear GS */
371 Ke386SetGs(0);
372
373 /* Set the TEB */
374 KiSetTebBase((PKPCR)Pcr, &NewThread->Teb->NtTib);
375
376 /* Set new TSS fields */
377 Pcr->TSS->Esp0 = (ULONG_PTR)NewThread->InitialStack;
378 if (!((KeGetTrapFrame(NewThread))->EFlags & EFLAGS_V86_MASK))
379 {
380 Pcr->TSS->Esp0 -= sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, V86Es);
381 }
382 Pcr->TSS->Esp0 -= NPX_FRAME_LENGTH;
383 Pcr->TSS->IoMapBase = NewProcess->IopmOffset;
384
385 /* Increase thread context switches */
386 NewThread->ContextSwitches++;
387
388 /* Load data from switch frame */
389 Pcr->NtTib.ExceptionList = SwitchFrame->ExceptionList;
390
391 /* DPCs shouldn't be active */
392 if (Pcr->PrcbData.DpcRoutineActive)
393 {
394 /* Crash the machine */
395 KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC,
396 (ULONG_PTR)OldThread,
397 (ULONG_PTR)NewThread,
398 (ULONG_PTR)OldThread->InitialStack,
399 0);
400 }
401
402 /* Kernel APCs may be pending */
403 if (NewThread->ApcState.KernelApcPending)
404 {
405 /* Are APCs enabled? */
406 if (!NewThread->SpecialApcDisable)
407 {
408 /* Request APC delivery */
409 if (SwitchFrame->ApcBypassDisable)
411 else
412 return TRUE;
413 }
414 }
415
416 /* Return stating that no kernel APCs are pending*/
417 return FALSE;
418}
__int64 * PLONG64
Definition: basetsd.h:177
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
#define ULONG_PTR
Definition: config.h:101
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
#define InterlockedAdd64
Definition: interlocked.h:72
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1826
FORCEINLINE VOID KiWriteThreadCycleTime(_Inout_ PKTHREAD Thread, _In_ ULONG64 NewCycleTime)
Definition: ke_x.h:1744
VOID KeSetGdtSelector(ULONG Entry, ULONG Value1, ULONG Value2)
Definition: ldt.c:107
if(dx< 0)
Definition: linetemp.h:194
unsigned __int64 ULONG64
Definition: imports.h:198
struct _KTRAP_FRAME KTRAP_FRAME
#define EFLAGS_V86_MASK
Definition: ketypes.h:207
#define NPX_FRAME_LENGTH
Definition: asm.h:247
#define KGDT_LDT
Definition: ketypes.h:131
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:395
#define KeGetTrapFrame(Thread)
Definition: ke.h:218
FORCEINLINE VOID KiSetTebBase(PKPCR Pcr, PNT_TIB TebAddress)
Definition: ke.h:455
struct _KTSS * TSS
Definition: ketypes.h:824
Definition: ke.h:294
UINT64 StartCycles
Definition: ketypes.h:859
UCHAR DpcRoutineActive
Definition: ketypes.h:792
USHORT IopmOffset
Definition: ketypes.h:2243
ULONG_PTR DirectoryTableBase
Definition: ketypes.h:2234
PVOID InitialStack
Definition: ketypes.h:1811
SHORT SpecialApcDisable
Definition: ketypes.h:2028
PVOID Teb
Definition: ketypes.h:1954
ULONG ContextSwitches
Definition: ketypes.h:1935
KAPC_STATE ApcState
Definition: ketypes.h:1925
ULONG CycleTime
Definition: svw_pata.c:43
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:1434
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().