/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: ntoskrnl/ke/krnlinit.c
+ * FILE: ntoskrnl/ke/amd64/krnlinit.c
* PURPOSE: Portable part of kernel initialization
* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
* Alex Ionescu (alex.ionescu@reactos.org)
extern ULONG_PTR MainSSDT[];
extern UCHAR MainSSPT[];
+extern BOOLEAN RtlpUse16ByteSLists;
+
/* FUNCTIONS *****************************************************************/
+CODE_SEG("INIT")
VOID
NTAPI
-INIT_FUNCTION
KiInitializeKernel(IN PKPROCESS InitProcess,
IN PKTHREAD InitThread,
IN PVOID IdleStack,
IN PLOADER_PARAMETER_BLOCK LoaderBlock);
+CODE_SEG("INIT")
+VOID
+KiCalculateCpuFrequency(
+ IN PKPRCB Prcb)
+{
+ if (Prcb->FeatureBits & KF_RDTSC)
+ {
+ ULONG Sample = 0;
+ CPU_INFO CpuInfo;
+ KI_SAMPLE_MAP Samples[10];
+ PKI_SAMPLE_MAP CurrentSample = Samples;
+
+ /* Start sampling loop */
+ for (;;)
+ {
+ /* Do a dummy CPUID to start the sample */
+ KiCpuId(&CpuInfo, 0);
+
+ /* Fill out the starting data */
+ CurrentSample->PerfStart = KeQueryPerformanceCounter(NULL);
+ CurrentSample->TSCStart = __rdtsc();
+ CurrentSample->PerfFreq.QuadPart = -50000;
+
+ /* Sleep for this sample */
+ KeStallExecutionProcessor(CurrentSample->PerfFreq.QuadPart * -1 / 10);
+
+ /* Do another dummy CPUID */
+ KiCpuId(&CpuInfo, 0);
+
+ /* Fill out the ending data */
+ CurrentSample->PerfEnd =
+ KeQueryPerformanceCounter(&CurrentSample->PerfFreq);
+ CurrentSample->TSCEnd = __rdtsc();
+
+ /* Calculate the differences */
+ CurrentSample->PerfDelta = CurrentSample->PerfEnd.QuadPart -
+ CurrentSample->PerfStart.QuadPart;
+ CurrentSample->TSCDelta = CurrentSample->TSCEnd -
+ CurrentSample->TSCStart;
+
+ /* Compute CPU Speed */
+ CurrentSample->MHz = (ULONG)((CurrentSample->TSCDelta *
+ CurrentSample->
+ PerfFreq.QuadPart + 500000) /
+ (CurrentSample->PerfDelta *
+ 1000000));
+
+ /* Check if this isn't the first sample */
+ if (Sample)
+ {
+ /* Check if we got a good precision within 1MHz */
+ if ((CurrentSample->MHz == CurrentSample[-1].MHz) ||
+ (CurrentSample->MHz == CurrentSample[-1].MHz + 1) ||
+ (CurrentSample->MHz == CurrentSample[-1].MHz - 1))
+ {
+ /* We did, stop sampling */
+ break;
+ }
+ }
+
+ /* Move on */
+ CurrentSample++;
+ Sample++;
+
+ if (Sample == RTL_NUMBER_OF(Samples))
+ {
+ /* No luck. Average the samples and be done */
+ ULONG TotalMHz = 0;
+ while (Sample--)
+ {
+ TotalMHz += Samples[Sample].MHz;
+ }
+ CurrentSample[-1].MHz = TotalMHz / RTL_NUMBER_OF(Samples);
+ DPRINT1("Sampling CPU frequency failed. Using average of %lu MHz\n", CurrentSample[-1].MHz);
+ break;
+ }
+ }
+
+ /* Save the CPU Speed */
+ Prcb->MHz = CurrentSample[-1].MHz;
+ }
+}
+
VOID
NTAPI
KiInitializeHandBuiltThread(
KeInitializeThread(Process, Thread, NULL, NULL, NULL, NULL, NULL, Stack);
Thread->NextProcessor = Prcb->Number;
+ Thread->IdealProcessor = Prcb->Number;
Thread->Priority = HIGH_PRIORITY;
Thread->State = Running;
Thread->Affinity = (ULONG_PTR)1 << Prcb->Number;
}
+CODE_SEG("INIT")
+DECLSPEC_NORETURN
VOID
NTAPI
-INIT_FUNCTION
KiSystemStartupBootStack(VOID)
{
PLOADER_PARAMETER_BLOCK LoaderBlock = KeLoaderBlock; // hack
PKPROCESS Process = Thread->ApcState.Process;
PVOID KernelStack = (PVOID)KeLoaderBlock->KernelStack;
+ /* Set Node Data */
+ Prcb->ParentNode = KeNodeBlock[0];
+ Prcb->ParentNode->ProcessorMask |= Prcb->SetMember;
+
/* Initialize the Power Management Support for this PRCB */
PoInitializePrcb(Prcb);
{
/* Initialize the startup thread */
KiInitializeHandBuiltThread(Thread, Process, KernelStack);
-
- /* Initialize cpu with HAL */
- if (!HalInitSystem(0, LoaderBlock))
- {
- /* Initialization failed */
- KeBugCheck(HAL_INITIALIZATION_FAILED);
- }
}
+ /* Calculate the CPU frequency */
+ KiCalculateCpuFrequency(Prcb);
+
/* Raise to Dispatch */
KfRaiseIrql(DISPATCH_LEVEL);
KiIdleLoop();
}
+CODE_SEG("INIT")
VOID
NTAPI
-INIT_FUNCTION
KiInitializeKernel(IN PKPROCESS InitProcess,
IN PKTHREAD InitThread,
IN PVOID IdleStack,
PVOID DpcStack;
ULONG i;
- /* Set Node Data */
- KeNodeBlock[0] = &KiNode0;
- Prcb->ParentNode = KeNodeBlock[0];
- KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
-
/* Set boot-level flags */
KeFeatureBits = Prcb->FeatureBits;
+ /* Initialize 8/16 bit SList support */
+ RtlpUse16ByteSLists = (KeFeatureBits & KF_CMPXCHG16B) ? TRUE : FALSE;
+
/* Set the current MP Master KPRCB to the Boot PRCB */
Prcb->MultiThreadSetMaster = Prcb;
PageDirectory[1] = 0;
KeInitializeProcess(InitProcess,
0,
- 0xFFFFFFFF,
+ MAXULONG_PTR,
PageDirectory,
FALSE);
InitProcess->QuantumReset = MAXCHAR;