ReactOS  0.4.13-dev-982-g9853eab
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)
 
VOID FASTCALL 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 458 of file thrdini.c.

459 {
460  PKIPCR Pcr = (PKIPCR)KeGetPcr();
461  PKPRCB Prcb = &Pcr->PrcbData;
462  PVOID OldHandler;
463  PKTHREAD NewThread, OldThread;
464 
465  /* Disable interrupts */
466  _disable();
467 
468  /* Check for pending timers, pending DPCs, or pending ready threads */
469  if ((Prcb->DpcData[0].DpcQueueDepth) ||
470  (Prcb->TimerRequest) ||
471  (Prcb->DeferredReadyListHead.Next))
472  {
473  /* Switch to safe execution context */
474  OldHandler = Pcr->NtTib.ExceptionList;
476 
477  /* Retire DPCs while under the DPC stack */
478  KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack);
479 
480  /* Restore context */
481  Pcr->NtTib.ExceptionList = OldHandler;
482  }
483 
484  /* Re-enable interrupts */
485  _enable();
486 
487  /* Check for quantum end */
488  if (Prcb->QuantumEnd)
489  {
490  /* Handle quantum end */
491  Prcb->QuantumEnd = FALSE;
492  KiQuantumEnd();
493  }
494  else if (Prcb->NextThread)
495  {
496  /* Capture current thread data */
497  OldThread = Prcb->CurrentThread;
498  NewThread = Prcb->NextThread;
499 
500  /* Set new thread data */
501  Prcb->NextThread = NULL;
502  Prcb->CurrentThread = NewThread;
503 
504  /* The thread is now running */
505  NewThread->State = Running;
506  OldThread->WaitReason = WrDispatchInt;
507 
508  /* Make the old thread ready */
509  KxQueueReadyThread(OldThread, Prcb);
510 
511  /* Swap to the new thread */
512  KiSwapContext(APC_LEVEL, OldThread);
513  }
514 }
KDPC_DATA DpcData[2]
Definition: ketypes.h:676
void __cdecl _enable(void)
Definition: intrin_arm.h:373
struct _KIPCR * PKIPCR
VOID NTAPI KiQuantumEnd(VOID)
Definition: dpc.c:465
UCHAR QuantumEnd
Definition: ketypes.h:696
struct _KTHREAD * NextThread
Definition: ketypes.h:567
#define KeGetPcr()
Definition: ke.h:25
BOOLEAN FASTCALL KiSwapContext(IN KIRQL WaitIrql, IN PKTHREAD CurrentThread)
FORCEINLINE VOID KxQueueReadyThread(IN PKTHREAD Thread, IN PKPRCB Prcb)
Definition: ke_x.h:1343
VOID FASTCALL KiRetireDpcListInDpcStack(IN PKPRCB Prcb, IN PVOID DpcStack)
struct _KTHREAD * CurrentThread
Definition: ketypes.h:566
smooth NULL
Definition: ftsmooth.c:416
UCHAR WaitReason
Definition: ketypes.h:1854
UINT64 TimerRequest
Definition: ketypes.h:691
KPRCB PrcbData
Definition: ketypes.h:774
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:371
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:636
SINGLE_LIST_ENTRY DeferredReadyListHead
Definition: ketypes.h:628
volatile ULONG DpcQueueDepth
Definition: ketypes.h:746
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
PVOID DpcStack
Definition: ketypes.h:677
volatile UCHAR State
Definition: ketypes.h:1679
void __cdecl _disable(void)
Definition: intrin_arm.h:365
NT_TIB NtTib
Definition: ketypes.h:857
#define APC_LEVEL
Definition: env_spec_w32.h:695

◆ KiIdleLoop()

VOID FASTCALL KiIdleLoop ( VOID  )

Definition at line 271 of file thrdini.c.

272 {
273  PKPRCB Prcb = KeGetCurrentPrcb();
274  PKTHREAD OldThread, NewThread;
275 
276  /* Now loop forever */
277  while (TRUE)
278  {
279  /* Start of the idle loop: disable interrupts */
280  _enable();
281  YieldProcessor();
282  YieldProcessor();
283  _disable();
284 
285  /* Check for pending timers, pending DPCs, or pending ready threads */
286  if ((Prcb->DpcData[0].DpcQueueDepth) ||
287  (Prcb->TimerRequest) ||
288  (Prcb->DeferredReadyListHead.Next))
289  {
290  /* Quiesce the DPC software interrupt */
292 
293  /* Handle it */
294  KiRetireDpcList(Prcb);
295  }
296 
297  /* Check if a new thread is scheduled for execution */
298  if (Prcb->NextThread)
299  {
300  /* Enable interrupts */
301  _enable();
302 
303  /* Capture current thread data */
304  OldThread = Prcb->CurrentThread;
305  NewThread = Prcb->NextThread;
306 
307  /* Set new thread data */
308  Prcb->NextThread = NULL;
309  Prcb->CurrentThread = NewThread;
310 
311  /* The thread is now running */
312  NewThread->State = Running;
313 
314  /* Switch away from the idle thread */
315  KiSwapContext(APC_LEVEL, OldThread);
316  }
317  else
318  {
319  /* Continue staying idle. Note the HAL returns with interrupts on */
320  Prcb->PowerState.IdleFunction(&Prcb->PowerState);
321  }
322  }
323 }
#define TRUE
Definition: types.h:120
KDPC_DATA DpcData[2]
Definition: ketypes.h:676
void __cdecl _enable(void)
Definition: intrin_arm.h:373
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
PROCESSOR_POWER_STATE PowerState
Definition: ketypes.h:795
struct _KTHREAD * NextThread
Definition: ketypes.h:567
BOOLEAN FASTCALL KiSwapContext(IN KIRQL WaitIrql, IN PKTHREAD CurrentThread)
FORCEINLINE VOID YieldProcessor(VOID)
Definition: ke.h:32
struct _KTHREAD * CurrentThread
Definition: ketypes.h:566
smooth NULL
Definition: ftsmooth.c:416
UINT64 TimerRequest
Definition: ketypes.h:691
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:636
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
SINGLE_LIST_ENTRY DeferredReadyListHead
Definition: ketypes.h:628
volatile ULONG DpcQueueDepth
Definition: ketypes.h:746
PPROCESSOR_IDLE_FUNCTION IdleFunction
Definition: potypes.h:68
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:282
volatile UCHAR State
Definition: ketypes.h:1679
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define APC_LEVEL
Definition: env_spec_w32.h:695
VOID FASTCALL KiRetireDpcList(IN PKPRCB Prcb)
Definition: dpc.c:561

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,
122  KTRAP_FRAME_LENGTH + sizeof(FX_SAVE_AREA));
123 
124  /* Setup the Fx Area */
125  FxSaveArea = &InitFrame->FxSaveArea;
126 
127  /* Check if we support FXsr */
128  if (KeI386FxsrPresent)
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  /* Check if the CPU has NPX */
156  if (KeI386NpxPresent)
157  {
158  /* Set an intial NPX State */
159  Context->FloatSave.Cr0NpxState = 0;
160  FxSaveArea->Cr0NpxState = 0;
161  FxSaveArea->NpxSavedCpu = 0;
162 
163  /* Now set the context flags depending on XMM support */
164  ContextFlags |= (KeI386FxsrPresent) ? CONTEXT_EXTENDED_REGISTERS :
166 
167  /* Set the Thread's NPX State */
168  Thread->NpxState = NPX_STATE_NOT_LOADED;
169  Thread->Header.NpxIrql = PASSIVE_LEVEL;
170  }
171  else
172  {
173  /* We'll use emulation */
174  FxSaveArea->Cr0NpxState = CR0_EM;
175  Thread->NpxState = NPX_STATE_NOT_LOADED &~ CR0_MP;
176  }
177 
178  /* Disable any debug registers */
179  Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
180 
181  /* Setup the Trap Frame */
182  TrapFrame = &InitFrame->TrapFrame;
183 
184  /* Set up a trap frame from the context. */
186  NULL,
187  TrapFrame,
188  Context->ContextFlags | ContextFlags,
189  UserMode);
190 
191  /* Set SS, DS, ES's RPL Mask properly */
192  TrapFrame->HardwareSegSs |= RPL_MASK;
193  TrapFrame->SegDs |= RPL_MASK;
194  TrapFrame->SegEs |= RPL_MASK;
195  TrapFrame->Dr7 = 0;
196 
197  /* Set the debug mark */
198  TrapFrame->DbgArgMark = 0xBADB0D00;
199 
200  /* Set the previous mode as user */
201  TrapFrame->PreviousPreviousMode = UserMode;
202 
203  /* Terminate the Exception Handler List */
204  TrapFrame->ExceptionList = EXCEPTION_CHAIN_END;
205 
206  /* Setup the Stack for KiThreadStartup and Context Switching */
207  StartFrame = &InitFrame->StartFrame;
208  CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
209 
210  /* Tell the thread it will run in User Mode */
211  Thread->PreviousMode = UserMode;
212 
213  /* Tell KiThreadStartup of that too */
214  StartFrame->UserThread = TRUE;
215  }
216  else
217  {
218  /* Set up the Initial Frame for the system thread */
219  PKKINIT_FRAME InitFrame;
220  InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
221  sizeof(KKINIT_FRAME));
222 
223  /* Setup the Fx Area */
224  FxSaveArea = &InitFrame->FxSaveArea;
225  RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA));
226 
227  /* Check if we have Fxsr support */
228  if (KeI386FxsrPresent)
229  {
230  /* Set the stub FX area */
231  FxSaveArea->U.FxArea.ControlWord = 0x27F;
232  FxSaveArea->U.FxArea.MXCsr = 0x1F80;
233  }
234  else
235  {
236  /* Set the stub FN area */
237  FxSaveArea->U.FnArea.ControlWord = 0x27F;
238  FxSaveArea->U.FnArea.TagWord = -1;
239  }
240 
241  /* No NPX State */
242  Thread->NpxState = NPX_STATE_NOT_LOADED;
243 
244  /* Setup the Stack for KiThreadStartup and Context Switching */
245  StartFrame = &InitFrame->StartFrame;
246  CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
247 
248  /* Tell the thread it will run in Kernel Mode */
249  Thread->PreviousMode = KernelMode;
250 
251  /* Tell KiThreadStartup of that too */
252  StartFrame->UserThread = FALSE;
253  }
254 
255  /* Now setup the remaining data for KiThreadStartup */
256  StartFrame->StartContext = StartContext;
257  StartFrame->StartRoutine = StartRoutine;
258  StartFrame->SystemRoutine = SystemRoutine;
259 
260  /* And set up the Context Switch Frame */
261  CtxSwitchFrame->RetAddr = KiThreadStartup;
262  CtxSwitchFrame->ApcBypassDisable = TRUE;
263  CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;
264 
265  /* Save back the new value of the kernel stack. */
266  Thread->KernelStack = (PVOID)CtxSwitchFrame;
267 }
#define CR0_MP
Definition: asm.h:246
VOID NTAPI KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame, ULONG ContextFlags, KPROCESSOR_MODE PreviousMode)
KSWITCH_FRAME CtxSwitchFrame
Definition: thrdini.c:18
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ULONG DbgArgMark
Definition: ketypes.h:241
#define CONTEXT_EXTENDED_REGISTERS
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine
Definition: psfuncs.h:87
PKSTART_ROUTINE StartRoutine
Definition: thrdini.c:25
ULONG TagWord
Definition: ketypes.h:415
ULONG MXCsr
Definition: ketypes.h:433
ULONG ErrorSelector
Definition: ketypes.h:430
struct _FXSAVE_FORMAT * PFXSAVE_FORMAT
USHORT ControlWord
Definition: ketypes.h:425
ULONG HardwareSegSs
Definition: ketypes.h:269
ULONG KeI386NpxPresent
Definition: cpu.c:31
#define KTRAP_FRAME_LENGTH
Definition: asm.h:126
PKSYSTEM_ROUTINE SystemRoutine
Definition: thrdini.c:24
BOOLEAN ApcBypassDisable
Definition: thrdini.c:20
USHORT StatusWord
Definition: ketypes.h:426
#define NPX_STATE_NOT_LOADED
Definition: asm.h:262
ULONG KeI386FxsrPresent
Definition: cpu.c:31
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID NTAPI KiThreadStartup(VOID)
Definition: thrdini.c:63
KSTART_FRAME StartFrame
Definition: thrdini.c:19
PVOID RetAddr
Definition: thrdini.c:21
USHORT SegEs
Definition: ketypes.h:365
FX_SAVE_AREA FxSaveArea
Definition: thrdini.c:42
#define RPL_MASK
Definition: ketypes.h:69
smooth NULL
Definition: ftsmooth.c:416
ULONG Cr0NpxState
Definition: ketypes.h:449
USHORT TagWord
Definition: ketypes.h:427
void * PVOID
Definition: retypes.h:9
#define CONTEXT_CONTROL
Definition: compat.h:265
ULONG NpxSavedCpu
Definition: ketypes.h:448
KTRAP_FRAME TrapFrame
Definition: thrdini.c:21
ULONG DataOffset
Definition: ketypes.h:431
struct _KKINIT_FRAME KKINIT_FRAME
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:258
ULONG ControlWord
Definition: ketypes.h:413
union _FX_SAVE_AREA::@2337 U
ULONG DataSelector
Definition: ketypes.h:432
struct _KUINIT_FRAME * PKUINIT_FRAME
USHORT SegDs
Definition: ketypes.h:364
KSTART_FRAME StartFrame
Definition: thrdini.c:28
struct _KUINIT_FRAME KUINIT_FRAME
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
ULONG ErrorOffset
Definition: ketypes.h:429
struct _KKINIT_FRAME * PKKINIT_FRAME
ULONG PreviousPreviousMode
Definition: ketypes.h:257
PVOID StartContext
Definition: thrdini.c:26
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
PVOID ExceptionList
Definition: thrdini.c:19
#define CONTEXT_FLOATING_POINT
Definition: compat.h:267
FNSAVE_FORMAT FnArea
Definition: ketypes.h:445
FX_SAVE_AREA FxSaveArea
Definition: thrdini.c:35
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
UINT64 Dr7
Definition: ketypes.h:347
BOOLEAN UserThread
Definition: thrdini.c:27
FXSAVE_FORMAT FxArea
Definition: ketypes.h:446
#define CONTEXT_DEBUG_REGISTERS
Definition: compat.h:268
KSWITCH_FRAME CtxSwitchFrame
Definition: thrdini.c:27
#define CR0_EM
Definition: asm.h:247

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

416 {
417  PKIPCR Pcr = (PKIPCR)KeGetPcr();
418  PKTHREAD OldThread, NewThread;
419  ULONG Cr0, NewCr0;
420 
421  /* Save APC bypass disable */
422  SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3;
423  SwitchFrame->ExceptionList = Pcr->NtTib.ExceptionList;
424 
425  /* Increase context switch count and check if tracing is enabled */
426  Pcr->ContextSwitches++;
427  if (Pcr->PerfGlobalGroupMask)
428  {
429  /* We don't support this yet on x86 either */
430  DPRINT1("WMI Tracing not supported\n");
431  ASSERT(FALSE);
432  }
433 
434  /* Get thread pointers */
435  OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3);
436  NewThread = Pcr->PrcbData.CurrentThread;
437 
438  /* Get the old thread and set its kernel stack */
439  OldThread->KernelStack = SwitchFrame;
440 
441  /* ISRs can change FPU state, so disable interrupts while checking */
442  _disable();
443 
444  /* Get current and new CR0 and check if they've changed */
445  Cr0 = __readcr0();
446  NewCr0 = NewThread->NpxState |
447  (Cr0 & ~(CR0_MP | CR0_EM | CR0_TS)) |
448  KiGetThreadNpxArea(NewThread)->Cr0NpxState;
449  if (Cr0 != NewCr0) __writecr0(NewCr0);
450 
451  /* Now enable interrupts and do the switch */
452  _enable();
453  KiSwitchThreads(OldThread, NewThread->KernelStack);
454 }
#define CR0_MP
Definition: asm.h:246
void __cdecl _enable(void)
Definition: intrin_arm.h:373
struct _KIPCR * PKIPCR
#define CR0_TS
Definition: asm.h:248
#define KeGetPcr()
Definition: ke.h:25
struct _KTHREAD * PKTHREAD
Definition: nt_native.h:28
struct _KTHREAD * CurrentThread
Definition: ketypes.h:566
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1670
ULONG Cr0NpxState
Definition: ketypes.h:449
PVOID KernelStack
Definition: ketypes.h:1565
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:600
ULONG64 NpxState
Definition: ketypes.h:1958
KPRCB PrcbData
Definition: ketypes.h:774
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:371
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1692
VOID FASTCALL KiSwitchThreads(IN PKTHREAD OldThread, IN PKTHREAD NewThread)
#define DPRINT1
Definition: precomp.h:8
ULONG ContextSwitches
Definition: ketypes.h:892
PVOID PerfGlobalGroupMask
Definition: ketypes.h:742
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
NT_TIB NtTib
Definition: ketypes.h:857
#define CR0_EM
Definition: asm.h:247

◆ KiSwapContextExit()

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

Definition at line 327 of file thrdini.c.

329 {
330  PKIPCR Pcr = (PKIPCR)KeGetPcr();
331  PKPROCESS OldProcess, NewProcess;
332  PKTHREAD NewThread;
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  /* Clear GS */
363  Ke386SetGs(0);
364 
365  /* Set the TEB */
366  KiSetTebBase((PKPCR)Pcr, NewThread->Teb);
367 
368  /* Set new TSS fields */
369  Pcr->TSS->Esp0 = (ULONG_PTR)NewThread->InitialStack;
370  if (!((KeGetTrapFrame(NewThread))->EFlags & EFLAGS_V86_MASK))
371  {
372  Pcr->TSS->Esp0 -= (FIELD_OFFSET(KTRAP_FRAME, V86Gs) - FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs));
373  }
374  Pcr->TSS->Esp0 -= NPX_FRAME_LENGTH;
375  Pcr->TSS->IoMapBase = NewProcess->IopmOffset;
376 
377  /* Increase thread context switches */
378  NewThread->ContextSwitches++;
379 
380  /* Load data from switch frame */
381  Pcr->NtTib.ExceptionList = SwitchFrame->ExceptionList;
382 
383  /* DPCs shouldn't be active */
384  if (Pcr->PrcbData.DpcRoutineActive)
385  {
386  /* Crash the machine */
387  KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC,
388  (ULONG_PTR)OldThread,
389  (ULONG_PTR)NewThread,
390  (ULONG_PTR)OldThread->InitialStack,
391  0);
392  }
393 
394  /* Kernel APCs may be pending */
395  if (NewThread->ApcState.KernelApcPending)
396  {
397  /* Are APCs enabled? */
398  if (!NewThread->SpecialApcDisable)
399  {
400  /* Request APC delivery */
401  if (SwitchFrame->ApcBypassDisable)
403  else
404  return TRUE;
405  }
406  }
407 
408  /* Return stating that no kernel APCs are pending*/
409  return FALSE;
410 }
#define TRUE
Definition: types.h:120
ULONG_PTR DirectoryTableBase
Definition: ketypes.h:1977
SHORT SpecialApcDisable
Definition: ketypes.h:1771
#define NPX_FRAME_LENGTH
Definition: asm.h:244
USHORT IopmOffset
Definition: ketypes.h:1986
struct _KIPCR * PKIPCR
Definition: ke.h:280
#define KeGetPcr()
Definition: ke.h:25
#define EFLAGS_V86_MASK
Definition: ketypes.h:129
uint32_t ULONG_PTR
Definition: typedefs.h:63
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1675
#define KGDT_LDT
Definition: ketypes.h:81
VOID KeSetGdtSelector(ULONG Entry, ULONG Value1, ULONG Value2)
Definition: ldt.c:107
KAPC_STATE ApcState
Definition: ketypes.h:1668
struct _KTHREAD * CurrentThread
Definition: ketypes.h:566
struct _KTSS * TSS
Definition: ketypes.h:758
if(!(yy_init))
Definition: macro.lex.yy.c:714
KPRCB PrcbData
Definition: ketypes.h:774
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:371
UCHAR DpcRoutineActive
Definition: ketypes.h:688
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
PVOID Teb
Definition: ketypes.h:1697
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
ULONG ContextSwitches
Definition: ketypes.h:1678
FORCEINLINE VOID KiSetTebBase(PKPCR Pcr, PVOID TebAddress)
Definition: ke.h:318
#define ULONG_PTR
Definition: config.h:101
NT_TIB NtTib
Definition: ketypes.h:857
PVOID InitialStack
Definition: ketypes.h:1554
#define KeGetTrapFrame(Thread)
Definition: ke.h:145
#define APC_LEVEL
Definition: env_spec_w32.h:695
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:107

◆ 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 }
PKSTART_ROUTINE StartRoutine
Definition: thrdini.c:25
PKSYSTEM_ROUTINE SystemRoutine
Definition: thrdini.c:24
KSTART_FRAME StartFrame
Definition: thrdini.c:19
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1507
KTRAP_FRAME TrapFrame
Definition: thrdini.c:21
VOID FASTCALL KfLowerIrql(IN KIRQL NewIrql)
Definition: pic.c:232
PVOID StartContext
Definition: thrdini.c:26
#define KiServiceExit2
Definition: ke.h:5
#define KeGetCurrentThread
Definition: hal.h:44
BOOLEAN UserThread
Definition: thrdini.c:27
#define APC_LEVEL
Definition: env_spec_w32.h:695

Referenced by GspGetRegisters(), and KiInitializeContextThread().