ReactOS  r74406
krnlinit.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ke/krnlinit.c
5  * PURPOSE: Portable part of kernel initialization
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 #include <internal/napi.h>
15 
16 /* GLOBALS *******************************************************************/
17 
18 /* Portable CPU Features and Flags */
24 
25 /* System call count */
27 
28 /* ARC Loader Block */
30 
31 /* PRCB Array */
33 
34 /* Number of processors */
36 
37 /* NUMA Node Support */
42 
43 /* Initial Process and Thread */
46 
47 /* System-defined Spinlocks */
65 
66 /* FUNCTIONS *****************************************************************/
67 
68 VOID
69 NTAPI
72 {
73  ULONG i;
74 
75  /* Initialize Bugcheck Callback data */
79 
80  /* Initialize the Timer Expiration DPC */
83 
84  /* Initialize Profiling data */
88 
89  /* Loop the timer table */
90  for (i = 0; i < TIMER_TABLE_SIZE; i++)
91  {
92  /* Initialize the list and entries */
94  KiTimerTableListHead[i].Time.HighPart = 0xFFFFFFFF;
96  }
97 
98  /* Initialize the Swap event and all swap lists */
103 
104  /* Initialize the mutex for generic DPC calls */
106 
107  /* Initialize the syscall table */
113 
114  /* Copy the the current table into the shadow table for win32k */
117  sizeof(KeServiceDescriptorTable));
118 }
119 
121 NTAPI
124  OUT PUCHAR Shift)
125 {
126  LARGE_INTEGER Reciprocal = {{0, 0}};
127  LONG BitCount = 0, Remainder = 1;
128 
129  /* Start by calculating the remainder */
130  while (Reciprocal.HighPart >= 0)
131  {
132  /* Increase the loop (bit) count */
133  BitCount++;
134 
135  /* Calculate the current fraction */
136  Reciprocal.HighPart = (Reciprocal.HighPart << 1) |
137  (Reciprocal.LowPart >> 31);
138  Reciprocal.LowPart <<= 1;
139 
140  /* Double the remainder and see if we went past the divisor */
141  Remainder <<= 1;
142  if (Remainder >= Divisor)
143  {
144  /* Set the low-bit and calculate the new remainder */
145  Remainder -= Divisor;
146  Reciprocal.LowPart |= 1;
147  }
148  }
149 
150  /* Check if we have a remainder */
151  if (Remainder)
152  {
153  /* Check if the current fraction value is too large */
154  if ((Reciprocal.LowPart == 0xFFFFFFFF) &&
155  (Reciprocal.HighPart == (LONG)0xFFFFFFFF))
156  {
157  /* Set the high bit and reduce the bit count */
158  Reciprocal.LowPart = 0;
159  Reciprocal.HighPart = 0x80000000;
160  BitCount--;
161  }
162  else
163  {
164  /* Check if only the lowest bits got too large */
165  if (Reciprocal.LowPart == 0xFFFFFFFF)
166  {
167  /* Reset them and increase the high bits instead */
168  Reciprocal.LowPart = 0;
169  Reciprocal.HighPart++;
170  }
171  else
172  {
173  /* All is well, increase the low bits */
174  Reciprocal.LowPart++;
175  }
176  }
177  }
178 
179  /* Now calculate the actual shift and return the reciprocal */
180  *Shift = (UCHAR)BitCount - 64;
181  return Reciprocal;
182 }
183 
184 VOID
185 NTAPI
188  IN CCHAR Number)
189 {
190  ULONG i;
191 
192  /* Initialize Dispatcher Fields */
193  Prcb->QueueIndex = 1;
194  Prcb->ReadySummary = 0;
195  Prcb->DeferredReadyListHead.Next = NULL;
196  for (i = 0; i < MAXIMUM_PRIORITY; i++)
197  {
198  /* Initialize the ready list */
199  InitializeListHead(&Prcb->DispatcherReadyListHead[i]);
200  }
201 
202  /* Initialize DPC Fields */
203  InitializeListHead(&Prcb->DpcData[DPC_NORMAL].DpcListHead);
204  KeInitializeSpinLock(&Prcb->DpcData[DPC_NORMAL].DpcLock);
205  Prcb->DpcData[DPC_NORMAL].DpcQueueDepth = 0;
206  Prcb->DpcData[DPC_NORMAL].DpcCount = 0;
207  Prcb->DpcRoutineActive = FALSE;
208  Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
209  Prcb->MinimumDpcRate = KiMinimumDpcRate;
210  Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
211  KeInitializeDpc(&Prcb->CallDpc, NULL, NULL);
212  KeSetTargetProcessorDpc(&Prcb->CallDpc, Number);
213  KeSetImportanceDpc(&Prcb->CallDpc, HighImportance);
214 
215  /* Initialize the Wait List Head */
216  InitializeListHead(&Prcb->WaitListHead);
217 
218  /* Initialize Queued Spinlocks */
219  Prcb->LockQueue[LockQueueDispatcherLock].Next = NULL;
220  Prcb->LockQueue[LockQueueDispatcherLock].Lock = &KiDispatcherLock;
221  Prcb->LockQueue[LockQueueExpansionLock].Next = NULL;
222  Prcb->LockQueue[LockQueueExpansionLock].Lock = NULL;
223  Prcb->LockQueue[LockQueuePfnLock].Next = NULL;
224  Prcb->LockQueue[LockQueuePfnLock].Lock = &MmPfnLock;
225  Prcb->LockQueue[LockQueueSystemSpaceLock].Next = NULL;
226  Prcb->LockQueue[LockQueueSystemSpaceLock].Lock = &MmSystemSpaceLock;
227  Prcb->LockQueue[LockQueueBcbLock].Next = NULL;
228  Prcb->LockQueue[LockQueueBcbLock].Lock = &CcBcbSpinLock;
229  Prcb->LockQueue[LockQueueMasterLock].Next = NULL;
230  Prcb->LockQueue[LockQueueMasterLock].Lock = &CcMasterSpinLock;
231  Prcb->LockQueue[LockQueueVacbLock].Next = NULL;
232  Prcb->LockQueue[LockQueueVacbLock].Lock = &CcVacbSpinLock;
233  Prcb->LockQueue[LockQueueWorkQueueLock].Next = NULL;
234  Prcb->LockQueue[LockQueueWorkQueueLock].Lock = &CcWorkQueueSpinLock;
235  Prcb->LockQueue[LockQueueNonPagedPoolLock].Next = NULL;
236  Prcb->LockQueue[LockQueueNonPagedPoolLock].Lock = &NonPagedPoolLock;
237  Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Next = NULL;
238  Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Lock = &MmNonPagedPoolLock;
239  Prcb->LockQueue[LockQueueIoCancelLock].Next = NULL;
240  Prcb->LockQueue[LockQueueIoCancelLock].Lock = &IopCancelSpinLock;
241  Prcb->LockQueue[LockQueueIoVpbLock].Next = NULL;
242  Prcb->LockQueue[LockQueueIoVpbLock].Lock = &IopVpbSpinLock;
243  Prcb->LockQueue[LockQueueIoDatabaseLock].Next = NULL;
244  Prcb->LockQueue[LockQueueIoDatabaseLock].Lock = &IopDatabaseLock;
245  Prcb->LockQueue[LockQueueIoCompletionLock].Next = NULL;
246  Prcb->LockQueue[LockQueueIoCompletionLock].Lock = &IopCompletionLock;
247  Prcb->LockQueue[LockQueueNtfsStructLock].Next = NULL;
248  Prcb->LockQueue[LockQueueNtfsStructLock].Lock = &NtfsStructLock;
249  Prcb->LockQueue[LockQueueAfdWorkQueueLock].Next = NULL;
250  Prcb->LockQueue[LockQueueAfdWorkQueueLock].Lock = &AfdWorkQueueSpinLock;
251  Prcb->LockQueue[LockQueueUnusedSpare16].Next = NULL;
252  Prcb->LockQueue[LockQueueUnusedSpare16].Lock = NULL;
253 
254  /* Loop timer locks */
255  for (i = 0; i < LOCK_QUEUE_TIMER_TABLE_LOCKS; i++)
256  {
257  /* Initialize the lock and setup the Queued Spinlock */
259  Prcb->LockQueue[LockQueueTimerTableLock + i].Next = NULL;
260  Prcb->LockQueue[LockQueueTimerTableLock + i].Lock =
262  }
263 
264  /* Initialize the PRCB lock */
265  KeInitializeSpinLock(&Prcb->PrcbLock);
266 
267  /* Check if this is the boot CPU */
268  if (!Number)
269  {
270  /* Initialize the lock themselves */
287  }
288 }
289 
290 BOOLEAN
291 NTAPI
294 {
295  /* Check if Threaded DPCs are enabled */
296  if (KeThreadDpcEnable)
297  {
298  /* FIXME: TODO */
299  DPRINT1("Threaded DPCs not yet supported\n");
300  }
301 
302  /* Initialize non-portable parts of the kernel */
304  return TRUE;
305 }
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
VOID NTAPI KiInitMachineDependent(VOID)
Definition: kiinit.c:47
KSPIN_LOCK CcVacbSpinLock
Definition: krnlinit.c:53
#define IN
Definition: typedefs.h:39
VOID NTAPI INIT_FUNCTION KiInitSystem(VOID)
Definition: krnlinit.c:71
VOID NTAPI INIT_FUNCTION KiInitSpinLocks(IN PKPRCB Prcb, IN CCHAR Number)
Definition: krnlinit.c:187
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
KSPIN_LOCK KiProfileLock
Definition: profobj.c:20
KNODE KiNode0
Definition: krnlinit.c:38
KDPC KiTimerExpireDpc
Definition: dpc.c:25
BOOLEAN NTAPI INIT_FUNCTION KeInitSystem(VOID)
Definition: krnlinit.c:293
#define DPC_NORMAL
ETHREAD KiInitialThread
Definition: krnlinit.c:44
unsigned char * PUCHAR
Definition: retypes.h:3
PKNODE KeNodeBlock[1]
Definition: krnlinit.c:39
KSPIN_LOCK MmPfnLock
Definition: krnlinit.c:49
#define TRUE
Definition: numbers.c:17
VOID NTAPI KeSetImportanceDpc(IN PKDPC Dpc, IN KDPC_IMPORTANCE Importance)
Definition: dpc.c:957
ULONG_PTR MainSSDT[]
Definition: napi.h:9
$ULONG LowPart
Definition: ntbasedef.h:568
ULONG KiAdjustDpcThreshold
Definition: dpc.c:21
KSPIN_LOCK NtfsStructLock
Definition: krnlinit.c:61
KSPIN_LOCK CcWorkQueueSpinLock
Definition: krnlinit.c:54
KSPIN_LOCK IopCancelSpinLock
Definition: krnlinit.c:57
#define LOCK_QUEUE_TIMER_TABLE_LOCKS
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
FAST_MUTEX KiGenericCallDpcMutex
Definition: dpc.c:24
LIST_ENTRY KiProfileListHead
Definition: profobj.c:18
GLenum GLclampf GLint i
Definition: glfuncs.h:14
KSPIN_LOCK IopVpbSpinLock
Definition: krnlinit.c:58
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
VOID NTAPI KiTimerExpiration(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:79
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES]
Definition: procobj.c:24
ULONG KeFeatureBits
Definition: krnlinit.c:22
smooth NULL
Definition: ftsmooth.c:464
KSPIN_LOCK AfdWorkQueueSpinLock
Definition: krnlinit.c:62
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
ULARGE_INTEGER Time
Definition: ketypes.h:667
unsigned char BOOLEAN
#define TIMER_TABLE_SIZE
Definition: ketypes.h:821
$ULONG HighPart
Definition: ntbasedef.h:569
PKPRCB KiProcessorBlock[MAXIMUM_PROCESSORS]
Definition: krnlinit.c:32
EPROCESS KiInitialProcess
Definition: krnlinit.c:45
KSPIN_LOCK KiReverseStallIpiLock
Definition: krnlinit.c:64
char CCHAR
Definition: typedefs.h:51
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
ULONG KiServiceLimit
Definition: krnlinit.c:26
ULONG KiMinimumDpcRate
Definition: dpc.c:20
USHORT KeProcessorRevision
Definition: krnlinit.c:21
LARGE_INTEGER NTAPI INIT_FUNCTION KiComputeReciprocal(IN LONG Divisor, OUT PUCHAR Shift)
Definition: krnlinit.c:123
LIST_ENTRY KeBugcheckCallbackListHead
Definition: bug.c:21
#define LONG
Definition: msvc.h:36
USHORT KeProcessorArchitecture
Definition: krnlinit.c:19
KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE]
Definition: timerobj.c:17
unsigned char UCHAR
Definition: xmlstorage.h:181
KSPIN_LOCK KiTimerTableLock[16]
Definition: krnlinit.c:63
#define NUMBER_OF_SYSCALLS
Definition: napi.h:20
BOOLEAN KeThreadDpcEnable
Definition: dpc.c:23
ULONG LowPart
Definition: typedefs.h:105
KEVENT KiSwapEvent
Definition: procobj.c:21
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
LIST_ENTRY KiProfileSourceListHead
Definition: profobj.c:19
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
KSPIN_LOCK KiDispatcherLock
Definition: krnlinit.c:48
ULONG KiMaximumDpcQueueDepth
Definition: dpc.c:19
KSPIN_LOCK MmNonPagedPoolLock
Definition: krnlinit.c:56
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
unsigned short USHORT
Definition: pedump.c:61
ULONG_PTR KAFFINITY
Definition: compat.h:75
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LIST_ENTRY KeBugcheckReasonCallbackListHead
Definition: bug.c:22
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
UCHAR KeNumberNodes
Definition: krnlinit.c:40
_In_ ULONG Shift
Definition: rtlfuncs.h:2683
KSPIN_LOCK CcBcbSpinLock
Definition: krnlinit.c:51
KSPIN_LOCK MmSystemSpaceLock
Definition: krnlinit.c:50
#define DPRINT1
Definition: precomp.h:8
UCHAR MainSSPT[]
Definition: napi.h:15
VOID NTAPI KeSetTargetProcessorDpc(IN PKDPC Dpc, IN CCHAR Number)
Definition: dpc.c:970
#define OUT
Definition: typedefs.h:40
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES]
Definition: procobj.c:23
#define FALSE
Definition: numbers.c:16
KSPIN_LOCK IopCompletionLock
Definition: krnlinit.c:60
_In_ LARGE_INTEGER Divisor
Definition: rtlfuncs.h:3046
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY KiStackInSwapListHead
Definition: procobj.c:20
LIST_ENTRY KiProcessInSwapListHead
Definition: procobj.c:19
LIST_ENTRY KiProcessOutSwapListHead
Definition: procobj.c:19
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
KSPIN_LOCK CcMasterSpinLock
Definition: krnlinit.c:52
USHORT KeProcessorLevel
Definition: krnlinit.c:20
KSPIN_LOCK NonPagedPoolLock
Definition: krnlinit.c:55
base of all file and directory entries
Definition: entries.h:82
KSPIN_LOCK BugCheckCallbackLock
Definition: bug.c:23
KSPIN_LOCK IopDatabaseLock
Definition: krnlinit.c:59
#define MAXIMUM_PRIORITY
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3046
#define INIT_FUNCTION
Definition: ntoskrnl.h:11
UCHAR KeProcessNodeSeed
Definition: krnlinit.c:41