mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
- Final cleanup for now:
- main.c -> freeldr.c + cleanups and nice formatitng. - Move out variables that were in main.c to ex\init.c or cpu.c, depending. - Separate i386/kernel.c into i386/kiinit.c for X86-specific intiailization, and /krnlinit.c for portable initialization across all architectures. Also move out global variables appropriately. - main_asm.S -> cpu.S svn path=/trunk/; revision=23903
This commit is contained in:
parent
00abb85d36
commit
9fbb616938
11 changed files with 723 additions and 685 deletions
|
@ -27,11 +27,10 @@
|
|||
// Ke:
|
||||
//
|
||||
// - FIXES:
|
||||
// * Implement invalid opcode handler (fixes some apps from crashing).
|
||||
// * Get rid of KiRosPrintAddress and use KiDumpParameterImages instead.
|
||||
// * Sanitize some context fields during conversions.
|
||||
// * Implement stack fault and segment fault handlers.
|
||||
// * Add DR macro/save and VM macro/save.
|
||||
// * Make boot process more NT-like.
|
||||
// - FEATURES:
|
||||
// * Use Queued Spinlocks for scheduling and dispatching.
|
||||
// * New optimized table-based tick-hashed timer implementation.
|
||||
|
|
|
@ -15,6 +15,17 @@
|
|||
|
||||
/* DATA **********************************************************************/
|
||||
|
||||
#define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
|
||||
|
||||
/* NT Version Info */
|
||||
ULONG NtMajorVersion = 5;
|
||||
ULONG NtMinorVersion = 0;
|
||||
ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(4, 0);
|
||||
ULONG NtBuildNumber = KERNEL_VERSION_BUILD;
|
||||
ULONG NtGlobalFlag = 0;
|
||||
|
||||
ULONG InitSafeBootMode = 0; /* KB83764 */
|
||||
|
||||
extern ULONG MmCoreDumpType;
|
||||
extern CHAR KiTimerSystemAuditing;
|
||||
extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
|
||||
|
|
|
@ -82,9 +82,13 @@ extern ULONG KeProcessorArchitecture;
|
|||
extern ULONG KeProcessorLevel;
|
||||
extern ULONG KeProcessorRevision;
|
||||
extern ULONG KeFeatureBits;
|
||||
extern ULONG Ke386GlobalPagesEnabled;
|
||||
extern KNODE KiNode0;
|
||||
extern PKNODE KeNodeBlock[1];
|
||||
extern UCHAR KeNumberNodes;
|
||||
extern UCHAR KeProcessNodeSeed;
|
||||
extern ETHREAD KiInitialThread;
|
||||
extern EPROCESS KiInitialProcess;
|
||||
extern ULONG KiInterruptTemplate[KINTERRUPT_DISPATCH_CODES];
|
||||
extern PULONG KiInterruptTemplateObject;
|
||||
extern PULONG KiInterruptTemplateDispatch;
|
||||
|
@ -801,6 +805,26 @@ KiFlushNPXState(
|
|||
IN FLOATING_SAVE_AREA *SaveArea
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitSpinLocks(
|
||||
IN PKPRCB Prcb,
|
||||
IN CCHAR Number
|
||||
);
|
||||
|
||||
LARGE_INTEGER
|
||||
NTAPI
|
||||
KiComputeReciprocal(
|
||||
IN LONG Divisor,
|
||||
OUT PUCHAR Shift
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitSystem(
|
||||
VOID
|
||||
);
|
||||
|
||||
#include "ke_x.h"
|
||||
|
||||
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */
|
||||
|
|
|
@ -1,76 +1,41 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/main.c
|
||||
* PURPOSE: Initalizes the kernel
|
||||
*
|
||||
* PROGRAMMERS: Alex Ionescu (cleaned up code, moved Executiv stuff to ex/init.c)
|
||||
* David Welch (welch@cwcom.net)
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ke/freeldr.c
|
||||
* PURPOSE: FreeLDR Bootstrap Support
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
|
||||
|
||||
|
||||
ULONG NtMajorVersion = 5;
|
||||
ULONG NtMinorVersion = 0;
|
||||
ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(4, 0);
|
||||
ULONG NtBuildNumber = KERNEL_VERSION_BUILD;
|
||||
ULONG NtGlobalFlag = 0;
|
||||
CHAR KeNumberProcessors;
|
||||
KAFFINITY KeActiveProcessors = 1;
|
||||
ROS_LOADER_PARAMETER_BLOCK KeLoaderBlock;
|
||||
ULONG KeDcacheFlushCount = 0;
|
||||
ULONG KeIcacheFlushCount = 0;
|
||||
ULONG KiDmaIoCoherency = 0; /* RISC Architectures only */
|
||||
ULONG InitSafeBootMode = 0; /* KB83764 */
|
||||
|
||||
/* FreeLDR Module Data */
|
||||
LOADER_MODULE KeLoaderModules[64];
|
||||
static CHAR KeLoaderModuleStrings[64][256];
|
||||
static CHAR KeLoaderCommandLine[256];
|
||||
PLOADER_MODULE CachedModules[MaximumCachedModuleType];
|
||||
|
||||
/* FreeLDR Memory Data */
|
||||
ADDRESS_RANGE KeMemoryMap[64];
|
||||
ULONG KeMemoryMapRangeCount;
|
||||
ULONG_PTR FirstKrnlPhysAddr;
|
||||
ULONG_PTR LastKrnlPhysAddr;
|
||||
ULONG_PTR LastKernelAddress;
|
||||
|
||||
PVOID KeUserApcDispatcher = NULL;
|
||||
PVOID KeUserCallbackDispatcher = NULL;
|
||||
PVOID KeUserExceptionDispatcher = NULL;
|
||||
PVOID KeRaiseUserExceptionDispatcher = NULL;
|
||||
|
||||
ULONG KeLargestCacheLine = 0x40; /* FIXME: Arch-specific */
|
||||
|
||||
/* Cached modules from the loader block */
|
||||
PLOADER_MODULE CachedModules[MaximumCachedModuleType];
|
||||
/* FreeLDR Loader Data */
|
||||
ROS_LOADER_PARAMETER_BLOCK KeLoaderBlock;
|
||||
static CHAR KeLoaderCommandLine[256];
|
||||
|
||||
/* FreeLDR PE Hack Data */
|
||||
extern unsigned int _image_base__;
|
||||
ULONG_PTR KERNEL_BASE = (ULONG_PTR)&_image_base__;
|
||||
|
||||
#if defined (ALLOC_PRAGMA)
|
||||
#pragma alloc_text(INIT, _main)
|
||||
#endif
|
||||
|
||||
extern LDR_DATA_TABLE_ENTRY HalModuleObject;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
STDCALL
|
||||
KeGetRecommendedSharedDataAlignment(VOID)
|
||||
{
|
||||
return KeLargestCacheLine;
|
||||
}
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
|
@ -121,7 +86,8 @@ KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
}
|
||||
|
||||
/* Save data */
|
||||
KeLoaderBlock.MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
|
||||
KeLoaderBlock.MmapLength = KeMemoryMapRangeCount *
|
||||
sizeof(ADDRESS_RANGE);
|
||||
KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
|
||||
}
|
||||
else
|
||||
|
@ -148,7 +114,8 @@ KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
OptHead = &NtHeader->OptionalHeader;
|
||||
|
||||
/* Set Kernel Ending */
|
||||
KeLoaderModules[0].ModEnd = KeLoaderModules[0].ModStart + PAGE_ROUND_UP((ULONG)OptHead->SizeOfImage);
|
||||
KeLoaderModules[0].ModEnd = KeLoaderModules[0].ModStart +
|
||||
PAGE_ROUND_UP((ULONG)OptHead->SizeOfImage);
|
||||
|
||||
/* Create a block for each module */
|
||||
for (i = 1; i < KeLoaderBlock.ModsCount; i++)
|
||||
|
@ -180,7 +147,8 @@ KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
}
|
||||
|
||||
/* Choose last module address as the final kernel address */
|
||||
LastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
|
||||
LastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.
|
||||
ModsCount - 1].ModEnd);
|
||||
|
||||
/* Select the HAL Base */
|
||||
HalBase = KeLoaderModules[1].ModStart;
|
||||
|
@ -207,7 +175,9 @@ KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
//
|
||||
// This dirty hack fixes it, and should make symbol lookup work too.
|
||||
//
|
||||
HalModuleObject.SizeOfImage = RtlImageNtHeader((PVOID)HalModuleObject.DllBase)->OptionalHeader.SizeOfImage;
|
||||
HalModuleObject.SizeOfImage = RtlImageNtHeader((PVOID)HalModuleObject.
|
||||
DllBase)->
|
||||
OptionalHeader.SizeOfImage;
|
||||
|
||||
/* Increase the last kernel address with the size of HAL */
|
||||
LastKernelAddress += PAGE_ROUND_UP(DriverSize);
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* FILE: ntoskrnl/ke/i386/main_asm.S
|
||||
* FILE: ntoskrnl/ke/i386/boot.S
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PURPOSE: Kernel Bootstrap Code
|
||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
|
@ -65,6 +65,12 @@ ULONG Ke386Pae = FALSE;
|
|||
ULONG Ke386GlobalPagesEnabled = FALSE;
|
||||
ULONG Ke386NoExecute = FALSE;
|
||||
BOOLEAN KiI386PentiumLockErrataPresent;
|
||||
ULONG KeLargestCacheLine = 0x40;
|
||||
ULONG KeDcacheFlushCount = 0;
|
||||
ULONG KeIcacheFlushCount = 0;
|
||||
ULONG KiDmaIoCoherency = 0;
|
||||
CHAR KeNumberProcessors;
|
||||
KAFFINITY KeActiveProcessors = 1;
|
||||
|
||||
/* CPU Signatures */
|
||||
CHAR CmpIntelID[] = "GenuineIntel";
|
||||
|
@ -769,3 +775,12 @@ KeFlushCurrentTb(VOID)
|
|||
_Ke386SetCr(3, _Ke386GetCr(3));
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
STDCALL
|
||||
KeGetRecommendedSharedDataAlignment(VOID)
|
||||
{
|
||||
return KeLargestCacheLine;
|
||||
}
|
||||
|
|
306
reactos/ntoskrnl/ke/i386/kiinit.c
Normal file
306
reactos/ntoskrnl/ke/i386/kiinit.c
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ke/i386/kiinit.c
|
||||
* PURPOSE: Kernel Initialization for x86 CPUs
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* Spinlocks used only on X86 */
|
||||
KSPIN_LOCK KiFreezeExecutionLock;
|
||||
KSPIN_LOCK Ki486CompatibilityLock;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializePcr(IN ULONG ProcessorNumber,
|
||||
IN PKIPCR Pcr,
|
||||
IN PKIDTENTRY Idt,
|
||||
IN PKGDTENTRY Gdt,
|
||||
IN PKTSS Tss,
|
||||
IN PKTHREAD IdleThread,
|
||||
IN PVOID DpcStack)
|
||||
{
|
||||
/* Setup the TIB */
|
||||
Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
|
||||
Pcr->NtTib.StackBase = 0;
|
||||
Pcr->NtTib.StackLimit = 0;
|
||||
Pcr->NtTib.Self = 0;
|
||||
|
||||
/* Set the Current Thread */
|
||||
//Pcr->PrcbData.CurrentThread = IdleThread;
|
||||
|
||||
/* Set pointers to ourselves */
|
||||
Pcr->Self = (PKPCR)Pcr;
|
||||
Pcr->Prcb = &Pcr->PrcbData;
|
||||
|
||||
/* Set the PCR Version */
|
||||
Pcr->MajorVersion = PCR_MAJOR_VERSION;
|
||||
Pcr->MinorVersion = PCR_MINOR_VERSION;
|
||||
|
||||
/* Set the PCRB Version */
|
||||
Pcr->PrcbData.MajorVersion = 1;
|
||||
Pcr->PrcbData.MinorVersion = 1;
|
||||
|
||||
/* Set the Build Type */
|
||||
Pcr->PrcbData.BuildType = 0;
|
||||
|
||||
/* Set the Processor Number and current Processor Mask */
|
||||
Pcr->PrcbData.Number = (UCHAR)ProcessorNumber;
|
||||
Pcr->PrcbData.SetMember = 1 << ProcessorNumber;
|
||||
|
||||
/* Set the PRCB for this Processor */
|
||||
KiProcessorBlock[ProcessorNumber] = Pcr->Prcb;
|
||||
|
||||
/* Start us out at PASSIVE_LEVEL */
|
||||
Pcr->Irql = PASSIVE_LEVEL;
|
||||
|
||||
/* Set the GDI, IDT, TSS and DPC Stack */
|
||||
Pcr->GDT = (PVOID)Gdt;
|
||||
Pcr->IDT = Idt;
|
||||
Pcr->TSS = Tss;
|
||||
Pcr->PrcbData.DpcStack = DpcStack;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||
IN PKTHREAD InitThread,
|
||||
IN PVOID IdleStack,
|
||||
IN PKPRCB Prcb,
|
||||
IN CCHAR Number,
|
||||
IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
BOOLEAN NpxPresent;
|
||||
ULONG FeatureBits;
|
||||
LARGE_INTEGER PageDirectory;
|
||||
PVOID DpcStack;
|
||||
|
||||
/* Detect and set the CPU Type */
|
||||
KiSetProcessorType();
|
||||
|
||||
/* Set CR0 features based on detected CPU */
|
||||
KiSetCR0Bits();
|
||||
|
||||
/* Check if an FPU is present */
|
||||
NpxPresent = KiIsNpxPresent();
|
||||
|
||||
/* Initialize the Power Management Support for this PRCB */
|
||||
PoInitializePrcb(Prcb);
|
||||
|
||||
/* Bugcheck if this is a 386 CPU */
|
||||
if (Prcb->CpuType == 3) KeBugCheckEx(0x5D, 0x386, 0, 0, 0);
|
||||
|
||||
/* Get the processor features for the CPU */
|
||||
FeatureBits = KiGetFeatureBits();
|
||||
|
||||
/* Save feature bits */
|
||||
Prcb->FeatureBits = FeatureBits;
|
||||
|
||||
/* Get cache line information for this CPU */
|
||||
KiGetCacheInformation();
|
||||
|
||||
/* Initialize spinlocks and DPC data */
|
||||
KiInitSpinLocks(Prcb, Number);
|
||||
|
||||
/* Check if this is the Boot CPU */
|
||||
if (!Number)
|
||||
{
|
||||
/* Set Node Data */
|
||||
KeNodeBlock[0] = &KiNode0;
|
||||
Prcb->ParentNode = KeNodeBlock[0];
|
||||
KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
|
||||
|
||||
/* Set boot-level flags */
|
||||
KeI386NpxPresent = NpxPresent;
|
||||
KeI386CpuType = Prcb->CpuType;
|
||||
KeI386CpuStep = Prcb->CpuStep;
|
||||
KeProcessorArchitecture = 0;
|
||||
KeProcessorLevel = (USHORT)Prcb->CpuType;
|
||||
if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep;
|
||||
KeFeatureBits = FeatureBits;
|
||||
KeI386FxsrPresent = (KeFeatureBits & KF_FXSR) ? TRUE : FALSE;
|
||||
KeI386XMMIPresent = (KeFeatureBits & KF_XMMI) ? TRUE : FALSE;
|
||||
|
||||
/* Set the current MP Master KPRCB to the Boot PRCB */
|
||||
Prcb->MultiThreadSetMaster = Prcb;
|
||||
|
||||
/* Initialize some spinlocks */
|
||||
KeInitializeSpinLock(&KiFreezeExecutionLock);
|
||||
KeInitializeSpinLock(&Ki486CompatibilityLock);
|
||||
|
||||
/* Initialize portable parts of the OS */
|
||||
KiInitSystem();
|
||||
|
||||
/* Initialize the Idle Process and the Process Listhead */
|
||||
InitializeListHead(&KiProcessListHead);
|
||||
PageDirectory.QuadPart = 0;
|
||||
KeInitializeProcess(InitProcess,
|
||||
0,
|
||||
0xFFFFFFFF,
|
||||
PageDirectory);
|
||||
InitProcess->QuantumReset = MAXCHAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME */
|
||||
DPRINT1("SMP Boot support not yet present\n");
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Setup the Idle Thread */
|
||||
KeInitializeThread(InitProcess,
|
||||
InitThread,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
IdleStack);
|
||||
#endif
|
||||
InitThread->NextProcessor = Number;
|
||||
InitThread->Priority = HIGH_PRIORITY;
|
||||
InitThread->State = Running;
|
||||
InitThread->Affinity = 1 << Number;
|
||||
InitThread->WaitIrql = DISPATCH_LEVEL;
|
||||
InitProcess->ActiveProcessors = 1 << Number;
|
||||
|
||||
/* Set up the thread-related fields in the PRCB */
|
||||
//Prcb->CurrentThread = InitThread;
|
||||
Prcb->NextThread = NULL;
|
||||
//Prcb->IdleThread = InitThread;
|
||||
|
||||
/* Initialize the Kernel Executive */
|
||||
ExpInitializeExecutive();
|
||||
|
||||
/* Only do this on the boot CPU */
|
||||
if (!Number)
|
||||
{
|
||||
/* Calculate the time reciprocal */
|
||||
KiTimeIncrementReciprocal =
|
||||
KiComputeReciprocal(KeMaximumIncrement,
|
||||
&KiTimeIncrementShiftCount);
|
||||
|
||||
/* Update DPC Values in case they got updated by the executive */
|
||||
Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
|
||||
Prcb->MinimumDpcRate = KiMinimumDpcRate;
|
||||
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
|
||||
|
||||
/* Allocate the DPC Stack */
|
||||
DpcStack = MmCreateKernelStack(FALSE);
|
||||
if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
|
||||
Prcb->DpcStack = DpcStack;
|
||||
|
||||
/* Allocate the IOPM save area. */
|
||||
Ki386IopmSaveArea = ExAllocatePoolWithTag(PagedPool,
|
||||
PAGE_SIZE * 2,
|
||||
TAG('K', 'e', ' ', ' '));
|
||||
if (!Ki386IopmSaveArea)
|
||||
{
|
||||
/* Bugcheck. We need this for V86/VDM support. */
|
||||
KeBugCheckEx(NO_PAGES_AVAILABLE, 2, PAGE_SIZE * 2, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free Initial Memory */
|
||||
MiFreeInitMemory();
|
||||
|
||||
while (1)
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
Timeout.QuadPart = 0x7fffffffffffffffLL;
|
||||
KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
|
||||
}
|
||||
|
||||
/* Bug Check and loop forever if anything failed */
|
||||
KEBUGCHECK(0);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
ULONG Cpu;
|
||||
PKIPCR Pcr = (PKIPCR)KPCR_BASE;
|
||||
PKPRCB Prcb;
|
||||
|
||||
/* Save the loader block and get the current CPU */
|
||||
//KeLoaderBlock = LoaderBlock;
|
||||
Cpu = KeNumberProcessors;
|
||||
if (!Cpu)
|
||||
{
|
||||
/* If this is the boot CPU, set FS and the CPU Number*/
|
||||
Ke386SetFs(KGDT_R0_PCR);
|
||||
KeGetPcr()->Number = Cpu;
|
||||
}
|
||||
|
||||
/* Skip initial setup if this isn't the Boot CPU */
|
||||
if (Cpu) goto AppCpuInit;
|
||||
|
||||
/* Setup the boot (Freeldr should've done), double fault and NMI TSS */
|
||||
Ki386InitializeTss();
|
||||
|
||||
/* Initialize the PCR */
|
||||
RtlZeroMemory(Pcr, PAGE_SIZE);
|
||||
KiInitializePcr(Cpu,
|
||||
Pcr,
|
||||
KiIdt,
|
||||
KiBootGdt,
|
||||
&KiBootTss,
|
||||
&KiInitialThread.Tcb,
|
||||
KiDoubleFaultStack);
|
||||
|
||||
/* Set us as the current process */
|
||||
KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
|
||||
|
||||
/* Clear DR6/7 to cleanup bootloader debugging */
|
||||
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr6 = 0;
|
||||
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr7 = 0;
|
||||
|
||||
/* Load Ring 3 selectors for DS/ES */
|
||||
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
||||
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
|
||||
|
||||
/* Setup CPU-related fields */
|
||||
AppCpuInit:
|
||||
Prcb = Pcr->Prcb;
|
||||
Pcr->Number = Cpu;
|
||||
Pcr->SetMember = 1 << Cpu;
|
||||
Pcr->SetMemberCopy = 1 << Cpu;
|
||||
Prcb->SetMember = 1 << Cpu;
|
||||
|
||||
/* Initialize the Processor with HAL */
|
||||
HalInitializeProcessor(Cpu, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
|
||||
|
||||
/* Set active processors */
|
||||
KeActiveProcessors |= Pcr->SetMember;
|
||||
KeNumberProcessors++;
|
||||
|
||||
/* Initialize the Debugger for the Boot CPU */
|
||||
if (!Cpu) KdInitSystem (0, &KeLoaderBlock);
|
||||
|
||||
/* Check for break-in */
|
||||
if (KdPollBreakIn()) DbgBreakPointWithStatus(1);
|
||||
|
||||
/* Raise to HIGH_LEVEL */
|
||||
KfRaiseIrql(HIGH_LEVEL);
|
||||
|
||||
/* Call main kernel intialization */
|
||||
KiInitializeKernel(&KiInitialProcess.Pcb,
|
||||
&KiInitialThread.Tcb,
|
||||
P0BootStack,
|
||||
Prcb,
|
||||
Cpu,
|
||||
LoaderBlock);
|
||||
}
|
||||
|
|
@ -1,622 +1,330 @@
|
|||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/i386/kernel.c
|
||||
* PURPOSE: Initializes the kernel
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
#include <internal/napi.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
PKPRCB KiProcessorBlock[MAXIMUM_PROCESSORS];
|
||||
KNODE KiNode0;
|
||||
PKNODE KeNodeBlock[1];
|
||||
UCHAR KeNumberNodes = 1;
|
||||
UCHAR KeProcessNodeSeed;
|
||||
ETHREAD KiInitialThread;
|
||||
EPROCESS KiInitialProcess;
|
||||
|
||||
extern ULONG Ke386GlobalPagesEnabled;
|
||||
extern PVOID trap_stack;
|
||||
|
||||
/* System-defined Spinlocks */
|
||||
KSPIN_LOCK KiDispatcherLock;
|
||||
KSPIN_LOCK MmPfnLock;
|
||||
KSPIN_LOCK MmSystemSpaceLock;
|
||||
KSPIN_LOCK CcBcbSpinLock;
|
||||
KSPIN_LOCK CcMasterSpinLock;
|
||||
KSPIN_LOCK CcVacbSpinLock;
|
||||
KSPIN_LOCK CcWorkQueueSpinLock;
|
||||
KSPIN_LOCK NonPagedPoolLock;
|
||||
KSPIN_LOCK MmNonPagedPoolLock;
|
||||
KSPIN_LOCK IopCancelSpinLock;
|
||||
KSPIN_LOCK IopVpbSpinLock;
|
||||
KSPIN_LOCK IopDatabaseLock;
|
||||
KSPIN_LOCK IopCompletionLock;
|
||||
KSPIN_LOCK NtfsStructLock;
|
||||
KSPIN_LOCK AfdWorkQueueSpinLock;
|
||||
KSPIN_LOCK KiTimerTableLock[16];
|
||||
KSPIN_LOCK KiReverseStallIpiLock;
|
||||
|
||||
KSPIN_LOCK KiFreezeExecutionLock;
|
||||
KSPIN_LOCK Ki486CompatibilityLock;
|
||||
|
||||
#if defined (ALLOC_PRAGMA)
|
||||
#pragma alloc_text(INIT, KeInit1)
|
||||
#pragma alloc_text(INIT, KeInit2)
|
||||
#endif
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitSystem(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* Initialize Bugcheck Callback data */
|
||||
InitializeListHead(&BugcheckCallbackListHead);
|
||||
InitializeListHead(&BugcheckReasonCallbackListHead);
|
||||
KeInitializeSpinLock(&BugCheckCallbackLock);
|
||||
|
||||
/* Initialize the Timer Expiration DPC */
|
||||
KeInitializeDpc(&KiExpireTimerDpc, KiExpireTimers, NULL);
|
||||
KeSetTargetProcessorDpc(&KiExpireTimerDpc, 0);
|
||||
|
||||
/* Initialize Profiling data */
|
||||
KeInitializeSpinLock(&KiProfileLock);
|
||||
InitializeListHead(&KiProfileListHead);
|
||||
InitializeListHead(&KiProfileSourceListHead);
|
||||
|
||||
/* Loop the timer table */
|
||||
for (i = 0; i < TIMER_TABLE_SIZE; i++)
|
||||
{
|
||||
/* Initialize the list and entries */
|
||||
InitializeListHead(&KiTimerTableListHead[i].Entry);
|
||||
KiTimerTableListHead[i].Time.HighPart = 0xFFFFFFFF;
|
||||
KiTimerTableListHead[i].Time.LowPart = 0;
|
||||
}
|
||||
|
||||
/* Initialize old-style list */
|
||||
InitializeListHead(&KiTimerListHead);
|
||||
|
||||
/* Initialize the Swap event and all swap lists */
|
||||
KeInitializeEvent(&KiSwapEvent, SynchronizationEvent, FALSE);
|
||||
InitializeListHead(&KiProcessInSwapListHead);
|
||||
InitializeListHead(&KiProcessOutSwapListHead);
|
||||
InitializeListHead(&KiStackInSwapListHead);
|
||||
|
||||
/* Initialize the mutex for generic DPC calls */
|
||||
KeInitializeMutex(&KiGenericCallDpcMutex, 0);
|
||||
|
||||
/* Initialize the syscall table */
|
||||
KeServiceDescriptorTable[0].Base = MainSSDT;
|
||||
KeServiceDescriptorTable[0].Count = NULL;
|
||||
KeServiceDescriptorTable[0].Limit = NUMBER_OF_SYSCALLS;
|
||||
KeServiceDescriptorTable[1].Limit = 0;
|
||||
KeServiceDescriptorTable[0].Number = MainSSPT;
|
||||
|
||||
/* Copy the the current table into the shadow table for win32k */
|
||||
RtlCopyMemory(KeServiceDescriptorTableShadow,
|
||||
KeServiceDescriptorTable,
|
||||
sizeof(KeServiceDescriptorTable));
|
||||
}
|
||||
|
||||
LARGE_INTEGER
|
||||
NTAPI
|
||||
KiComputeReciprocal(IN LONG Divisor,
|
||||
OUT PUCHAR Shift)
|
||||
{
|
||||
LARGE_INTEGER Reciprocal = {{0}};
|
||||
LONG BitCount = 0, Remainder = 1;
|
||||
|
||||
/* Start by calculating the remainder */
|
||||
while (Reciprocal.HighPart >= 0)
|
||||
{
|
||||
/* Increase the loop (bit) count */
|
||||
BitCount++;
|
||||
|
||||
/* Calculate the current fraction */
|
||||
Reciprocal.HighPart = (Reciprocal.HighPart << 1) |
|
||||
(Reciprocal.LowPart >> 31);
|
||||
Reciprocal.LowPart <<= 1;
|
||||
|
||||
/* Double the remainder and see if we went past the divisor */
|
||||
Remainder <<= 1;
|
||||
if (Remainder >= Divisor)
|
||||
{
|
||||
/* Set the low-bit and calculate the new remainder */
|
||||
Remainder -= Divisor;
|
||||
Reciprocal.LowPart |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we have a remainder */
|
||||
if (Remainder)
|
||||
{
|
||||
/* Check if the current fraction value is too large */
|
||||
if ((Reciprocal.LowPart == 0xFFFFFFFF) &&
|
||||
(Reciprocal.HighPart == 0xFFFFFFFF))
|
||||
{
|
||||
/* Set the high bit and reduce the bit count */
|
||||
Reciprocal.LowPart = 0;
|
||||
Reciprocal.HighPart = 0x80000000;
|
||||
BitCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if only the lowest bits got too large */
|
||||
if (Reciprocal.LowPart == 0xFFFFFFFF)
|
||||
{
|
||||
/* Reset them and increase the high bits instead */
|
||||
Reciprocal.LowPart = 0;
|
||||
Reciprocal.HighPart++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* All is well, increase the low bits */
|
||||
Reciprocal.LowPart++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now calculate the actual shift and return the reciprocal */
|
||||
*Shift = (UCHAR)BitCount - 64;
|
||||
return Reciprocal;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitSpinLocks(IN PKPRCB Prcb,
|
||||
IN CCHAR Number)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* Initialize Dispatcher Fields */
|
||||
Prcb->QueueIndex = 1;
|
||||
Prcb->ReadySummary = 0;
|
||||
Prcb->DeferredReadyListHead.Next = NULL;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
/* Initialize the ready list */
|
||||
InitializeListHead(&Prcb->DispatcherReadyListHead[i]);
|
||||
}
|
||||
|
||||
/* Initialize DPC Fields */
|
||||
InitializeListHead(&Prcb->DpcData[DPC_NORMAL].DpcListHead);
|
||||
KeInitializeSpinLock(&Prcb->DpcData[DPC_NORMAL].DpcLock);
|
||||
Prcb->DpcData[DPC_NORMAL].DpcQueueDepth = 0;
|
||||
Prcb->DpcData[DPC_NORMAL].DpcCount = 0;
|
||||
Prcb->DpcRoutineActive = FALSE;
|
||||
Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
|
||||
Prcb->MinimumDpcRate = KiMinimumDpcRate;
|
||||
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
|
||||
KeInitializeDpc(&Prcb->CallDpc, NULL, NULL);
|
||||
KeSetTargetProcessorDpc(&Prcb->CallDpc, Number);
|
||||
KeSetImportanceDpc(&Prcb->CallDpc, HighImportance);
|
||||
|
||||
/* Initialize the Wait List Head */
|
||||
InitializeListHead(&Prcb->WaitListHead);
|
||||
|
||||
/* Initialize Queued Spinlocks */
|
||||
Prcb->LockQueue[LockQueueDispatcherLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueDispatcherLock].Lock = &KiDispatcherLock;
|
||||
Prcb->LockQueue[LockQueueExpansionLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueExpansionLock].Lock = NULL;
|
||||
Prcb->LockQueue[LockQueuePfnLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueuePfnLock].Lock = &MmPfnLock;
|
||||
Prcb->LockQueue[LockQueueSystemSpaceLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueSystemSpaceLock].Lock = &MmSystemSpaceLock;
|
||||
Prcb->LockQueue[LockQueueBcbLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueBcbLock].Lock = &CcBcbSpinLock;
|
||||
Prcb->LockQueue[LockQueueMasterLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueMasterLock].Lock = &CcMasterSpinLock;
|
||||
Prcb->LockQueue[LockQueueVacbLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueVacbLock].Lock = &CcVacbSpinLock;
|
||||
Prcb->LockQueue[LockQueueWorkQueueLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueWorkQueueLock].Lock = &CcWorkQueueSpinLock;
|
||||
Prcb->LockQueue[LockQueueNonPagedPoolLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueNonPagedPoolLock].Lock = &NonPagedPoolLock;
|
||||
Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Lock = &MmNonPagedPoolLock;
|
||||
Prcb->LockQueue[LockQueueIoCancelLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueIoCancelLock].Lock = &IopCancelSpinLock;
|
||||
Prcb->LockQueue[LockQueueIoVpbLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueIoVpbLock].Lock = &IopVpbSpinLock;
|
||||
Prcb->LockQueue[LockQueueIoDatabaseLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueIoDatabaseLock].Lock = &IopDatabaseLock;
|
||||
Prcb->LockQueue[LockQueueIoCompletionLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueIoCompletionLock].Lock = &IopCompletionLock;
|
||||
Prcb->LockQueue[LockQueueNtfsStructLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueNtfsStructLock].Lock = &NtfsStructLock;
|
||||
Prcb->LockQueue[LockQueueAfdWorkQueueLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueAfdWorkQueueLock].Lock = &AfdWorkQueueSpinLock;
|
||||
Prcb->LockQueue[LockQueueUnusedSpare16].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueUnusedSpare16].Lock = NULL;
|
||||
|
||||
/* Loop timer locks */
|
||||
for (i = 0; i < LOCK_QUEUE_TIMER_TABLE_LOCKS; i++)
|
||||
{
|
||||
/* Initialize the lock and setup the Queued Spinlock */
|
||||
KeInitializeSpinLock(&KiTimerTableLock[i]);
|
||||
Prcb->LockQueue[i].Next = NULL;
|
||||
Prcb->LockQueue[i].Lock = &KiTimerTableLock[i];
|
||||
}
|
||||
|
||||
/* Check if this is the boot CPU */
|
||||
if (!Number)
|
||||
{
|
||||
/* Initialize the lock themselves */
|
||||
KeInitializeSpinLock(&KiDispatcherLock);
|
||||
KeInitializeSpinLock(&KiReverseStallIpiLock);
|
||||
KeInitializeSpinLock(&MmPfnLock);
|
||||
KeInitializeSpinLock(&MmSystemSpaceLock);
|
||||
KeInitializeSpinLock(&CcBcbSpinLock);
|
||||
KeInitializeSpinLock(&CcMasterSpinLock);
|
||||
KeInitializeSpinLock(&CcVacbSpinLock);
|
||||
KeInitializeSpinLock(&CcWorkQueueSpinLock);
|
||||
KeInitializeSpinLock(&IopCancelSpinLock);
|
||||
KeInitializeSpinLock(&IopCompletionLock);
|
||||
KeInitializeSpinLock(&IopDatabaseLock);
|
||||
KeInitializeSpinLock(&IopVpbSpinLock);
|
||||
KeInitializeSpinLock(&NonPagedPoolLock);
|
||||
KeInitializeSpinLock(&MmNonPagedPoolLock);
|
||||
KeInitializeSpinLock(&NtfsStructLock);
|
||||
KeInitializeSpinLock(&AfdWorkQueueSpinLock);
|
||||
KeInitializeDispatcher(); // ROS OLD DISPATCHER
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializePcr(IN ULONG ProcessorNumber,
|
||||
IN PKIPCR Pcr,
|
||||
IN PKIDTENTRY Idt,
|
||||
IN PKGDTENTRY Gdt,
|
||||
IN PKTSS Tss,
|
||||
IN PKTHREAD IdleThread,
|
||||
IN PVOID DpcStack)
|
||||
{
|
||||
/* Setup the TIB */
|
||||
Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
|
||||
Pcr->NtTib.StackBase = 0;
|
||||
Pcr->NtTib.StackLimit = 0;
|
||||
Pcr->NtTib.Self = 0;
|
||||
|
||||
/* Set the Current Thread */
|
||||
//Pcr->PrcbData.CurrentThread = IdleThread;
|
||||
|
||||
/* Set pointers to ourselves */
|
||||
Pcr->Self = (PKPCR)Pcr;
|
||||
Pcr->Prcb = &Pcr->PrcbData;
|
||||
|
||||
/* Set the PCR Version */
|
||||
Pcr->MajorVersion = PCR_MAJOR_VERSION;
|
||||
Pcr->MinorVersion = PCR_MINOR_VERSION;
|
||||
|
||||
/* Set the PCRB Version */
|
||||
Pcr->PrcbData.MajorVersion = 1;
|
||||
Pcr->PrcbData.MinorVersion = 1;
|
||||
|
||||
/* Set the Build Type */
|
||||
Pcr->PrcbData.BuildType = 0;
|
||||
|
||||
/* Set the Processor Number and current Processor Mask */
|
||||
Pcr->PrcbData.Number = (UCHAR)ProcessorNumber;
|
||||
Pcr->PrcbData.SetMember = 1 << ProcessorNumber;
|
||||
|
||||
/* Set the PRCB for this Processor */
|
||||
KiProcessorBlock[ProcessorNumber] = Pcr->Prcb;
|
||||
|
||||
/* Start us out at PASSIVE_LEVEL */
|
||||
Pcr->Irql = PASSIVE_LEVEL;
|
||||
|
||||
/* Set the GDI, IDT, TSS and DPC Stack */
|
||||
Pcr->GDT = (PVOID)Gdt;
|
||||
Pcr->IDT = Idt;
|
||||
Pcr->TSS = Tss;
|
||||
Pcr->PrcbData.DpcStack = DpcStack;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||
IN PKTHREAD InitThread,
|
||||
IN PVOID IdleStack,
|
||||
IN PKPRCB Prcb,
|
||||
IN CCHAR Number,
|
||||
IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
BOOLEAN NpxPresent;
|
||||
ULONG FeatureBits;
|
||||
LARGE_INTEGER PageDirectory;
|
||||
PVOID DpcStack;
|
||||
|
||||
/* Detect and set the CPU Type */
|
||||
KiSetProcessorType();
|
||||
|
||||
/* Set CR0 features based on detected CPU */
|
||||
KiSetCR0Bits();
|
||||
|
||||
/* Check if an FPU is present */
|
||||
NpxPresent = KiIsNpxPresent();
|
||||
|
||||
/* Initialize the Power Management Support for this PRCB */
|
||||
PoInitializePrcb(Prcb);
|
||||
|
||||
/* Bugcheck if this is a 386 CPU */
|
||||
if (Prcb->CpuType == 3) KeBugCheckEx(0x5D, 0x386, 0, 0, 0);
|
||||
|
||||
/* Get the processor features for the CPU */
|
||||
FeatureBits = KiGetFeatureBits();
|
||||
|
||||
/* Save feature bits */
|
||||
Prcb->FeatureBits = FeatureBits;
|
||||
|
||||
/* Get cache line information for this CPU */
|
||||
KiGetCacheInformation();
|
||||
|
||||
/* Initialize spinlocks and DPC data */
|
||||
KiInitSpinLocks(Prcb, Number);
|
||||
|
||||
/* Check if this is the Boot CPU */
|
||||
if (!Number)
|
||||
{
|
||||
/* Set Node Data */
|
||||
KeNodeBlock[0] = &KiNode0;
|
||||
Prcb->ParentNode = KeNodeBlock[0];
|
||||
KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
|
||||
|
||||
/* Set boot-level flags */
|
||||
KeI386NpxPresent = NpxPresent;
|
||||
KeI386CpuType = Prcb->CpuType;
|
||||
KeI386CpuStep = Prcb->CpuStep;
|
||||
KeProcessorArchitecture = 0;
|
||||
KeProcessorLevel = (USHORT)Prcb->CpuType;
|
||||
if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep;
|
||||
KeFeatureBits = FeatureBits;
|
||||
KeI386FxsrPresent = (KeFeatureBits & KF_FXSR) ? TRUE : FALSE;
|
||||
KeI386XMMIPresent = (KeFeatureBits & KF_XMMI) ? TRUE : FALSE;
|
||||
|
||||
/* Set the current MP Master KPRCB to the Boot PRCB */
|
||||
Prcb->MultiThreadSetMaster = Prcb;
|
||||
|
||||
/* Initialize some spinlocks */
|
||||
KeInitializeSpinLock(&KiFreezeExecutionLock);
|
||||
KeInitializeSpinLock(&Ki486CompatibilityLock);
|
||||
|
||||
/* Initialize portable parts of the OS */
|
||||
KiInitSystem();
|
||||
|
||||
/* Initialize the Idle Process and the Process Listhead */
|
||||
InitializeListHead(&KiProcessListHead);
|
||||
PageDirectory.QuadPart = 0;
|
||||
KeInitializeProcess(InitProcess,
|
||||
0,
|
||||
0xFFFFFFFF,
|
||||
PageDirectory);
|
||||
InitProcess->QuantumReset = MAXCHAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME */
|
||||
DPRINT1("SMP Boot support not yet present\n");
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Setup the Idle Thread */
|
||||
KeInitializeThread(InitProcess,
|
||||
InitThread,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
IdleStack);
|
||||
#endif
|
||||
InitThread->NextProcessor = Number;
|
||||
InitThread->Priority = HIGH_PRIORITY;
|
||||
InitThread->State = Running;
|
||||
InitThread->Affinity = 1 << Number;
|
||||
InitThread->WaitIrql = DISPATCH_LEVEL;
|
||||
InitProcess->ActiveProcessors = 1 << Number;
|
||||
|
||||
/* Set up the thread-related fields in the PRCB */
|
||||
//Prcb->CurrentThread = InitThread;
|
||||
Prcb->NextThread = NULL;
|
||||
//Prcb->IdleThread = InitThread;
|
||||
|
||||
/* Initialize the Kernel Executive */
|
||||
ExpInitializeExecutive();
|
||||
|
||||
/* Only do this on the boot CPU */
|
||||
if (!Number)
|
||||
{
|
||||
/* Calculate the time reciprocal */
|
||||
KiTimeIncrementReciprocal =
|
||||
KiComputeReciprocal(KeMaximumIncrement,
|
||||
&KiTimeIncrementShiftCount);
|
||||
|
||||
/* Update DPC Values in case they got updated by the executive */
|
||||
Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
|
||||
Prcb->MinimumDpcRate = KiMinimumDpcRate;
|
||||
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
|
||||
|
||||
/* Allocate the DPC Stack */
|
||||
DpcStack = MmCreateKernelStack(FALSE);
|
||||
if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
|
||||
Prcb->DpcStack = DpcStack;
|
||||
|
||||
/* Allocate the IOPM save area. */
|
||||
Ki386IopmSaveArea = ExAllocatePoolWithTag(PagedPool,
|
||||
PAGE_SIZE * 2,
|
||||
TAG('K', 'e', ' ', ' '));
|
||||
if (!Ki386IopmSaveArea)
|
||||
{
|
||||
/* Bugcheck. We need this for V86/VDM support. */
|
||||
KeBugCheckEx(NO_PAGES_AVAILABLE, 2, PAGE_SIZE * 2, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free Initial Memory */
|
||||
MiFreeInitMemory();
|
||||
|
||||
while (1)
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
Timeout.QuadPart = 0x7fffffffffffffffLL;
|
||||
KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
|
||||
}
|
||||
|
||||
/* Bug Check and loop forever if anything failed */
|
||||
KEBUGCHECK(0);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
ULONG Cpu;
|
||||
PKIPCR Pcr = (PKIPCR)KPCR_BASE;
|
||||
PKPRCB Prcb;
|
||||
|
||||
/* Save the loader block and get the current CPU */
|
||||
//KeLoaderBlock = LoaderBlock;
|
||||
Cpu = KeNumberProcessors;
|
||||
if (!Cpu)
|
||||
{
|
||||
/* If this is the boot CPU, set FS and the CPU Number*/
|
||||
Ke386SetFs(KGDT_R0_PCR);
|
||||
KeGetPcr()->Number = Cpu;
|
||||
}
|
||||
|
||||
/* Skip initial setup if this isn't the Boot CPU */
|
||||
if (Cpu) goto AppCpuInit;
|
||||
|
||||
/* Setup the boot (Freeldr should've done), double fault and NMI TSS */
|
||||
Ki386InitializeTss();
|
||||
|
||||
/* Initialize the PCR */
|
||||
RtlZeroMemory(Pcr, PAGE_SIZE);
|
||||
KiInitializePcr(Cpu,
|
||||
Pcr,
|
||||
KiIdt,
|
||||
KiBootGdt,
|
||||
&KiBootTss,
|
||||
&KiInitialThread.Tcb,
|
||||
KiDoubleFaultStack);
|
||||
|
||||
/* Set us as the current process */
|
||||
KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
|
||||
|
||||
/* Clear DR6/7 to cleanup bootloader debugging */
|
||||
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr6 = 0;
|
||||
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr7 = 0;
|
||||
|
||||
/* Load Ring 3 selectors for DS/ES */
|
||||
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
||||
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
|
||||
|
||||
/* Setup CPU-related fields */
|
||||
AppCpuInit:
|
||||
Prcb = Pcr->Prcb;
|
||||
Pcr->Number = Cpu;
|
||||
Pcr->SetMember = 1 << Cpu;
|
||||
Pcr->SetMemberCopy = 1 << Cpu;
|
||||
Prcb->SetMember = 1 << Cpu;
|
||||
|
||||
/* Initialize the Processor with HAL */
|
||||
HalInitializeProcessor(Cpu, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
|
||||
|
||||
/* Set active processors */
|
||||
KeActiveProcessors |= Pcr->SetMember;
|
||||
KeNumberProcessors++;
|
||||
|
||||
/* Initialize the Debugger for the Boot CPU */
|
||||
if (!Cpu) KdInitSystem (0, &KeLoaderBlock);
|
||||
|
||||
/* Check for break-in */
|
||||
if (KdPollBreakIn()) DbgBreakPointWithStatus(1);
|
||||
|
||||
/* Raise to HIGH_LEVEL */
|
||||
KfRaiseIrql(HIGH_LEVEL);
|
||||
|
||||
/* Call main kernel intialization */
|
||||
KiInitializeKernel(&KiInitialProcess.Pcb,
|
||||
&KiInitialThread.Tcb,
|
||||
P0BootStack,
|
||||
Prcb,
|
||||
Cpu,
|
||||
LoaderBlock);
|
||||
}
|
||||
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
NTAPI
|
||||
KeInit2(VOID)
|
||||
{
|
||||
ULONG Protect;
|
||||
|
||||
/* Check if Fxsr was found */
|
||||
if (KeI386FxsrPresent)
|
||||
{
|
||||
/* Enable it. FIXME: Send an IPI */
|
||||
Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSFXSR);
|
||||
|
||||
/* Check if XMM was found too */
|
||||
if (KeI386XMMIPresent)
|
||||
{
|
||||
/* Enable it: FIXME: Send an IPI. */
|
||||
Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);
|
||||
|
||||
/* FIXME: Implement and enable XMM Page Zeroing for Mm */
|
||||
}
|
||||
}
|
||||
|
||||
if (KeFeatureBits & KF_GLOBAL_PAGE)
|
||||
{
|
||||
ULONG Flags;
|
||||
/* Enable global pages */
|
||||
Ke386GlobalPagesEnabled = TRUE;
|
||||
Ke386SaveFlags(Flags);
|
||||
Ke386DisableInterrupts();
|
||||
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
|
||||
Ke386RestoreFlags(Flags);
|
||||
}
|
||||
|
||||
if (KeFeatureBits & KF_FAST_SYSCALL)
|
||||
{
|
||||
extern void KiFastCallEntry(void);
|
||||
|
||||
/* CS Selector of the target segment. */
|
||||
Ke386Wrmsr(0x174, KGDT_R0_CODE, 0);
|
||||
/* Target ESP. */
|
||||
Ke386Wrmsr(0x175, 0, 0);
|
||||
/* Target EIP. */
|
||||
Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0);
|
||||
}
|
||||
|
||||
/* Does the CPU Support 'prefetchnta' (SSE) */
|
||||
if(KeFeatureBits & KF_XMMI)
|
||||
{
|
||||
Protect = MmGetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal);
|
||||
MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect | PAGE_IS_WRITABLE);
|
||||
/* Replace the ret by a nop */
|
||||
*(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90;
|
||||
MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect);
|
||||
}
|
||||
|
||||
/* Set IDT to writable */
|
||||
Protect = MmGetPageProtect(NULL, (PVOID)KiIdt);
|
||||
MmSetPageProtect(NULL, (PVOID)KiIdt, Protect | PAGE_IS_WRITABLE);
|
||||
}
|
||||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ke/krnlinit.c
|
||||
* PURPOSE: Portable part of kernel initialization
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#include <internal/napi.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* PRCB Array */
|
||||
PKPRCB KiProcessorBlock[MAXIMUM_PROCESSORS];
|
||||
|
||||
/* NUMA Node Support */
|
||||
KNODE KiNode0;
|
||||
PKNODE KeNodeBlock[1];
|
||||
UCHAR KeNumberNodes = 1;
|
||||
UCHAR KeProcessNodeSeed;
|
||||
|
||||
/* Initial Process and Thread */
|
||||
ETHREAD KiInitialThread;
|
||||
EPROCESS KiInitialProcess;
|
||||
|
||||
/* System-defined Spinlocks */
|
||||
KSPIN_LOCK KiDispatcherLock;
|
||||
KSPIN_LOCK MmPfnLock;
|
||||
KSPIN_LOCK MmSystemSpaceLock;
|
||||
KSPIN_LOCK CcBcbSpinLock;
|
||||
KSPIN_LOCK CcMasterSpinLock;
|
||||
KSPIN_LOCK CcVacbSpinLock;
|
||||
KSPIN_LOCK CcWorkQueueSpinLock;
|
||||
KSPIN_LOCK NonPagedPoolLock;
|
||||
KSPIN_LOCK MmNonPagedPoolLock;
|
||||
KSPIN_LOCK IopCancelSpinLock;
|
||||
KSPIN_LOCK IopVpbSpinLock;
|
||||
KSPIN_LOCK IopDatabaseLock;
|
||||
KSPIN_LOCK IopCompletionLock;
|
||||
KSPIN_LOCK NtfsStructLock;
|
||||
KSPIN_LOCK AfdWorkQueueSpinLock;
|
||||
KSPIN_LOCK KiTimerTableLock[16];
|
||||
KSPIN_LOCK KiReverseStallIpiLock;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitSystem(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* Initialize Bugcheck Callback data */
|
||||
InitializeListHead(&BugcheckCallbackListHead);
|
||||
InitializeListHead(&BugcheckReasonCallbackListHead);
|
||||
KeInitializeSpinLock(&BugCheckCallbackLock);
|
||||
|
||||
/* Initialize the Timer Expiration DPC */
|
||||
KeInitializeDpc(&KiExpireTimerDpc, KiExpireTimers, NULL);
|
||||
KeSetTargetProcessorDpc(&KiExpireTimerDpc, 0);
|
||||
|
||||
/* Initialize Profiling data */
|
||||
KeInitializeSpinLock(&KiProfileLock);
|
||||
InitializeListHead(&KiProfileListHead);
|
||||
InitializeListHead(&KiProfileSourceListHead);
|
||||
|
||||
/* Loop the timer table */
|
||||
for (i = 0; i < TIMER_TABLE_SIZE; i++)
|
||||
{
|
||||
/* Initialize the list and entries */
|
||||
InitializeListHead(&KiTimerTableListHead[i].Entry);
|
||||
KiTimerTableListHead[i].Time.HighPart = 0xFFFFFFFF;
|
||||
KiTimerTableListHead[i].Time.LowPart = 0;
|
||||
}
|
||||
|
||||
/* Initialize old-style list */
|
||||
InitializeListHead(&KiTimerListHead);
|
||||
|
||||
/* Initialize the Swap event and all swap lists */
|
||||
KeInitializeEvent(&KiSwapEvent, SynchronizationEvent, FALSE);
|
||||
InitializeListHead(&KiProcessInSwapListHead);
|
||||
InitializeListHead(&KiProcessOutSwapListHead);
|
||||
InitializeListHead(&KiStackInSwapListHead);
|
||||
|
||||
/* Initialize the mutex for generic DPC calls */
|
||||
KeInitializeMutex(&KiGenericCallDpcMutex, 0);
|
||||
|
||||
/* Initialize the syscall table */
|
||||
KeServiceDescriptorTable[0].Base = MainSSDT;
|
||||
KeServiceDescriptorTable[0].Count = NULL;
|
||||
KeServiceDescriptorTable[0].Limit = NUMBER_OF_SYSCALLS;
|
||||
KeServiceDescriptorTable[1].Limit = 0;
|
||||
KeServiceDescriptorTable[0].Number = MainSSPT;
|
||||
|
||||
/* Copy the the current table into the shadow table for win32k */
|
||||
RtlCopyMemory(KeServiceDescriptorTableShadow,
|
||||
KeServiceDescriptorTable,
|
||||
sizeof(KeServiceDescriptorTable));
|
||||
}
|
||||
|
||||
LARGE_INTEGER
|
||||
NTAPI
|
||||
KiComputeReciprocal(IN LONG Divisor,
|
||||
OUT PUCHAR Shift)
|
||||
{
|
||||
LARGE_INTEGER Reciprocal = {{0}};
|
||||
LONG BitCount = 0, Remainder = 1;
|
||||
|
||||
/* Start by calculating the remainder */
|
||||
while (Reciprocal.HighPart >= 0)
|
||||
{
|
||||
/* Increase the loop (bit) count */
|
||||
BitCount++;
|
||||
|
||||
/* Calculate the current fraction */
|
||||
Reciprocal.HighPart = (Reciprocal.HighPart << 1) |
|
||||
(Reciprocal.LowPart >> 31);
|
||||
Reciprocal.LowPart <<= 1;
|
||||
|
||||
/* Double the remainder and see if we went past the divisor */
|
||||
Remainder <<= 1;
|
||||
if (Remainder >= Divisor)
|
||||
{
|
||||
/* Set the low-bit and calculate the new remainder */
|
||||
Remainder -= Divisor;
|
||||
Reciprocal.LowPart |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we have a remainder */
|
||||
if (Remainder)
|
||||
{
|
||||
/* Check if the current fraction value is too large */
|
||||
if ((Reciprocal.LowPart == 0xFFFFFFFF) &&
|
||||
(Reciprocal.HighPart == 0xFFFFFFFF))
|
||||
{
|
||||
/* Set the high bit and reduce the bit count */
|
||||
Reciprocal.LowPart = 0;
|
||||
Reciprocal.HighPart = 0x80000000;
|
||||
BitCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if only the lowest bits got too large */
|
||||
if (Reciprocal.LowPart == 0xFFFFFFFF)
|
||||
{
|
||||
/* Reset them and increase the high bits instead */
|
||||
Reciprocal.LowPart = 0;
|
||||
Reciprocal.HighPart++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* All is well, increase the low bits */
|
||||
Reciprocal.LowPart++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now calculate the actual shift and return the reciprocal */
|
||||
*Shift = (UCHAR)BitCount - 64;
|
||||
return Reciprocal;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitSpinLocks(IN PKPRCB Prcb,
|
||||
IN CCHAR Number)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* Initialize Dispatcher Fields */
|
||||
Prcb->QueueIndex = 1;
|
||||
Prcb->ReadySummary = 0;
|
||||
Prcb->DeferredReadyListHead.Next = NULL;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
/* Initialize the ready list */
|
||||
InitializeListHead(&Prcb->DispatcherReadyListHead[i]);
|
||||
}
|
||||
|
||||
/* Initialize DPC Fields */
|
||||
InitializeListHead(&Prcb->DpcData[DPC_NORMAL].DpcListHead);
|
||||
KeInitializeSpinLock(&Prcb->DpcData[DPC_NORMAL].DpcLock);
|
||||
Prcb->DpcData[DPC_NORMAL].DpcQueueDepth = 0;
|
||||
Prcb->DpcData[DPC_NORMAL].DpcCount = 0;
|
||||
Prcb->DpcRoutineActive = FALSE;
|
||||
Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
|
||||
Prcb->MinimumDpcRate = KiMinimumDpcRate;
|
||||
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
|
||||
KeInitializeDpc(&Prcb->CallDpc, NULL, NULL);
|
||||
KeSetTargetProcessorDpc(&Prcb->CallDpc, Number);
|
||||
KeSetImportanceDpc(&Prcb->CallDpc, HighImportance);
|
||||
|
||||
/* Initialize the Wait List Head */
|
||||
InitializeListHead(&Prcb->WaitListHead);
|
||||
|
||||
/* Initialize Queued Spinlocks */
|
||||
Prcb->LockQueue[LockQueueDispatcherLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueDispatcherLock].Lock = &KiDispatcherLock;
|
||||
Prcb->LockQueue[LockQueueExpansionLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueExpansionLock].Lock = NULL;
|
||||
Prcb->LockQueue[LockQueuePfnLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueuePfnLock].Lock = &MmPfnLock;
|
||||
Prcb->LockQueue[LockQueueSystemSpaceLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueSystemSpaceLock].Lock = &MmSystemSpaceLock;
|
||||
Prcb->LockQueue[LockQueueBcbLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueBcbLock].Lock = &CcBcbSpinLock;
|
||||
Prcb->LockQueue[LockQueueMasterLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueMasterLock].Lock = &CcMasterSpinLock;
|
||||
Prcb->LockQueue[LockQueueVacbLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueVacbLock].Lock = &CcVacbSpinLock;
|
||||
Prcb->LockQueue[LockQueueWorkQueueLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueWorkQueueLock].Lock = &CcWorkQueueSpinLock;
|
||||
Prcb->LockQueue[LockQueueNonPagedPoolLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueNonPagedPoolLock].Lock = &NonPagedPoolLock;
|
||||
Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Lock = &MmNonPagedPoolLock;
|
||||
Prcb->LockQueue[LockQueueIoCancelLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueIoCancelLock].Lock = &IopCancelSpinLock;
|
||||
Prcb->LockQueue[LockQueueIoVpbLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueIoVpbLock].Lock = &IopVpbSpinLock;
|
||||
Prcb->LockQueue[LockQueueIoDatabaseLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueIoDatabaseLock].Lock = &IopDatabaseLock;
|
||||
Prcb->LockQueue[LockQueueIoCompletionLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueIoCompletionLock].Lock = &IopCompletionLock;
|
||||
Prcb->LockQueue[LockQueueNtfsStructLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueNtfsStructLock].Lock = &NtfsStructLock;
|
||||
Prcb->LockQueue[LockQueueAfdWorkQueueLock].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueAfdWorkQueueLock].Lock = &AfdWorkQueueSpinLock;
|
||||
Prcb->LockQueue[LockQueueUnusedSpare16].Next = NULL;
|
||||
Prcb->LockQueue[LockQueueUnusedSpare16].Lock = NULL;
|
||||
|
||||
/* Loop timer locks */
|
||||
for (i = 0; i < LOCK_QUEUE_TIMER_TABLE_LOCKS; i++)
|
||||
{
|
||||
/* Initialize the lock and setup the Queued Spinlock */
|
||||
KeInitializeSpinLock(&KiTimerTableLock[i]);
|
||||
Prcb->LockQueue[i].Next = NULL;
|
||||
Prcb->LockQueue[i].Lock = &KiTimerTableLock[i];
|
||||
}
|
||||
|
||||
/* Check if this is the boot CPU */
|
||||
if (!Number)
|
||||
{
|
||||
/* Initialize the lock themselves */
|
||||
KeInitializeSpinLock(&KiDispatcherLock);
|
||||
KeInitializeSpinLock(&KiReverseStallIpiLock);
|
||||
KeInitializeSpinLock(&MmPfnLock);
|
||||
KeInitializeSpinLock(&MmSystemSpaceLock);
|
||||
KeInitializeSpinLock(&CcBcbSpinLock);
|
||||
KeInitializeSpinLock(&CcMasterSpinLock);
|
||||
KeInitializeSpinLock(&CcVacbSpinLock);
|
||||
KeInitializeSpinLock(&CcWorkQueueSpinLock);
|
||||
KeInitializeSpinLock(&IopCancelSpinLock);
|
||||
KeInitializeSpinLock(&IopCompletionLock);
|
||||
KeInitializeSpinLock(&IopDatabaseLock);
|
||||
KeInitializeSpinLock(&IopVpbSpinLock);
|
||||
KeInitializeSpinLock(&NonPagedPoolLock);
|
||||
KeInitializeSpinLock(&MmNonPagedPoolLock);
|
||||
KeInitializeSpinLock(&NtfsStructLock);
|
||||
KeInitializeSpinLock(&AfdWorkQueueSpinLock);
|
||||
KeInitializeDispatcher(); // ROS OLD DISPATCHER
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Rename and make portable */
|
||||
VOID
|
||||
NTAPI
|
||||
KeInit2(VOID)
|
||||
{
|
||||
ULONG Protect;
|
||||
|
||||
/* Check if Fxsr was found */
|
||||
if (KeI386FxsrPresent)
|
||||
{
|
||||
/* Enable it. FIXME: Send an IPI */
|
||||
Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSFXSR);
|
||||
|
||||
/* Check if XMM was found too */
|
||||
if (KeI386XMMIPresent)
|
||||
{
|
||||
/* Enable it: FIXME: Send an IPI. */
|
||||
Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);
|
||||
|
||||
/* FIXME: Implement and enable XMM Page Zeroing for Mm */
|
||||
}
|
||||
}
|
||||
|
||||
if (KeFeatureBits & KF_GLOBAL_PAGE)
|
||||
{
|
||||
ULONG Flags;
|
||||
/* Enable global pages */
|
||||
Ke386GlobalPagesEnabled = TRUE;
|
||||
Ke386SaveFlags(Flags);
|
||||
Ke386DisableInterrupts();
|
||||
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
|
||||
Ke386RestoreFlags(Flags);
|
||||
}
|
||||
|
||||
if (KeFeatureBits & KF_FAST_SYSCALL)
|
||||
{
|
||||
extern void KiFastCallEntry(void);
|
||||
|
||||
/* CS Selector of the target segment. */
|
||||
Ke386Wrmsr(0x174, KGDT_R0_CODE, 0);
|
||||
/* Target ESP. */
|
||||
Ke386Wrmsr(0x175, 0, 0);
|
||||
/* Target EIP. */
|
||||
Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0);
|
||||
}
|
||||
|
||||
/* Does the CPU Support 'prefetchnta' (SSE) */
|
||||
if(KeFeatureBits & KF_XMMI)
|
||||
{
|
||||
Protect = MmGetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal);
|
||||
MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect | PAGE_IS_WRITABLE);
|
||||
/* Replace the ret by a nop */
|
||||
*(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90;
|
||||
MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect);
|
||||
}
|
||||
|
||||
/* Set IDT to writable */
|
||||
Protect = MmGetPageProtect(NULL, (PVOID)KiIdt);
|
||||
MmSetPageProtect(NULL, (PVOID)KiIdt, Protect | PAGE_IS_WRITABLE);
|
||||
}
|
|
@ -7,13 +7,13 @@
|
|||
* Gregor Anich
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
/* INCLUDES ********(*********************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
LIST_ENTRY KiProcessListHead;
|
||||
LIST_ENTRY KiProcessInSwapListHead, KiProcessOutSwapListHead;
|
||||
|
@ -23,6 +23,11 @@ KEVENT KiSwapEvent;
|
|||
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES];
|
||||
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES];
|
||||
|
||||
PVOID KeUserApcDispatcher;
|
||||
PVOID KeUserCallbackDispatcher;
|
||||
PVOID KeUserExceptionDispatcher;
|
||||
PVOID KeRaiseUserExceptionDispatcher;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
PKPROCESS
|
||||
|
|
|
@ -70,7 +70,6 @@ __inline LARGE_INTEGER PTE_TO_PAGE(ULONG npage)
|
|||
|
||||
extern BOOLEAN Ke386Pae;
|
||||
extern BOOLEAN Ke386NoExecute;
|
||||
extern BOOLEAN Ke386GlobalPagesEnabled;
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
|
|
|
@ -26,14 +26,14 @@
|
|||
<directory name="ke">
|
||||
<if property="ARCH" value="i386">
|
||||
<directory name="i386">
|
||||
<file first="true">main_asm.S</file>
|
||||
<file first="true">boot.S</file>
|
||||
<file>abios.c</file>
|
||||
<file>cpu.c</file>
|
||||
<file>ctxswitch.S</file>
|
||||
<file>clock.S</file>
|
||||
<file>exp.c</file>
|
||||
<!-- <file>irq.c</file> -->
|
||||
<file>kernel.c</file>
|
||||
<file>kiinit.c</file>
|
||||
<file>ldt.c</file>
|
||||
<file>thread.c</file>
|
||||
<file>trap.s</file>
|
||||
|
@ -49,12 +49,13 @@
|
|||
<file>dpc.c</file>
|
||||
<file>event.c</file>
|
||||
<file>exception.c</file>
|
||||
<file>freeldr.c</file>
|
||||
<file>gate.c</file>
|
||||
<file>gmutex.c</file>
|
||||
<file>ipi.c</file>
|
||||
<file>kqueue.c</file>
|
||||
<file>krnlinit.c</file>
|
||||
<file>kthread.c</file>
|
||||
<file>main.c</file>
|
||||
<file>mutex.c</file>
|
||||
<file>process.c</file>
|
||||
<file>profile.c</file>
|
||||
|
|
Loading…
Reference in a new issue