[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / ke / i386 / kiinit.c
index a87d096..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;
 
-/* BIOS Memory Map. Not NTLDR-compliant yet */
-extern ULONG KeMemoryMapRangeCount;
-extern ADDRESS_RANGE KeMemoryMap[64];
+/* Perf */
+ULONG ProcessCount;
+ULONGLONG BootCycles, BootCyclesEnd;
 
 /* FUNCTIONS *****************************************************************/
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiInitMachineDependent(VOID)
 {
-    ULONG Protect;
     ULONG CpuCount;
     BOOLEAN FbCaching = FALSE;
     NTSTATUS Status;
@@ -36,7 +43,7 @@ KiInitMachineDependent(VOID)
     ULONG i, Affinity, Sample = 0;
     PFX_SAVE_AREA FxSaveArea;
     ULONG MXCsrMask = 0xFFBF;
-    ULONG Dummy[4];
+    ULONG Dummy;
     KI_SAMPLE_MAP Samples[4];
     PKI_SAMPLE_MAP CurrentSample = Samples;
 
@@ -44,7 +51,7 @@ KiInitMachineDependent(VOID)
     if (KeFeatureBits & KF_LARGE_PAGE)
     {
         /* FIXME: Support this */
-        DPRINT1("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 */
@@ -150,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);
         }
     }
 
@@ -183,7 +185,7 @@ KiInitMachineDependent(VOID)
                 for (;;)
                 {
                     /* Do a dummy CPUID to start the sample */
-                    CPUID(Dummy, 0);
+                    CPUID(0, &Dummy, &Dummy, &Dummy, &Dummy);
 
                     /* Fill out the starting data */
                     CurrentSample->PerfStart = KeQueryPerformanceCounter(NULL);
@@ -196,7 +198,7 @@ KiInitMachineDependent(VOID)
                                            &CurrentSample->PerfFreq);
 
                     /* Do another dummy CPUID */
-                    CPUID(Dummy, 0);
+                    CPUID(0, &Dummy, &Dummy, &Dummy, &Dummy);
 
                     /* Fill out the ending data */
                     CurrentSample->PerfEnd =
@@ -262,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)
                 {
@@ -294,7 +291,7 @@ KiInitMachineDependent(VOID)
                     if (KiMXCsrMask != MXCsrMask)
                     {
                         /* No, something is definitely wrong */
-                        KEBUGCHECKEX(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
+                        KeBugCheckEx(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
                                      KF_FXSR,
                                      KiMXCsrMask,
                                      MXCsrMask,
@@ -317,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,
@@ -355,7 +356,7 @@ KiInitializePcr(IN ULONG ProcessorNumber,
 #ifndef CONFIG_SMP
     Pcr->PrcbData.BuildType |= PRCB_BUILD_UNIPROCESSOR;
 #endif
-#ifdef DBG
+#if DBG
     Pcr->PrcbData.BuildType |= PRCB_BUILD_DEBUG;
 #endif
 
@@ -382,6 +383,7 @@ KiInitializePcr(IN ULONG ProcessorNumber,
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiInitializeKernel(IN PKPROCESS InitProcess,
                    IN PKTHREAD InitThread,
                    IN PVOID IdleStack,
@@ -398,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();
 
@@ -580,7 +579,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
         /* Allocate the IOPM save area. */
         Ki386IopmSaveArea = ExAllocatePoolWithTag(PagedPool,
                                                   PAGE_SIZE * 2,
-                                                  TAG('K', 'e', ' ', ' '));
+                                                  '  eK');
         if (!Ki386IopmSaveArea)
         {
             /* Bugcheck. We need this for V86/VDM support. */
@@ -606,26 +605,26 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
 
 VOID
 FASTCALL
+INIT_FUNCTION
 KiGetMachineBootPointers(IN PKGDTENTRY *Gdt,
                          IN PKIDTENTRY *Idt,
                          IN PKIPCR *Pcr,
                          IN PKTSS *Tss)
 {
-    KDESCRIPTOR GdtDescriptor = {0}, IdtDescriptor = {0};
+    KDESCRIPTOR GdtDescriptor, IdtDescriptor;
     KGDTENTRY TssSelector, PcrSelector;
-    USHORT Tr = 0, Fs;
+    USHORT Tr, Fs;
 
     /* Get GDT and IDT descriptors */
-    Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&GdtDescriptor.Limit);
-    Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&IdtDescriptor.Limit);
+    Ke386GetGlobalDescriptorTable(&GdtDescriptor.Limit);
+    __sidt(&IdtDescriptor.Limit);
 
     /* Save IDT and GDT */
     *Gdt = (PKGDTENTRY)GdtDescriptor.Base;
     *Idt = (PKIDTENTRY)IdtDescriptor.Base;
 
     /* Get TSS and FS Selectors */
-    Ke386GetTr(Tr);
-    if (Tr != KGDT_TSS) Tr = KGDT_TSS; // FIXME: HACKHACK
+    Tr = Ke386GetTr();
     Fs = Ke386GetFs();
 
     /* Get PCR Selector, mask it and get its GDT Entry */
@@ -647,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;
@@ -657,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;
@@ -699,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;
@@ -757,20 +793,12 @@ AppCpuInit:
         KdInitSystem(0, KeLoaderBlock);
 
         /* Check for break-in */
-        if (KdPollBreakIn()) DbgBreakPointWithStatus(1);
+        if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
     }
 
     /* 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);
 }