diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index b445f99d80b..beb7392b542 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -736,8 +736,8 @@ ExPhase2Init(PVOID Context) /* Set us at maximum priority */ KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY); - /* Initialize the second stage of the kernel */ - KeInit2(); + /* Initialize the later stages of the kernel */ + KeInitSystem(); /* Initialize all processors */ HalAllProcessorsStarted(); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index d901f374913..d36d30142d1 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -116,6 +116,7 @@ extern ULONG KiMaximumDpcQueueDepth; extern ULONG KiMinimumDpcRate; extern ULONG KiAdjustDpcThreshold; extern ULONG KiIdealDpcRate; +extern BOOLEAN KeThreadDpcEnable; extern LARGE_INTEGER KiTimeIncrementReciprocal; extern UCHAR KiTimeIncrementShiftCount; extern LIST_ENTRY BugcheckCallbackListHead, BugcheckReasonCallbackListHead; @@ -135,6 +136,7 @@ extern ULONG KiMask32Array[MAXIMUM_PRIORITY]; extern ULONG KiIdleSummary; extern VOID KiTrap8(VOID); extern VOID KiTrap2(VOID); +extern VOID KiFastCallEntry(VOID); extern PVOID KeUserApcDispatcher; extern PVOID KeUserCallbackDispatcher; extern PVOID KeUserExceptionDispatcher; @@ -550,10 +552,6 @@ KiWaitTest( KPRIORITY Increment ); -PULONG -NTAPI -KeGetStackTopThread(struct _ETHREAD* Thread); - VOID NTAPI KeContextToTrapFrame( @@ -636,6 +634,10 @@ KiActivateWaiterQueue(IN PKQUEUE Queue); /* INITIALIZATION FUNCTIONS *************************************************/ +VOID +NTAPI +KeInitSystem(VOID); + VOID NTAPI KeInitExceptions(VOID); @@ -646,34 +648,18 @@ KeInitInterrupts(VOID); VOID NTAPI -KeInitTimer(VOID); - -VOID -NTAPI -KeInitDispatcher(VOID); +KiInitializeBugCheck(VOID); VOID NTAPI KiInitializeSystemClock(VOID); -VOID -NTAPI -KiInitializeBugCheck(VOID); - -VOID -NTAPI -Phase1Initialization(PVOID Context); - VOID NTAPI KiSystemStartup( IN PLOADER_PARAMETER_BLOCK LoaderBlock ); -VOID -NTAPI -KeInit2(VOID); - BOOLEAN NTAPI KiDeliverUserApc(PKTRAP_FRAME TrapFrame); @@ -710,33 +696,6 @@ KeTrapFrameToContext( IN OUT PCONTEXT Context ); -VOID -NTAPI -KeApplicationProcessorInit(VOID); - -VOID -NTAPI -KePrepareForApplicationProcessorInit(ULONG id); - -ULONG -NTAPI -KiUserTrapHandler( - PKTRAP_FRAME Tf, - ULONG ExceptionNr, - PVOID Cr2 -); - -VOID -NTAPI -KePushAndStackSwitchAndSysRet( - ULONG Push, - PVOID NewStack -); - -VOID -NTAPI -KeStackSwitchAndRet(PVOID NewStack); - VOID NTAPI KeBugCheckWithTf( @@ -813,7 +772,6 @@ KeI386VdmInitialize( VOID ); - VOID NTAPI KiInitializeMachineType( @@ -866,6 +824,48 @@ KiGetUserModeStackAddress( VOID ); +ULONG_PTR +NTAPI +Ki386EnableGlobalPage(IN volatile ULONG_PTR Context); + +VOID +NTAPI +KiInitializePAT(VOID); + +VOID +NTAPI +KiInitializeMTRR(IN BOOLEAN FinalCpu); + +VOID +NTAPI +KiAmdK6InitializeMTRR(VOID); + +VOID +NTAPI +KiRestoreFastSyscallReturnState(VOID); + +ULONG_PTR +NTAPI +Ki386EnableDE(IN ULONG_PTR Context); + +ULONG_PTR +NTAPI +Ki386EnableFxsr(IN ULONG_PTR Context); + +ULONG_PTR +NTAPI +Ki386EnableXMMIExceptions(IN ULONG_PTR Context); + +VOID +NTAPI +KiInitMachineDependent(VOID); + +VOID +WRMSR( + IN ULONG Register, + IN LONGLONG Value +); + #include "ke_x.h" #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */ diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 926a874f6f8..0788738a08b 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -22,6 +22,7 @@ ULONG KiMaximumDpcQueueDepth = 4; ULONG KiMinimumDpcRate = 3; ULONG KiAdjustDpcThreshold = 20; ULONG KiIdealDpcRate = 20; +BOOLEAN KeThreadDpcEnable; KMUTEX KiGenericCallDpcMutex; /* PRIVATE FUNCTIONS *********************************************************/ diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 7f87e9ec989..65164978018 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -63,7 +63,6 @@ ULONG KeI386XMMIPresent = 0; ULONG KeI386FxsrPresent = 0; ULONG KeI386MachineType; ULONG Ke386Pae = FALSE; -ULONG Ke386GlobalPagesEnabled = FALSE; ULONG Ke386NoExecute = FALSE; BOOLEAN KiI386PentiumLockErrataPresent; ULONG KeLargestCacheLine = 0x40; @@ -760,6 +759,60 @@ KiInitializeMachineType(VOID) KeI386MachineType = KeLoaderBlock->u.I386.MachineType & 0x000FF; } +ULONG_PTR +NTAPI +KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context) +{ + /* Set CS and ESP */ + Ke386Wrmsr(0x174, KGDT_R0_CODE, 0); + Ke386Wrmsr(0x175, 0, 0); + + /* Set LSTAR */ + Ke386Wrmsr(0x176, KiFastCallEntry, 0); + return 0; +} + +VOID +NTAPI +KiRestoreFastSyscallReturnState(VOID) +{ + /* FIXME: NT has support for SYSCALL, IA64-SYSENTER, etc. */ + + /* Check if the CPU Supports fast system call */ + if (KeFeatureBits & KF_FAST_SYSCALL) + { + /* Do an IPI to enable it */ + KeIpiGenericCall(KiLoadFastSyscallMachineSpecificRegisters, 0); + } +} + +ULONG_PTR +NTAPI +Ki386EnableDE(IN ULONG_PTR Context) +{ + /* Enable DE */ + Ke386SetCr4(Ke386GetCr4() | CR4_DE); + return 0; +} + +ULONG_PTR +NTAPI +Ki386EnableFxsr(IN ULONG_PTR Context) +{ + /* Enable FXSR */ + Ke386SetCr4(Ke386GetCr4() | CR4_FXSR); + return 0; +} + +ULONG_PTR +NTAPI +Ki386EnableXMMIExceptions(IN ULONG_PTR Context) +{ + /* FIXME: Support this */ + DPRINT1("Your machine supports XMMI exceptions but ReactOS doesn't\n"); + return 0; +} + /* PUBLIC FUNCTIONS **********************************************************/ /* diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index 8e4f8112349..a94815b8c95 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -20,6 +20,137 @@ KSPIN_LOCK Ki486CompatibilityLock; /* FUNCTIONS *****************************************************************/ +VOID +NTAPI +KiInitMachineDependent(VOID) +{ + ULONG Protect; + ULONG CpuCount; + BOOLEAN FbCaching = FALSE; + NTSTATUS Status; + //ULONG ReturnLength; + ULONG i, Affinity; + + /* Check for large page support */ + if (KeFeatureBits & KF_LARGE_PAGE) + { + /* FIXME: Support this */ + DPRINT1("Your machine supports PGE but ReactOS doesn't yet.\n"); + } + + /* Check for global page support */ + if (KeFeatureBits & KF_GLOBAL_PAGE) + { + /* Do an IPI to enable it on all CPUs */ + CpuCount = KeNumberProcessors; + KeIpiGenericCall(Ki386EnableGlobalPage, (ULONG_PTR)&CpuCount); + } + + /* Check for PAT and/or MTRR support */ + if (KeFeatureBits & (KF_PAT | KF_MTRR)) + { + /* FIXME: ROS HAL Doesn't initialize this! */ +#if 1 + Status = STATUS_UNSUCCESSFUL; +#else + /* Query the HAL to make sure we can use it */ + Status = HalQuerySystemInformation(HalFrameBufferCachingInformation, + sizeof(BOOLEAN), + &FbCaching, + &ReturnLength); +#endif + if ((NT_SUCCESS(Status)) && (FbCaching)) + { + /* We can't, disable it */ + KeFeatureBits &= ~(KF_PAT | KF_MTRR); + } + } + + /* Check for PAT support and enable it */ + if (KeFeatureBits & KF_PAT) KiInitializePAT(); + + /* Check for CR4 support */ + if (KeFeatureBits & KF_CR4) + { + /* Do an IPI call to enable the Debug Exceptions */ + CpuCount = KeNumberProcessors; + KeIpiGenericCall(Ki386EnableDE, (ULONG_PTR)&CpuCount); + } + + /* Check if FXSR was found */ + if (KeFeatureBits & KF_FXSR) + { + /* Do an IPI call to enable the FXSR */ + CpuCount = KeNumberProcessors; + KeIpiGenericCall(Ki386EnableFxsr, (ULONG_PTR)&CpuCount); + + /* Check if XMM was found too */ + if (KeFeatureBits & KF_XMMI) + { + /* Do an IPI call to enable XMMI exceptions */ + CpuCount = KeNumberProcessors; + KeIpiGenericCall(Ki386EnableXMMIExceptions, (ULONG_PTR)&CpuCount); + + /* 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); + } + } + + /* Check for, and enable SYSENTER support */ + KiRestoreFastSyscallReturnState(); + + /* Loop every CPU */ + i = KeActiveProcessors; + for (Affinity = 1; i; Affinity <<= 1) + { + /* Check if this is part of the set */ + if (i & Affinity) + { + /* Run on this CPU */ + i &= ~Affinity; + KeSetSystemAffinityThread(Affinity); + + /* Reset MHz to 0 for this CPU */ + KeGetCurrentPrcb()->MHz = 0; + + /* Check if we can use RDTSC */ + if (KeFeatureBits & KF_RDTSC) + { + /* Start sampling loop */ + for (;;) + { + // + // FIXME: TODO + // + break; + } + } + + /* Check if we have MTRR without PAT */ + if (!(KeFeatureBits & KF_PAT) && (KeFeatureBits & KF_MTRR)) + { + /* Then manually initialize MTRR for the CPU */ + KiInitializeMTRR((BOOLEAN)i); + } + + /* Check if we have AMD MTRR and initialize it for the CPU */ + if (KeFeatureBits & KF_AMDK6MTRR) KiAmdK6InitializeMTRR(); + + /* FIXME: Apply P5 LOCK Errata fixups */ + } + } + + /* Return affinity back to where it was */ + KeRevertToUserAffinityThread(); +} + VOID NTAPI KiInitializePcr(IN ULONG ProcessorNumber, diff --git a/reactos/ntoskrnl/ke/i386/mtrr.c b/reactos/ntoskrnl/ke/i386/mtrr.c new file mode 100644 index 00000000000..41fc221741c --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/mtrr.c @@ -0,0 +1,33 @@ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/ke/i386/mtrr.c +* PURPOSE: Support for MTRR and AMD K6 MTRR +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +VOID +NTAPI +KiInitializeMTRR(IN BOOLEAN FinalCpu) +{ + /* FIXME: Support this */ + DPRINT1("Your machine supports MTRR but ReactOS doesn't yet.\n"); +} + +VOID +NTAPI +KiAmdK6InitializeMTRR(VOID) +{ + /* FIXME: Support this */ + DPRINT1("Your machine supports AMD MTRR but ReactOS doesn't yet.\n"); +} diff --git a/reactos/ntoskrnl/ke/i386/patpge.c b/reactos/ntoskrnl/ke/i386/patpge.c new file mode 100644 index 00000000000..e09f2e62e4f --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/patpge.c @@ -0,0 +1,63 @@ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/ke/i386/patpge.c +* PURPOSE: Support for PAT and PGE (Large Pages) +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +ULONG Ke386GlobalPagesEnabled; + +/* FUNCTIONS *****************************************************************/ + +ULONG_PTR +NTAPI +Ki386EnableGlobalPage(IN volatile ULONG_PTR Context) +{ + volatile PLONG Count = (PLONG)Context; + ULONG Cr4, Cr3; + + /* Disable interrupts */ + _disable(); + + /* Decrease CPU Count and loop until it's reached 0 */ + do {InterlockedDecrement(Count);} while (!*Count); + + /* Now check if this is the Boot CPU */ + if (!KeGetPcr()->Number) + { + /* It is.FIXME: Patch KeFlushCurrentTb */ + } + + /* Now get CR4 and make sure PGE is masked out */ + Cr4 = Ke386GetCr4(); + Ke386SetCr4(Cr4 & ~CR4_PGE); + + /* Flush the TLB */ + Ke386GetPageTableDirectory(Cr3); + Ke386SetPageTableDirectory(Cr3); + + /* Now enable PGE */ + Ke386SetCr4(Cr4 | CR4_PGE); + Ke386GlobalPagesEnabled = TRUE; + + /* Restore interrupts */ + _enable(); + return 0; +} + +VOID +NTAPI +KiInitializePAT(VOID) +{ + /* FIXME: Support this */ + DPRINT1("Your machine supports PAT but ReactOS doesn't yet.\n"); +} diff --git a/reactos/ntoskrnl/ke/krnlinit.c b/reactos/ntoskrnl/ke/krnlinit.c index ccdd281239b..236613ba43c 100644 --- a/reactos/ntoskrnl/ke/krnlinit.c +++ b/reactos/ntoskrnl/ke/krnlinit.c @@ -6,7 +6,7 @@ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG @@ -273,63 +273,18 @@ KiInitSpinLocks(IN PKPRCB Prcb, } } -/* FIXME: Rename and make portable */ VOID NTAPI -KeInit2(VOID) +KeInitSystem(VOID) { - ULONG Protect; - - /* Check if Fxsr was found */ - if (KeI386FxsrPresent) + /* Check if Threaded DPCs are enabled */ + if (KeThreadDpcEnable) { - /* 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 */ - } + /* FIXME: TODO */ + DPRINT1("Threaded DPCs not yet supported\n"); } - 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); + /* Initialize non-portable parts of the kernel */ + KiInitMachineDependent(); } + diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 02925121c28..f8ca060552e 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -37,6 +37,8 @@ kiinit.c ldt.c + mtrr.c + patpge.c thread.c trap.s usercall_asm.S