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)
10 /* INCLUDES ******************************************************************/
16 extern ULONG_PTR MainSSDT
[];
17 extern UCHAR MainSSPT
[];
19 extern BOOLEAN RtlpUse16ByteSLists
;
21 /* FUNCTIONS *****************************************************************/
26 KiInitializeKernel(IN PKPROCESS InitProcess
,
27 IN PKTHREAD InitThread
,
30 IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
35 KiInitializeHandBuiltThread(
40 PKPRCB Prcb
= KeGetCurrentPrcb();
42 /* Setup the Thread */
43 KeInitializeThread(Process
, Thread
, NULL
, NULL
, NULL
, NULL
, NULL
, Stack
);
45 Thread
->NextProcessor
= Prcb
->Number
;
46 Thread
->Priority
= HIGH_PRIORITY
;
47 Thread
->State
= Running
;
48 Thread
->Affinity
= (ULONG_PTR
)1 << Prcb
->Number
;
49 Thread
->WaitIrql
= DISPATCH_LEVEL
;
50 Process
->ActiveProcessors
|= (ULONG_PTR
)1 << Prcb
->Number
;
57 KiSystemStartupBootStack(VOID
)
59 PLOADER_PARAMETER_BLOCK LoaderBlock
= KeLoaderBlock
; // hack
60 PKPRCB Prcb
= KeGetCurrentPrcb();
61 PKTHREAD Thread
= (PKTHREAD
)KeLoaderBlock
->Thread
;
62 PKPROCESS Process
= Thread
->ApcState
.Process
;
63 PVOID KernelStack
= (PVOID
)KeLoaderBlock
->KernelStack
;
65 /* Initialize the Power Management Support for this PRCB */
66 PoInitializePrcb(Prcb
);
69 KiSaveProcessorControlState(&Prcb
->ProcessorState
);
71 /* Get cache line information for this CPU */
72 KiGetCacheInformation();
74 /* Initialize spinlocks and DPC data */
75 KiInitSpinLocks(Prcb
, Prcb
->Number
);
77 /* Set up the thread-related fields in the PRCB */
78 Prcb
->CurrentThread
= Thread
;
79 Prcb
->NextThread
= NULL
;
80 Prcb
->IdleThread
= Thread
;
82 /* Initialize PRCB pool lookaside pointers */
83 ExInitPoolLookasidePointers();
85 /* Lower to APC_LEVEL */
86 KeLowerIrql(APC_LEVEL
);
88 /* Check if this is the boot cpu */
89 if (Prcb
->Number
== 0)
91 /* Initialize the kernel */
92 KiInitializeKernel(Process
, Thread
, KernelStack
, Prcb
, LoaderBlock
);
96 /* Initialize the startup thread */
97 KiInitializeHandBuiltThread(Thread
, Process
, KernelStack
);
99 /* Initialize cpu with HAL */
100 if (!HalInitSystem(0, LoaderBlock
))
102 /* Initialization failed */
103 KeBugCheck(HAL_INITIALIZATION_FAILED
);
107 /* Raise to Dispatch */
108 KfRaiseIrql(DISPATCH_LEVEL
);
110 /* Set the Idle Priority to 0. This will jump into Phase 1 */
111 KeSetPriorityThread(Thread
, 0);
113 /* If there's no thread scheduled, put this CPU in the Idle summary */
114 KiAcquirePrcbLock(Prcb
);
115 if (!Prcb
->NextThread
) KiIdleSummary
|= (ULONG_PTR
)1 << Prcb
->Number
;
116 KiReleasePrcbLock(Prcb
);
118 /* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
119 KfRaiseIrql(HIGH_LEVEL
);
120 LoaderBlock
->Prcb
= 0;
122 /* Set the priority of this thread to 0 */
123 Thread
= KeGetCurrentThread();
124 Thread
->Priority
= 0;
126 /* Force interrupts enabled and lower IRQL back to DISPATCH_LEVEL */
128 KeLowerIrql(DISPATCH_LEVEL
);
130 /* Set the right wait IRQL */
131 Thread
->WaitIrql
= DISPATCH_LEVEL
;
133 /* Jump into the idle loop */
140 KiInitializeKernel(IN PKPROCESS InitProcess
,
141 IN PKTHREAD InitThread
,
144 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
146 ULONG_PTR PageDirectory
[2];
151 KeNodeBlock
[0] = &KiNode0
;
152 Prcb
->ParentNode
= KeNodeBlock
[0];
153 KeNodeBlock
[0]->ProcessorMask
= Prcb
->SetMember
;
155 /* Set boot-level flags */
156 KeFeatureBits
= Prcb
->FeatureBits
;
158 /* Initialize 8/16 bit SList support */
159 RtlpUse16ByteSLists
= (KeFeatureBits
& KF_CMPXCHG16B
) ? TRUE
: FALSE
;
161 /* Set the current MP Master KPRCB to the Boot PRCB */
162 Prcb
->MultiThreadSetMaster
= Prcb
;
164 /* Initialize Bugcheck Callback data */
165 InitializeListHead(&KeBugcheckCallbackListHead
);
166 InitializeListHead(&KeBugcheckReasonCallbackListHead
);
167 KeInitializeSpinLock(&BugCheckCallbackLock
);
169 /* Initialize the Timer Expiration DPC */
170 KeInitializeDpc(&KiTimerExpireDpc
, KiTimerExpiration
, NULL
);
171 KeSetTargetProcessorDpc(&KiTimerExpireDpc
, 0);
173 /* Initialize Profiling data */
174 KeInitializeSpinLock(&KiProfileLock
);
175 InitializeListHead(&KiProfileListHead
);
176 InitializeListHead(&KiProfileSourceListHead
);
178 /* Loop the timer table */
179 for (i
= 0; i
< TIMER_TABLE_SIZE
; i
++)
181 /* Initialize the list and entries */
182 InitializeListHead(&KiTimerTableListHead
[i
].Entry
);
183 KiTimerTableListHead
[i
].Time
.HighPart
= 0xFFFFFFFF;
184 KiTimerTableListHead
[i
].Time
.LowPart
= 0;
187 /* Initialize the Swap event and all swap lists */
188 KeInitializeEvent(&KiSwapEvent
, SynchronizationEvent
, FALSE
);
189 InitializeListHead(&KiProcessInSwapListHead
);
190 InitializeListHead(&KiProcessOutSwapListHead
);
191 InitializeListHead(&KiStackInSwapListHead
);
193 /* Initialize the mutex for generic DPC calls */
194 ExInitializeFastMutex(&KiGenericCallDpcMutex
);
196 /* Initialize the syscall table */
197 KeServiceDescriptorTable
[0].Base
= MainSSDT
;
198 KeServiceDescriptorTable
[0].Count
= NULL
;
199 KeServiceDescriptorTable
[0].Limit
= KiServiceLimit
;
200 KeServiceDescriptorTable
[1].Limit
= 0;
201 KeServiceDescriptorTable
[0].Number
= MainSSPT
;
203 /* Copy the the current table into the shadow table for win32k */
204 RtlCopyMemory(KeServiceDescriptorTableShadow
,
205 KeServiceDescriptorTable
,
206 sizeof(KeServiceDescriptorTable
));
208 /* Initialize the Idle Process and the Process Listhead */
209 InitializeListHead(&KiProcessListHead
);
210 PageDirectory
[0] = 0;
211 PageDirectory
[1] = 0;
212 KeInitializeProcess(InitProcess
,
217 InitProcess
->QuantumReset
= MAXCHAR
;
219 /* Initialize the startup thread */
220 KiInitializeHandBuiltThread(InitThread
, InitProcess
, IdleStack
);
222 /* Initialize the Kernel Executive */
223 ExpInitializeExecutive(0, LoaderBlock
);
225 /* Calculate the time reciprocal */
226 KiTimeIncrementReciprocal
=
227 KiComputeReciprocal(KeMaximumIncrement
,
228 &KiTimeIncrementShiftCount
);
230 /* Update DPC Values in case they got updated by the executive */
231 Prcb
->MaximumDpcQueueDepth
= KiMaximumDpcQueueDepth
;
232 Prcb
->MinimumDpcRate
= KiMinimumDpcRate
;
233 Prcb
->AdjustDpcThreshold
= KiAdjustDpcThreshold
;
235 /* Allocate the DPC Stack */
236 DpcStack
= MmCreateKernelStack(FALSE
, 0);
237 if (!DpcStack
) KeBugCheckEx(NO_PAGES_AVAILABLE
, 1, 0, 0, 0);
238 Prcb
->DpcStack
= DpcStack
;