ReactOS 0.4.15-dev-6694-g4ba8af9
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/amd64/krnlinit.c
5 * PURPOSE: Portable part of kernel initialization
6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
7 * Alex Ionescu (alex.ionescu@reactos.org)
8 */
9
10/* INCLUDES ******************************************************************/
11
12#include <ntoskrnl.h>
13#define NDEBUG
14#include <debug.h>
15
16extern ULONG_PTR MainSSDT[];
17extern UCHAR MainSSPT[];
18
20
21/* FUNCTIONS *****************************************************************/
22
23CODE_SEG("INIT")
24VOID
27 IN PKTHREAD InitThread,
28 IN PVOID IdleStack,
29 IN PKPRCB Prcb,
30 IN PLOADER_PARAMETER_BLOCK LoaderBlock);
31
32
33CODE_SEG("INIT")
34VOID
36 IN PKPRCB Prcb)
37{
38 if (Prcb->FeatureBits & KF_RDTSC)
39 {
40 ULONG Sample = 0;
41 CPU_INFO CpuInfo;
42 KI_SAMPLE_MAP Samples[10];
43 PKI_SAMPLE_MAP CurrentSample = Samples;
44
45 /* Start sampling loop */
46 for (;;)
47 {
48 /* Do a dummy CPUID to start the sample */
49 KiCpuId(&CpuInfo, 0);
50
51 /* Fill out the starting data */
53 CurrentSample->TSCStart = __rdtsc();
54 CurrentSample->PerfFreq.QuadPart = -50000;
55
56 /* Sleep for this sample */
57 KeStallExecutionProcessor(CurrentSample->PerfFreq.QuadPart * -1 / 10);
58
59 /* Do another dummy CPUID */
60 KiCpuId(&CpuInfo, 0);
61
62 /* Fill out the ending data */
63 CurrentSample->PerfEnd =
64 KeQueryPerformanceCounter(&CurrentSample->PerfFreq);
65 CurrentSample->TSCEnd = __rdtsc();
66
67 /* Calculate the differences */
68 CurrentSample->PerfDelta = CurrentSample->PerfEnd.QuadPart -
69 CurrentSample->PerfStart.QuadPart;
70 CurrentSample->TSCDelta = CurrentSample->TSCEnd -
71 CurrentSample->TSCStart;
72
73 /* Compute CPU Speed */
74 CurrentSample->MHz = (ULONG)((CurrentSample->TSCDelta *
75 CurrentSample->
76 PerfFreq.QuadPart + 500000) /
77 (CurrentSample->PerfDelta *
78 1000000));
79
80 /* Check if this isn't the first sample */
81 if (Sample)
82 {
83 /* Check if we got a good precision within 1MHz */
84 if ((CurrentSample->MHz == CurrentSample[-1].MHz) ||
85 (CurrentSample->MHz == CurrentSample[-1].MHz + 1) ||
86 (CurrentSample->MHz == CurrentSample[-1].MHz - 1))
87 {
88 /* We did, stop sampling */
89 break;
90 }
91 }
92
93 /* Move on */
94 CurrentSample++;
95 Sample++;
96
97 if (Sample == RTL_NUMBER_OF(Samples))
98 {
99 /* No luck. Average the samples and be done */
100 ULONG TotalMHz = 0;
101 while (Sample--)
102 {
103 TotalMHz += Samples[Sample].MHz;
104 }
105 CurrentSample[-1].MHz = TotalMHz / RTL_NUMBER_OF(Samples);
106 DPRINT1("Sampling CPU frequency failed. Using average of %lu MHz\n", CurrentSample[-1].MHz);
107 break;
108 }
109 }
110
111 /* Save the CPU Speed */
112 Prcb->MHz = CurrentSample[-1].MHz;
113 }
114}
115
116VOID
117NTAPI
121 IN PVOID Stack)
122{
123 PKPRCB Prcb = KeGetCurrentPrcb();
124
125 /* Setup the Thread */
127
128 Thread->NextProcessor = Prcb->Number;
129 Thread->Priority = HIGH_PRIORITY;
130 Thread->State = Running;
131 Thread->Affinity = (ULONG_PTR)1 << Prcb->Number;
132 Thread->WaitIrql = DISPATCH_LEVEL;
133 Process->ActiveProcessors |= (ULONG_PTR)1 << Prcb->Number;
134
135}
136
137CODE_SEG("INIT")
139VOID
140NTAPI
142{
143 PLOADER_PARAMETER_BLOCK LoaderBlock = KeLoaderBlock; // hack
144 PKPRCB Prcb = KeGetCurrentPrcb();
146 PKPROCESS Process = Thread->ApcState.Process;
147 PVOID KernelStack = (PVOID)KeLoaderBlock->KernelStack;
148
149 /* Initialize the Power Management Support for this PRCB */
150 PoInitializePrcb(Prcb);
151
152 /* Save CPU state */
154
155 /* Get cache line information for this CPU */
157
158 /* Initialize spinlocks and DPC data */
159 KiInitSpinLocks(Prcb, Prcb->Number);
160
161 /* Set up the thread-related fields in the PRCB */
162 Prcb->CurrentThread = Thread;
163 Prcb->NextThread = NULL;
164 Prcb->IdleThread = Thread;
165
166 /* Initialize PRCB pool lookaside pointers */
168
169 /* Lower to APC_LEVEL */
171
172 /* Check if this is the boot cpu */
173 if (Prcb->Number == 0)
174 {
175 /* Initialize the kernel */
176 KiInitializeKernel(Process, Thread, KernelStack, Prcb, LoaderBlock);
177 }
178 else
179 {
180 /* Initialize the startup thread */
182
183 /* Initialize cpu with HAL */
184 if (!HalInitSystem(0, LoaderBlock))
185 {
186 /* Initialization failed */
187 KeBugCheck(HAL_INITIALIZATION_FAILED);
188 }
189 }
190
191 /* Calculate the CPU frequency */
193
194 /* Raise to Dispatch */
196
197 /* Set the Idle Priority to 0. This will jump into Phase 1 */
199
200 /* If there's no thread scheduled, put this CPU in the Idle summary */
201 KiAcquirePrcbLock(Prcb);
202 if (!Prcb->NextThread) KiIdleSummary |= (ULONG_PTR)1 << Prcb->Number;
203 KiReleasePrcbLock(Prcb);
204
205 /* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
207 LoaderBlock->Prcb = 0;
208
209 /* Set the priority of this thread to 0 */
211 Thread->Priority = 0;
212
213 /* Force interrupts enabled and lower IRQL back to DISPATCH_LEVEL */
214 _enable();
216
217 /* Set the right wait IRQL */
218 Thread->WaitIrql = DISPATCH_LEVEL;
219
220 /* Jump into the idle loop */
221 KiIdleLoop();
222}
223
224CODE_SEG("INIT")
225VOID
226NTAPI
228 IN PKTHREAD InitThread,
229 IN PVOID IdleStack,
230 IN PKPRCB Prcb,
231 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
232{
233 ULONG_PTR PageDirectory[2];
234 PVOID DpcStack;
235 ULONG i;
236
237 /* Set Node Data */
238 KeNodeBlock[0] = &KiNode0;
239 Prcb->ParentNode = KeNodeBlock[0];
240 KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
241
242 /* Set boot-level flags */
243 KeFeatureBits = Prcb->FeatureBits;
244
245 /* Initialize 8/16 bit SList support */
247
248 /* Set the current MP Master KPRCB to the Boot PRCB */
249 Prcb->MultiThreadSetMaster = Prcb;
250
251 /* Initialize Bugcheck Callback data */
255
256 /* Initialize the Timer Expiration DPC */
259
260 /* Initialize Profiling data */
264
265 /* Loop the timer table */
266 for (i = 0; i < TIMER_TABLE_SIZE; i++)
267 {
268 /* Initialize the list and entries */
270 KiTimerTableListHead[i].Time.HighPart = 0xFFFFFFFF;
272 }
273
274 /* Initialize the Swap event and all swap lists */
279
280 /* Initialize the mutex for generic DPC calls */
282
283 /* Initialize the syscall table */
289
290 /* Copy the the current table into the shadow table for win32k */
294
295 /* Initialize the Idle Process and the Process Listhead */
297 PageDirectory[0] = 0;
298 PageDirectory[1] = 0;
299 KeInitializeProcess(InitProcess,
300 0,
301 0xFFFFFFFF,
302 PageDirectory,
303 FALSE);
304 InitProcess->QuantumReset = MAXCHAR;
305
306 /* Initialize the startup thread */
307 KiInitializeHandBuiltThread(InitThread, InitProcess, IdleStack);
308
309 /* Initialize the Kernel Executive */
310 ExpInitializeExecutive(0, LoaderBlock);
311
312 /* Calculate the time reciprocal */
316
317 /* Update DPC Values in case they got updated by the executive */
318 Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
319 Prcb->MinimumDpcRate = KiMinimumDpcRate;
320 Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
321
322 /* Allocate the DPC Stack */
323 DpcStack = MmCreateKernelStack(FALSE, 0);
324 if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
325 Prcb->DpcStack = DpcStack;
326}
327
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
ULONG_PTR MainSSDT[]
Definition: napi.h:9
VOID KiCalculateCpuFrequency(IN PKPRCB Prcb)
Definition: krnlinit.c:35
VOID NTAPI KiInitializeKernel(IN PKPROCESS InitProcess, IN PKTHREAD InitThread, IN PVOID IdleStack, IN PKPRCB Prcb, IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: krnlinit.c:227
DECLSPEC_NORETURN VOID NTAPI KiSystemStartupBootStack(VOID)
Definition: krnlinit.c:141
VOID NTAPI KiInitializeHandBuiltThread(IN PKTHREAD Thread, IN PKPROCESS Process, IN PVOID Stack)
Definition: krnlinit.c:118
UCHAR MainSSPT[]
Definition: napi.h:15
BOOLEAN RtlpUse16ByteSLists
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
VOID NTAPI KeSetTargetProcessorDpc(IN PKDPC Dpc, IN CCHAR Number)
Definition: dpc.c:971
#define ULONG_PTR
Definition: config.h:101
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
#define KeGetCurrentThread
Definition: hal.h:55
BOOLEAN NTAPI HalInitSystem(IN ULONG BootPhase, IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: halinit.c:43
#define HIGH_PRIORITY
void __cdecl _enable(void)
Definition: intrin_arm.h:373
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
FORCEINLINE VOID KiReleasePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:230
FORCEINLINE VOID KiAcquirePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:220
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
VOID NTAPI ExInitPoolLookasidePointers(VOID)
Definition: lookas.c:59
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1084
#define KF_CMPXCHG16B
Definition: ketypes.h:163
@ Running
Definition: ketypes.h:423
#define KF_RDTSC
Definition: ketypes.h:144
struct _KTHREAD * PKTHREAD
Definition: nt_native.h:28
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
@ SynchronizationEvent
VOID NTAPI ExpInitializeExecutive(IN ULONG Cpu, IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: init.c:922
VOID KiGetCacheInformation(VOID)
Definition: cpu.c:293
KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE]
Definition: timerobj.c:17
LIST_ENTRY KeBugcheckCallbackListHead
Definition: bug.c:22
LIST_ENTRY KiProcessOutSwapListHead
Definition: ke.h:136
LARGE_INTEGER KiTimeIncrementReciprocal
Definition: timerobj.c:18
FAST_MUTEX KiGenericCallDpcMutex
Definition: dpc.c:24
KEVENT KiSwapEvent
Definition: procobj.c:21
ULONG KiAdjustDpcThreshold
Definition: dpc.c:21
ULONG KiMaximumDpcQueueDepth
Definition: dpc.c:19
KDPC KiTimerExpireDpc
Definition: dpc.c:25
VOID NTAPI KeInitializeThread(IN PKPROCESS Process, IN OUT PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, IN PCONTEXT Context, IN PVOID Teb, IN PVOID KernelStack)
Definition: thrdobj.c:900
ULONG KeFeatureBits
Definition: krnlinit.c:22
UCHAR KiTimeIncrementShiftCount
Definition: timerobj.c:19
KSPIN_LOCK BugCheckCallbackLock
Definition: bug.c:24
ULONG KiMinimumDpcRate
Definition: dpc.c:20
DECLSPEC_NORETURN VOID KiIdleLoop(VOID)
Definition: stubs.c:170
LIST_ENTRY KiProfileListHead
Definition: profobj.c:18
PKNODE KeNodeBlock[1]
Definition: krnlinit.c:39
LARGE_INTEGER NTAPI KiComputeReciprocal(IN LONG Divisor, OUT PUCHAR Shift)
Definition: krnlinit.c:123
LIST_ENTRY KiProcessInSwapListHead
Definition: procobj.c:19
ULONG KiServiceLimit
Definition: krnlinit.c:26
VOID NTAPI KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
Definition: cpu.c:451
KSPIN_LOCK KiProfileLock
Definition: profobj.c:20
LIST_ENTRY KiStackInSwapListHead
Definition: procobj.c:20
VOID NTAPI KeInitializeProcess(struct _KPROCESS *Process, KPRIORITY Priority, KAFFINITY Affinity, PULONG_PTR DirectoryTableBase, IN BOOLEAN Enable)
ULONG_PTR KiIdleSummary
Definition: thrdschd.c:25
VOID NTAPI KiInitSpinLocks(IN PKPRCB Prcb, IN CCHAR Number)
Definition: krnlinit.c:187
LIST_ENTRY KiProcessListHead
Definition: procobj.c:18
LIST_ENTRY KeBugcheckReasonCallbackListHead
Definition: ke.h:128
LIST_ENTRY KiProfileSourceListHead
Definition: ke.h:133
VOID NTAPI KiTimerExpiration(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:79
KNODE KiNode0
Definition: krnlinit.c:38
PVOID NTAPI MmCreateKernelStack(BOOLEAN GuiStack, UCHAR Node)
ULONG KeMaximumIncrement
Definition: clock.c:20
VOID NTAPI PoInitializePrcb(IN PKPRCB Prcb)
Definition: power.c:498
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES]
Definition: procobj.c:23
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES]
Definition: procobj.c:24
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
base of all file and directory entries
Definition: entries.h:83
LARGE_INTEGER PerfEnd
Definition: ke.h:60
LONGLONG PerfDelta
Definition: ke.h:61
LARGE_INTEGER PerfFreq
Definition: ke.h:62
LONGLONG TSCStart
Definition: ke.h:63
LONGLONG TSCEnd
Definition: ke.h:64
ULONG MHz
Definition: ke.h:66
LARGE_INTEGER PerfStart
Definition: ke.h:59
LONGLONG TSCDelta
Definition: ke.h:65
KAFFINITY ProcessorMask
Definition: ketypes.h:827
struct _KTHREAD * IdleThread
Definition: ketypes.h:577
struct _KTHREAD * CurrentThread
Definition: ketypes.h:575
struct _KTHREAD * NextThread
Definition: ketypes.h:576
USHORT Number
Definition: ketypes.h:568
KPROCESSOR_STATE ProcessorState
Definition: ketypes.h:588
ULARGE_INTEGER Time
Definition: ketypes.h:719
ULONG_PTR KernelStack
Definition: arc.h:543
ULONG_PTR Prcb
Definition: arc.h:544
ULONG_PTR Thread
Definition: arc.h:546
$ULONG LowPart
Definition: ntbasedef.h:569
$ULONG HighPart
Definition: ntbasedef.h:570
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1327
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define MAXCHAR
Definition: umtypes.h:112
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define TIMER_TABLE_SIZE
Definition: ketypes.h:836
unsigned char UCHAR
Definition: xmlstorage.h:181