ReactOS  0.4.13-dev-651-g5dbc677
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  _KUINIT_FRAME
 
struct  _KKINIT_FRAME
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _KSWITCHFRAME KSWITCHFRAME
 
typedef struct _KSWITCHFRAMEPKSWITCHFRAME
 
typedef struct _KUINIT_FRAME KUINIT_FRAME
 
typedef struct _KUINIT_FRAMEPKUINIT_FRAME
 
typedef struct _KKINIT_FRAME KKINIT_FRAME
 
typedef struct _KKINIT_FRAMEPKKINIT_FRAME
 

Functions

VOID NTAPI KiThreadStartup (VOID)
 
VOID FASTCALL KiSwitchThreads (IN PKTHREAD OldThread, IN PKTHREAD NewThread)
 
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

◆ KSWITCHFRAME

◆ KUINIT_FRAME

◆ PKKINIT_FRAME

◆ PKSWITCHFRAME

◆ PKUINIT_FRAME

Function Documentation

◆ KiDispatchInterrupt()

VOID NTAPI KiDispatchInterrupt ( VOID  )

Definition at line 295 of file thrdini.c.

296 {
297  PKIPCR Pcr = (PKIPCR)KeGetPcr();
298  PKPRCB Prcb = &Pcr->Prcb;
299  PKTHREAD NewThread, OldThread;
300 
301  /* Disable interrupts */
302  _disable();
303 
304  /* Check for pending timers, pending DPCs, or pending ready threads */
305  if ((Prcb->DpcData[0].DpcQueueDepth) ||
306  (Prcb->TimerRequest) ||
307  (Prcb->DeferredReadyListHead.Next))
308  {
309  /* Retire DPCs while under the DPC stack */
310  //KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack);
311  // FIXME!!! //
312  KiRetireDpcList(Prcb);
313  }
314 
315  /* Re-enable interrupts */
316  _enable();
317 
318  /* Check for quantum end */
319  if (Prcb->QuantumEnd)
320  {
321  /* Handle quantum end */
322  Prcb->QuantumEnd = FALSE;
323  KiQuantumEnd();
324  }
325  else if (Prcb->NextThread)
326  {
327  /* Capture current thread data */
328  OldThread = Prcb->CurrentThread;
329  NewThread = Prcb->NextThread;
330 
331  /* Set new thread data */
332  Prcb->NextThread = NULL;
333  Prcb->CurrentThread = NewThread;
334 
335  /* The thread is now running */
336  NewThread->State = Running;
337  OldThread->WaitReason = WrDispatchInt;
338 
339  /* Make the old thread ready */
340  KxQueueReadyThread(OldThread, Prcb);
341 
342  /* Swap to the new thread */
343  KiSwapContext(APC_LEVEL, OldThread);
344  }
345 }
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
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
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:636
KPRCB Prcb
Definition: ketypes.h:889
SINGLE_LIST_ENTRY DeferredReadyListHead
Definition: ketypes.h:628
volatile ULONG DpcQueueDepth
Definition: ketypes.h:746
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 _HalpDispatchInterruptHandler(), HalpDispatchInterruptHandler(), HalpLowerIrql(), and KiInitializePcr().

◆ KiIdleLoop()

VOID FASTCALL KiIdleLoop ( VOID  )

Definition at line 153 of file thrdini.c.

154 {
155  PKPRCB Prcb = KeGetCurrentPrcb();
156  PKTHREAD OldThread, NewThread;
157 
158  /* Now loop forever */
159  while (TRUE)
160  {
161  /* Start of the idle loop: disable interrupts */
162  _enable();
163  YieldProcessor();
164  YieldProcessor();
165  _disable();
166 
167  /* Check for pending timers, pending DPCs, or pending ready threads */
168  if ((Prcb->DpcData[0].DpcQueueDepth) ||
169  (Prcb->TimerRequest) ||
170  (Prcb->DeferredReadyListHead.Next))
171  {
172  /* Quiesce the DPC software interrupt */
174 
175  /* Handle it */
176  KiRetireDpcList(Prcb);
177  }
178 
179  /* Check if a new thread is scheduled for execution */
180  if (Prcb->NextThread)
181  {
182  /* Enable interrupts */
183  _enable();
184 
185  /* Capture current thread data */
186  OldThread = Prcb->CurrentThread;
187  NewThread = Prcb->NextThread;
188 
189  /* Set new thread data */
190  Prcb->NextThread = NULL;
191  Prcb->CurrentThread = NewThread;
192 
193  /* The thread is now running */
194  NewThread->State = Running;
195 
196  /* Switch away from the idle thread */
197  KiSwapContext(APC_LEVEL, OldThread);
198  }
199  else
200  {
201  /* Continue staying idle. Note the HAL returns with interrupts on */
202  Prcb->PowerState.IdleFunction(&Prcb->PowerState);
203  }
204  }
205 }
#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

◆ KiInitializeContextThread()

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

Definition at line 53 of file thrdini.c.

58 {
59  PKTRAP_FRAME TrapFrame;
60  PKEXCEPTION_FRAME ExceptionFrame = NULL, CtxSwitchFrame;
61 
62  //
63  // Check if this is a user thread
64  //
65  if (ContextPointer)
66  {
67  //
68  // Setup the initial frame
69  //
70  PKUINIT_FRAME InitFrame;
71  InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
72  sizeof(KUINIT_FRAME));
73 
74  //
75  // Setup the Trap Frame and Exception frame
76  //
77  TrapFrame = &InitFrame->TrapFrame;
78  ExceptionFrame = &InitFrame->ExceptionFrame;
79 
81  // Zero out the trap frame and exception frame
82  //
83  RtlZeroMemory(TrapFrame, sizeof(KTRAP_FRAME));
84  RtlZeroMemory(ExceptionFrame, sizeof(KEXCEPTION_FRAME));
85 
86  //
87  // Set up a trap frame from the context
88  //
89  KeContextToTrapFrame(ContextPointer,
90  ExceptionFrame,
91  TrapFrame,
92  ContextPointer->ContextFlags | CONTEXT_CONTROL,
93  UserMode);
94 
95  //
96  // Set the previous mode as user
97  //
98  //TrapFrame->PreviousMode = UserMode;
99  Thread->PreviousMode = UserMode;
100 
101  //
102  // Clear the return address
103  //
104  ExceptionFrame->Return = 0;
105 
106  //
107  // Context switch frame to setup below
108  //
109  CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
110  }
111  else
112  {
113  //
114  // Set up the Initial Frame for the system thread
115  //
116  PKKINIT_FRAME InitFrame;
117  InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
118  sizeof(KKINIT_FRAME));
119 
120  //
121  // Set the previous mode as kernel
122  //
123  Thread->PreviousMode = KernelMode;
124 
125  //
126  // Context switch frame to setup below
127  //
128  CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
129  }
130 
131  //
132  // Now setup the context switch frame
133  //
134  CtxSwitchFrame->Return = (ULONG)KiThreadStartup;
135  CtxSwitchFrame->R11 = (ULONG)(ExceptionFrame ? ExceptionFrame : CtxSwitchFrame);
136 
137  //
138  // Set the parameters
139  //
140  CtxSwitchFrame->R4 = (ULONG)ContextPointer;
141  CtxSwitchFrame->R5 = (ULONG)StartContext;
142  CtxSwitchFrame->R6 = (ULONG)StartRoutine;
143  CtxSwitchFrame->R7 = (ULONG)SystemRoutine;
144 
145  //
146  // Save back the new value of the kernel stack
147  //
148  Thread->KernelStack = (PVOID)CtxSwitchFrame;
149 }
VOID NTAPI KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame, ULONG ContextFlags, KPROCESSOR_MODE PreviousMode)
KSWITCH_FRAME CtxSwitchFrame
Definition: thrdini.c:18
KEXCEPTION_FRAME ExceptionFrame
Definition: thrdini.c:20
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine
Definition: psfuncs.h:87
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID NTAPI KiThreadStartup(VOID)
Definition: thrdini.c:63
ULONG64 Return
Definition: ketypes.h:966
ULONG64 Return
Definition: ketypes.h:1035
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
#define CONTEXT_CONTROL
Definition: compat.h:265
KTRAP_FRAME TrapFrame
Definition: thrdini.c:21
struct _KKINIT_FRAME KKINIT_FRAME
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
struct _KUINIT_FRAME * PKUINIT_FRAME
struct _KUINIT_FRAME KUINIT_FRAME
struct _KKINIT_FRAME * PKKINIT_FRAME
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
KSWITCH_FRAME CtxSwitchFrame
Definition: thrdini.c:27

◆ KiSwapContextEntry()

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

Definition at line 262 of file thrdini.c.

264 {
265  PKIPCR Pcr = (PKIPCR)KeGetPcr();
266  PKTHREAD OldThread, NewThread;
267 
268  /* Save APC bypass disable */
269  SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3;
270 
271  /* Increase context switch count and check if tracing is enabled */
272  Pcr->Prcb.KeContextSwitches++;
273 #if 0
274  if (Pcr->PerfGlobalGroupMask)
275  {
276  /* We don't support this yet on x86 either */
277  DPRINT1("WMI Tracing not supported\n");
278  ASSERT(FALSE);
279  }
280 #endif // 0
281 
282  /* Get thread pointers */
283  OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3);
284  NewThread = Pcr->Prcb.CurrentThread;
285 
286  /* Get the old thread and set its kernel stack */
287  OldThread->KernelStack = SwitchFrame;
288 
289  /* Do the switch */
290  KiSwitchThreads(OldThread, NewThread->KernelStack);
291 }
struct _KIPCR * PKIPCR
#define KeGetPcr()
Definition: ke.h:25
struct _KTHREAD * PKTHREAD
Definition: nt_native.h:28
struct _KTHREAD * CurrentThread
Definition: ketypes.h:566
PVOID KernelStack
Definition: ketypes.h:1565
ULONG KeContextSwitches
Definition: ketypes.h:648
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
KPRCB Prcb
Definition: ketypes.h:889
VOID FASTCALL KiSwitchThreads(IN PKTHREAD OldThread, IN PKTHREAD NewThread)
#define DPRINT1
Definition: precomp.h:8
PVOID PerfGlobalGroupMask
Definition: ketypes.h:742

◆ KiSwapContextExit()

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

Definition at line 209 of file thrdini.c.

211 {
212  PKIPCR Pcr = (PKIPCR)KeGetPcr();
213  PKPROCESS OldProcess, NewProcess;
214  PKTHREAD NewThread;
215  ARM_TTB_REGISTER TtbRegister;
216 
217  /* We are on the new thread stack now */
218  NewThread = Pcr->Prcb.CurrentThread;
219 
220  /* Now we are the new thread. Check if it's in a new process */
221  OldProcess = OldThread->ApcState.Process;
222  NewProcess = NewThread->ApcState.Process;
223  if (OldProcess != NewProcess)
224  {
225  TtbRegister.AsUlong = NewProcess->DirectoryTableBase[0];
226  ASSERT(TtbRegister.Reserved == 0);
228  }
229 
230  /* Increase thread context switches */
231  NewThread->ContextSwitches++;
232 
233  /* DPCs shouldn't be active */
234  if (Pcr->Prcb.DpcRoutineActive)
235  {
236  /* Crash the machine */
237  KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC,
238  (ULONG_PTR)OldThread,
239  (ULONG_PTR)NewThread,
240  (ULONG_PTR)OldThread->InitialStack,
241  0);
242  }
243 
244  /* Kernel APCs may be pending */
245  if (NewThread->ApcState.KernelApcPending)
246  {
247  /* Are APCs enabled? */
248  if (!NewThread->SpecialApcDisable)
249  {
250  /* Request APC delivery */
251  if (SwitchFrame->ApcBypassDisable) HalRequestSoftwareInterrupt(APC_LEVEL);
252  return TRUE;
253  }
254  }
255 
256  /* Return */
257  return FALSE;
258 }
#define TRUE
Definition: types.h:120
ULONG_PTR DirectoryTableBase
Definition: ketypes.h:1977
SHORT SpecialApcDisable
Definition: ketypes.h:1771
struct _KIPCR * PKIPCR
#define KeGetPcr()
Definition: ke.h:25
uint32_t ULONG_PTR
Definition: typedefs.h:63
KAPC_STATE ApcState
Definition: ketypes.h:1668
struct _KTHREAD * CurrentThread
Definition: ketypes.h:566
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
UCHAR DpcRoutineActive
Definition: ketypes.h:688
KPRCB Prcb
Definition: ketypes.h:889
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
ULONG ContextSwitches
Definition: ketypes.h:1678
#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
FORCEINLINE VOID KeArmTranslationTableRegisterSet(IN ARM_TTB_REGISTER Ttb)
Definition: intrin_i.h:145

◆ KiSwitchThreads()

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

Referenced by KiSwapContextEntry().

◆ 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 KiInitializeContextThread().