[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / ke / i386 / kiinit.c
index 1983aaf..45b25ed 100644 (file)
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <debug.h>
+#include "internal/trap_x.h"
 
 /* GLOBALS *******************************************************************/
 
+/* Boot and double-fault/NMI/DPC stack */
+UCHAR DECLSPEC_ALIGN(16) P0BootStackData[KERNEL_STACK_SIZE] = {0};
+UCHAR DECLSPEC_ALIGN(16) KiDoubleFaultStackData[KERNEL_STACK_SIZE] = {0};
+ULONG_PTR P0BootStack = (ULONG_PTR)&P0BootStackData[KERNEL_STACK_SIZE];
+ULONG_PTR KiDoubleFaultStack = (ULONG_PTR)&KiDoubleFaultStackData[KERNEL_STACK_SIZE];
+
 /* Spinlocks used only on X86 */
 KSPIN_LOCK KiFreezeExecutionLock;
 KSPIN_LOCK Ki486CompatibilityLock;
 
+/* Perf */
+ULONG ProcessCount;
+ULONGLONG BootCycles, BootCyclesEnd;
+
 /* FUNCTIONS *****************************************************************/
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiInitMachineDependent(VOID)
 {
-    ULONG Protect;
     ULONG CpuCount;
     BOOLEAN FbCaching = FALSE;
     NTSTATUS Status;
@@ -40,7 +51,7 @@ KiInitMachineDependent(VOID)
     if (KeFeatureBits & KF_LARGE_PAGE)
     {
         /* FIXME: Support this */
-        DPRINT("Large Page support detected but not yet taken advantage of!\n");
+        DPRINT1("Large Page support detected but not yet taken advantage of\n");
     }
 
     /* Check for global page support */
@@ -146,12 +157,7 @@ KiInitMachineDependent(VOID)
             /* FIXME: Implement and enable XMM Page Zeroing for Mm */
 
             /* Patch the RtlPrefetchMemoryNonTemporal routine to enable it */
-            Protect = MmGetPageProtect(NULL, RtlPrefetchMemoryNonTemporal);
-            MmSetPageProtect(NULL,
-                             RtlPrefetchMemoryNonTemporal,
-                             Protect | PAGE_IS_WRITABLE);
             *(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90;
-            MmSetPageProtect(NULL, RtlPrefetchMemoryNonTemporal, Protect);
         }
     }
 
@@ -258,19 +264,14 @@ KiInitMachineDependent(VOID)
             if (KeFeatureBits & KF_FXSR)
             {
                 /* Get the current thread NPX state */
-                FxSaveArea = (PVOID)
-                             ((ULONG_PTR)KeGetCurrentThread()->InitialStack -
-                             NPX_FRAME_LENGTH);
+                FxSaveArea = KiGetThreadNpxArea(KeGetCurrentThread());
 
                 /* Clear initial MXCsr mask */
                 FxSaveArea->U.FxArea.MXCsrMask = 0;
 
                 /* Save the current NPX State */
-#ifdef __GNUC__
-                asm volatile("fxsave %0\n\t" : "=m" (*FxSaveArea));
-#else
-                __asm fxsave [FxSaveArea]
-#endif
+                Ke386SaveFpuState(FxSaveArea);
+
                 /* Check if the current mask doesn't match the reserved bits */
                 if (FxSaveArea->U.FxArea.MXCsrMask != 0)
                 {
@@ -313,10 +314,14 @@ KiInitMachineDependent(VOID)
         /* FIXME: TODO */
         DPRINT1("ISR Time Limit not yet supported\n");
     }
+    
+    /* Set CR0 features based on detected CPU */
+    KiSetCR0Bits();
 }
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiInitializePcr(IN ULONG ProcessorNumber,
                 IN PKIPCR Pcr,
                 IN PKIDTENTRY Idt,
@@ -378,6 +383,7 @@ KiInitializePcr(IN ULONG ProcessorNumber,
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiInitializeKernel(IN PKPROCESS InitProcess,
                    IN PKTHREAD InitThread,
                    IN PVOID IdleStack,
@@ -394,9 +400,6 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
     /* Detect and set the CPU Type */
     KiSetProcessorType();
 
-    /* Set CR0 features based on detected CPU */
-    KiSetCR0Bits();
-
     /* Check if an FPU is present */
     NpxPresent = KiIsNpxPresent();
 
@@ -602,6 +605,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
 
 VOID
 FASTCALL
+INIT_FUNCTION
 KiGetMachineBootPointers(IN PKGDTENTRY *Gdt,
                          IN PKIDTENTRY *Idt,
                          IN PKIPCR *Pcr,
@@ -642,7 +646,38 @@ KiGetMachineBootPointers(IN PKGDTENTRY *Gdt,
 
 VOID
 NTAPI
-KiSystemStartupReal(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+INIT_FUNCTION
+KiSystemStartupBootStack(VOID)
+{
+    PKTHREAD Thread;
+    
+    /* Initialize the kernel for the current CPU */
+    KiInitializeKernel(&KiInitialProcess.Pcb,
+                       (PKTHREAD)KeLoaderBlock->Thread,
+                       (PVOID)(KeLoaderBlock->KernelStack & ~3),
+                       (PKPRCB)__readfsdword(KPCR_PRCB),
+                       KeNumberProcessors - 1,
+                       KeLoaderBlock);
+   
+    /* Set the priority of this thread to 0 */
+    Thread = KeGetCurrentThread();
+    Thread->Priority = 0;
+    
+    /* Force interrupts enabled and lower IRQL back to DISPATCH_LEVEL */
+    _enable();
+    KfLowerIrql(DISPATCH_LEVEL);
+    
+    /* Set the right wait IRQL */
+    Thread->WaitIrql = DISPATCH_LEVEL;
+
+    /* Jump into the idle loop */
+    KiIdleLoop();
+}
+
+VOID
+NTAPI
+INIT_FUNCTION
+KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     ULONG Cpu;
     PKTHREAD InitialThread;
@@ -652,7 +687,13 @@ KiSystemStartupReal(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     KIDTENTRY NmiEntry, DoubleFaultEntry;
     PKTSS Tss;
     PKIPCR Pcr;
-
+    
+    /* Boot cycles timestamp */
+    BootCycles = __rdtsc();
+#if !defined(_X86_)   
+    /* Check if we are being booted from FreeLDR */
+    if (!((ULONG_PTR)LoaderBlock & 0x80000000)) KiRosPrepareForSystemStartup((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock);
+#endif
     /* Save the loader block and get the current CPU */
     KeLoaderBlock = LoaderBlock;
     Cpu = KeNumberProcessors;
@@ -694,7 +735,7 @@ KiSystemStartupReal(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                     Gdt,
                     Tss,
                     InitialThread,
-                    KiDoubleFaultStack);
+                    (PVOID)KiDoubleFaultStack);
 
     /* Set us as the current process */
     InitialThread->ApcState.Process = &KiInitialProcess.Pcb;
@@ -758,14 +799,6 @@ AppCpuInit:
     /* Raise to HIGH_LEVEL */
     KfRaiseIrql(HIGH_LEVEL);
 
-    /* Align stack and make space for the trap frame and NPX frame */
-    InitialStack &= ~(KTRAP_FRAME_ALIGN - 1);
-
     /* Switch to new kernel stack and start kernel bootstrapping */
-    KiSetupStackAndInitializeKernel(&KiInitialProcess.Pcb,
-                                    InitialThread,
-                                    (PVOID)InitialStack,
-                                    (PKPRCB)__readfsdword(KPCR_PRCB),
-                                    (CCHAR)Cpu,
-                                    KeLoaderBlock);
+    KiSwitchToBootStack(InitialStack & ~3);
 }