#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;
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 */
/* 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);
}
}
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)
{
/* 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,
VOID
NTAPI
+INIT_FUNCTION
KiInitializeKernel(IN PKPROCESS InitProcess,
IN PKTHREAD InitThread,
IN PVOID IdleStack,
/* Detect and set the CPU Type */
KiSetProcessorType();
- /* Set CR0 features based on detected CPU */
- KiSetCR0Bits();
-
/* Check if an FPU is present */
NpxPresent = KiIsNpxPresent();
VOID
FASTCALL
+INIT_FUNCTION
KiGetMachineBootPointers(IN PKGDTENTRY *Gdt,
IN PKIDTENTRY *Idt,
IN PKIPCR *Pcr,
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;
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;
Gdt,
Tss,
InitialThread,
- KiDoubleFaultStack);
+ (PVOID)KiDoubleFaultStack);
/* Set us as the current process */
InitialThread->ApcState.Process = &KiInitialProcess.Pcb;
/* 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);
}