[MMIXER] Fix additional data size initialization for different audio formats (#6753)
[reactos.git] / ntoskrnl / ke / amd64 / krnlinit.c
index db09c94..d7aea4d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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,
@@ -28,6 +30,89 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
                    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(
@@ -41,6 +126,7 @@ 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;
@@ -49,9 +135,10 @@ KiInitializeHandBuiltThread(
 
 }
 
+CODE_SEG("INIT")
+DECLSPEC_NORETURN
 VOID
 NTAPI
-INIT_FUNCTION
 KiSystemStartupBootStack(VOID)
 {
     PLOADER_PARAMETER_BLOCK LoaderBlock = KeLoaderBlock; // hack
@@ -60,6 +147,10 @@ KiSystemStartupBootStack(VOID)
     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);
 
@@ -93,15 +184,11 @@ KiSystemStartupBootStack(VOID)
     {
         /* 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);
 
@@ -132,9 +219,9 @@ KiSystemStartupBootStack(VOID)
     KiIdleLoop();
 }
 
+CODE_SEG("INIT")
 VOID
 NTAPI
-INIT_FUNCTION
 KiInitializeKernel(IN PKPROCESS InitProcess,
                    IN PKTHREAD InitThread,
                    IN PVOID IdleStack,
@@ -145,14 +232,12 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
     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;
 
@@ -206,7 +291,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
     PageDirectory[1] = 0;
     KeInitializeProcess(InitProcess,
                         0,
-                        0xFFFFFFFF,
+                        MAXULONG_PTR,
                         PageDirectory,
                         FALSE);
     InitProcess->QuantumReset = MAXCHAR;