Author: tkreuzer Date: Thu Sep 15 19:32:13 2011 New Revision: 53714
URL: http://svn.reactos.org/svn/reactos?rev=53714&view=rev Log: [NTOSKRNL/AMD64] - Add portable kernel initialization code for amd64 only. - Modify amd64 init code accordingly
Added: trunk/reactos/ntoskrnl/ke/amd64/krnlinit.c (with props) Modified: trunk/reactos/ntoskrnl/CMakeLists.txt trunk/reactos/ntoskrnl/ke/amd64/boot.S trunk/reactos/ntoskrnl/ke/amd64/cpu.c trunk/reactos/ntoskrnl/ke/amd64/kiinit.c
Modified: trunk/reactos/ntoskrnl/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/CMakeLists.txt?rev... ============================================================================== --- trunk/reactos/ntoskrnl/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/CMakeLists.txt [iso-8859-1] Thu Sep 15 19:32:13 2011 @@ -312,6 +312,7 @@ ke/amd64/interrupt.c ke/amd64/irql.c ke/amd64/kiinit.c + ke/amd64/krnlinit.c ke/amd64/spinlock.c ke/amd64/stubs.c ke/amd64/thrdini.c
Modified: trunk/reactos/ntoskrnl/ke/amd64/boot.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/boot.S?re... ============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/boot.S [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/boot.S [iso-8859-1] Thu Sep 15 19:32:13 2011 @@ -10,7 +10,7 @@ #include <asm.inc> #include <ksamd64.inc>
-EXTERN KiInitializeKernelAndGotoIdleLoop:PROC +EXTERN KiSystemStartupBootStack:PROC
/* GLOBALS *******************************************************************/
@@ -21,42 +21,22 @@
/** * VOID - * KiSetupStackAndInitializeKernel( - * IN PKPROCESS InitProcess, <rsp + 0x08, rcx> - * IN PKTHREAD InitThread, <rsp + 0x10, rdx> - * IN PVOID IdleStack, <rsp + 0x18, r8> - * IN PKPRCB Prcb, <rsp + 0x20, r9> - * IN CCHAR Number, <rsp + 0x28> - * IN PLOADER_PARAMETER_BLOCK LoaderBlock) <rsp + 0x30> + * KiSwitchToBootStack( + * IN ULONG_PTR InitialStack<rcx>) */ -PUBLIC KiSetupStackAndInitializeKernel -.PROC KiSetupStackAndInitializeKernel - - /* Save current stack */ - mov rsi, rsp +PUBLIC KiSwitchToBootStack +.PROC KiSwitchToBootStack
/* Setup the new stack */ mov ax, HEX(18) mov ss, ax - mov rsp, r8 + mov rsp, rcx sub rsp, HEX(300) // FIXME - - /* Copy stack parameters to the new stack */ - sub rsp, HEX(38) .ENDPROLOG
- mov rdi, rsp - movsq - movsq - movsq - movsq - movsq - movsq - movsq + jmp KiSystemStartupBootStack
- jmp KiInitializeKernelAndGotoIdleLoop - -.ENDP KiSetupStackAndInitializeKernel +.ENDP KiSwitchToBootStack
END
Modified: trunk/reactos/ntoskrnl/ke/amd64/cpu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/cpu.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/cpu.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/cpu.c [iso-8859-1] Thu Sep 15 19:32:13 2011 @@ -370,41 +370,6 @@ }
VOID -FASTCALL -KiInitializeTss(IN PKTSS64 Tss, - IN UINT64 Stack) -{ - PKGDTENTRY64 TssEntry; - - /* Get pointer to the GDT entry */ - TssEntry = KiGetGdtEntry(KeGetPcr()->GdtBase, KGDT64_SYS_TSS); - - /* Initialize the GDT entry */ - KiInitGdtEntry(TssEntry, (ULONG64)Tss, sizeof(KTSS64), AMD64_TSS, 0); - - /* Zero out the TSS */ - RtlZeroMemory(Tss, sizeof(KTSS64)); - - /* FIXME: I/O Map? */ - Tss->IoMapBase = 0x68; - - /* Setup ring 0 stack pointer */ - Tss->Rsp0 = Stack; - - /* Setup a stack for Double Fault Traps */ - Tss->Ist[1] = (ULONG64)KiDoubleFaultStack; - - /* Setup a stack for CheckAbort Traps */ - Tss->Ist[2] = (ULONG64)KiDoubleFaultStack; - - /* Setup a stack for NMI Traps */ - Tss->Ist[3] = (ULONG64)KiDoubleFaultStack; - - /* Load the task register */ - __ltr(KGDT64_SYS_TSS); -} - -VOID NTAPI KeFlushCurrentTb(VOID) {
Modified: trunk/reactos/ntoskrnl/ke/amd64/kiinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/kiinit.c?... ============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/kiinit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/kiinit.c [iso-8859-1] Thu Sep 15 19:32:13 2011 @@ -69,256 +69,6 @@ /* FIXME: Support this */ DPRINT1("PAT support detected but not yet taken advantage of!\n"); } - - -} - -VOID -NTAPI -KiInitializePcr(IN PKIPCR Pcr, - IN ULONG ProcessorNumber, - IN PKTHREAD IdleThread, - IN PVOID DpcStack) -{ - KDESCRIPTOR GdtDescriptor = {{0},0,0}, IdtDescriptor = {{0},0,0}; - PKGDTENTRY64 TssEntry; - USHORT Tr = 0; - - /* Zero out the PCR */ - RtlZeroMemory(Pcr, PAGE_SIZE); - - /* Set pointers to ourselves */ - Pcr->Self = (PKPCR)Pcr; - Pcr->CurrentPrcb = &Pcr->Prcb; - - /* Set the PCR Version */ - Pcr->MajorVersion = PCR_MAJOR_VERSION; - Pcr->MinorVersion = PCR_MINOR_VERSION; - - /* Set the PRCB Version */ - Pcr->Prcb.MajorVersion = 1; - Pcr->Prcb.MinorVersion = 1; - - /* Set the Build Type */ - Pcr->Prcb.BuildType = 0; -#ifndef CONFIG_SMP - Pcr->Prcb.BuildType |= PRCB_BUILD_UNIPROCESSOR; -#endif -#ifdef DBG - Pcr->Prcb.BuildType |= PRCB_BUILD_DEBUG; -#endif - - /* Set the Processor Number and current Processor Mask */ - Pcr->Prcb.Number = (UCHAR)ProcessorNumber; - Pcr->Prcb.SetMember = 1 << ProcessorNumber; - - /* Get GDT and IDT descriptors */ - __sgdt(&GdtDescriptor.Limit); - __sidt(&IdtDescriptor.Limit); - Pcr->GdtBase = (PVOID)GdtDescriptor.Base; - Pcr->IdtBase = (PKIDTENTRY)IdtDescriptor.Base; - - /* Get TSS Selector */ - __str(&Tr); - ASSERT(Tr == KGDT64_SYS_TSS); - - /* Get TSS Entry */ - TssEntry = KiGetGdtEntry(Pcr->GdtBase, Tr); - - /* Get the KTSS itself */ - Pcr->TssBase = KiGetGdtDescriptorBase(TssEntry); - - Pcr->Prcb.RspBase = Pcr->TssBase->Rsp0; // FIXME - - /* Set DPC Stack */ - Pcr->Prcb.DpcStack = DpcStack; - - /* Setup the processor set */ - Pcr->Prcb.MultiThreadProcessorSet = Pcr->Prcb.SetMember; - - /* Clear DR6/7 to cleanup bootloader debugging */ - Pcr->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0; - Pcr->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; - - /* Set the Current Thread */ - Pcr->Prcb.CurrentThread = IdleThread; - - /* Start us out at PASSIVE_LEVEL */ - Pcr->Irql = PASSIVE_LEVEL; - KeSetCurrentIrql(PASSIVE_LEVEL); - -} - -VOID -NTAPI -KiInitializeCpuFeatures(ULONG Cpu) -{ - ULONG FeatureBits; - - /* Get the processor features for this CPU */ - FeatureBits = KiGetFeatureBits(); - - /* Check if we support all needed features */ - if ((FeatureBits & REQUIRED_FEATURE_BITS) != REQUIRED_FEATURE_BITS) - { - /* If not, bugcheck system */ - FrLdrDbgPrint("CPU doesn't have needed features! Has: 0x%x, required: 0x%x\n", - FeatureBits, REQUIRED_FEATURE_BITS); - KeBugCheck(0); - } - - /* Set DEP to always on */ - SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON; - FeatureBits |= KF_NX_ENABLED; - - /* Save feature bits */ - KeGetCurrentPrcb()->FeatureBits = FeatureBits; - - /* Enable fx save restore support */ - __writecr4(__readcr4() | CR4_FXSR); - - /* Enable XMMI exceptions */ - __writecr4(__readcr4() | CR4_XMMEXCPT); - - /* Enable Write-Protection */ - __writecr0(__readcr0() | CR0_WP); - - /* Disable fpu monitoring */ - __writecr0(__readcr0() & ~CR0_MP); - - /* Disable x87 fpu exceptions */ - __writecr0(__readcr0() & ~CR0_NE); - -} - -VOID -NTAPI -KiInitializeKernel(IN PKPROCESS InitProcess, - IN PKTHREAD InitThread, - IN PVOID IdleStack, - IN PKPRCB Prcb, - IN CCHAR Number, - IN PLOADER_PARAMETER_BLOCK LoaderBlock) -{ - ULONG PageDirectory[2]; - PVOID DpcStack; - - /* Detect and set the CPU Type */ - KiSetProcessorType(); - - /* Initialize the Power Management Support for this PRCB */ -// PoInitializePrcb(Prcb); - - /* Save CPU state */ - KiSaveProcessorControlState(&Prcb->ProcessorState); - - /* 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 == 0) - { - /* Set Node Data */ - KeNodeBlock[0] = &KiNode0; - Prcb->ParentNode = KeNodeBlock[0]; - KeNodeBlock[0]->ProcessorMask = Prcb->SetMember; - - /* Set boot-level flags */ - KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; - KeProcessorLevel = (USHORT)Prcb->CpuType; - if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep; - - /* Set the current MP Master KPRCB to the Boot PRCB */ - Prcb->MultiThreadSetMaster = Prcb; - - /* Lower to APC_LEVEL */ - KeLowerIrql(APC_LEVEL); - - /* Initialize some spinlocks */ - KeInitializeSpinLock(&KiFreezeExecutionLock); - - /* Initialize portable parts of the OS */ - KiInitSystem(); - - /* Initialize the Idle Process and the Process Listhead */ - InitializeListHead(&KiProcessListHead); - PageDirectory[0] = 0; - PageDirectory[1] = 0; - KeInitializeProcess(InitProcess, - 0, - 0xFFFFFFFF, - PageDirectory, - FALSE); - InitProcess->QuantumReset = MAXCHAR; - } - else - { - /* FIXME */ - DPRINT1("SMP Boot support not yet present\n"); - } - - /* HACK for MmUpdatePageDir */ - ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess; - - /* Setup the Idle Thread */ - KeInitializeThread(InitProcess, - InitThread, - NULL, - NULL, - NULL, - NULL, - NULL, - IdleStack); - - InitThread->NextProcessor = Number; - InitThread->Priority = HIGH_PRIORITY; - InitThread->State = Running; - InitThread->Affinity = 1 << Number; - InitThread->WaitIrql = DISPATCH_LEVEL; - InitProcess->ActiveProcessors = 1 << Number; - - /* Set basic CPU Features that user mode can read */ - SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = - (KeFeatureBits & KF_MMX) ? TRUE: FALSE; - SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = - (KeFeatureBits & KF_CMPXCHG8B) ? TRUE: FALSE; - SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = - ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI)) ? TRUE: FALSE; - SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = - ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI64)) ? TRUE: FALSE; - SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = - (KeFeatureBits & KF_3DNOW) ? TRUE: FALSE; - SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = - (KeFeatureBits & KF_RDTSC) ? TRUE: FALSE; - - /* Set up the thread-related fields in the PRCB */ - Prcb->CurrentThread = InitThread; - Prcb->NextThread = NULL; - Prcb->IdleThread = InitThread; - - /* Initialize the Kernel Executive */ - ExpInitializeExecutive(Number, LoaderBlock); - - /* Only do this on the boot CPU */ - if (Number == 0) - { - /* 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, 0); - if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0); - Prcb->DpcStack = DpcStack;
/* Allocate the IOPM save area. */ // Ki386IopmSaveArea = ExAllocatePoolWithTag(PagedPool, @@ -329,29 +79,263 @@ // /* Bugcheck. We need this for V86/VDM support. */ // KeBugCheckEx(NO_PAGES_AVAILABLE, 2, PAGE_SIZE * 2, 0, 0); // } - } - - /* Raise to Dispatch */ - KfRaiseIrql(DISPATCH_LEVEL); - - /* Set the Idle Priority to 0. This will jump into Phase 1 */ - KeSetPriorityThread(InitThread, 0); - - /* If there's no thread scheduled, put this CPU in the Idle summary */ - KiAcquirePrcbLock(Prcb); - if (!Prcb->NextThread) KiIdleSummary |= 1 << Number; - KiReleasePrcbLock(Prcb); - - /* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */ - KfRaiseIrql(HIGH_LEVEL); - LoaderBlock->Prcb = 0; + +} + +VOID +NTAPI +KiInitializePcr(IN PKIPCR Pcr, + IN ULONG ProcessorNumber, + IN PKTHREAD IdleThread, + IN PVOID DpcStack) +{ + KDESCRIPTOR GdtDescriptor = {{0},0,0}, IdtDescriptor = {{0},0,0}; + PKGDTENTRY64 TssEntry; + USHORT Tr = 0; + + /* Zero out the PCR */ + RtlZeroMemory(Pcr, PAGE_SIZE); + + /* Set pointers to ourselves */ + Pcr->Self = (PKPCR)Pcr; + Pcr->CurrentPrcb = &Pcr->Prcb; + + /* Set the PCR Version */ + Pcr->MajorVersion = PCR_MAJOR_VERSION; + Pcr->MinorVersion = PCR_MINOR_VERSION; + + /* Set the PRCB Version */ + Pcr->Prcb.MajorVersion = 1; + Pcr->Prcb.MinorVersion = 1; + + /* Set the Build Type */ + Pcr->Prcb.BuildType = 0; +#ifndef CONFIG_SMP + Pcr->Prcb.BuildType |= PRCB_BUILD_UNIPROCESSOR; +#endif +#ifdef DBG + Pcr->Prcb.BuildType |= PRCB_BUILD_DEBUG; +#endif + + /* Set the Processor Number and current Processor Mask */ + Pcr->Prcb.Number = (UCHAR)ProcessorNumber; + Pcr->Prcb.SetMember = 1ULL << ProcessorNumber; + + /* Get GDT and IDT descriptors */ + __sgdt(&GdtDescriptor.Limit); + __sidt(&IdtDescriptor.Limit); + Pcr->GdtBase = (PVOID)GdtDescriptor.Base; + Pcr->IdtBase = (PKIDTENTRY)IdtDescriptor.Base; + + /* Get TSS Selector */ + __str(&Tr); + ASSERT(Tr == KGDT64_SYS_TSS); + + /* Get TSS Entry */ + TssEntry = KiGetGdtEntry(Pcr->GdtBase, Tr); + + /* Get the KTSS itself */ + Pcr->TssBase = KiGetGdtDescriptorBase(TssEntry); + + Pcr->Prcb.RspBase = Pcr->TssBase->Rsp0; // FIXME + + /* Set DPC Stack */ + Pcr->Prcb.DpcStack = DpcStack; + + /* Setup the processor set */ + Pcr->Prcb.MultiThreadProcessorSet = Pcr->Prcb.SetMember; + + /* Clear DR6/7 to cleanup bootloader debugging */ + Pcr->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0; + Pcr->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; + + /* Set the Current Thread */ + Pcr->Prcb.CurrentThread = IdleThread; + + /* Start us out at PASSIVE_LEVEL */ + Pcr->Irql = PASSIVE_LEVEL; + KeSetCurrentIrql(PASSIVE_LEVEL); + + /* Set GS base */ + __writemsr(X86_MSR_GSBASE, (ULONG64)Pcr); + __writemsr(X86_MSR_KERNEL_GSBASE, (ULONG64)Pcr); +} + +VOID +NTAPI +KiInitializeCpu(PKPRCB Prcb) +{ + ULONG FeatureBits; + + /* Detect and set the CPU Type */ + KiSetProcessorType(); + + /* Get the processor features for this CPU */ + FeatureBits = KiGetFeatureBits(); + + /* Check if we support all needed features */ + if ((FeatureBits & REQUIRED_FEATURE_BITS) != REQUIRED_FEATURE_BITS) + { + /* If not, bugcheck system */ + FrLdrDbgPrint("CPU doesn't have needed features! Has: 0x%x, required: 0x%x\n", + FeatureBits, REQUIRED_FEATURE_BITS); + KeBugCheck(0); + } + + /* Set DEP to always on */ + SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON; + FeatureBits |= KF_NX_ENABLED; + + /* Save feature bits */ + Prcb->FeatureBits = FeatureBits; + + /* Enable fx save restore support */ + __writecr4(__readcr4() | CR4_FXSR); + + /* Enable XMMI exceptions */ + __writecr4(__readcr4() | CR4_XMMEXCPT); + + /* Enable Write-Protection */ + __writecr0(__readcr0() | CR0_WP); + + /* Disable fpu monitoring */ + __writecr0(__readcr0() & ~CR0_MP); + + /* Disable x87 fpu exceptions */ + __writecr0(__readcr0() & ~CR0_NE); + + /* LDT is unused */ + __lldt(0); +} + +VOID +FASTCALL +KiInitializeTss(IN PKTSS64 Tss, + IN UINT64 Stack) +{ + PKGDTENTRY64 TssEntry; + + /* Get pointer to the GDT entry */ + TssEntry = KiGetGdtEntry(KeGetPcr()->GdtBase, KGDT64_SYS_TSS); + + /* Initialize the GDT entry */ + KiInitGdtEntry(TssEntry, (ULONG64)Tss, sizeof(KTSS64), AMD64_TSS, 0); + + /* Zero out the TSS */ + RtlZeroMemory(Tss, sizeof(KTSS64)); + + /* FIXME: I/O Map? */ + Tss->IoMapBase = 0x68; + + /* Setup ring 0 stack pointer */ + Tss->Rsp0 = Stack; + + /* Setup a stack for Double Fault Traps */ + Tss->Ist[1] = (ULONG64)KiDoubleFaultStack; + + /* Setup a stack for CheckAbort Traps */ + Tss->Ist[2] = (ULONG64)KiDoubleFaultStack; + + /* Setup a stack for NMI Traps */ + Tss->Ist[3] = (ULONG64)KiDoubleFaultStack; + + /* Load the task register */ + __ltr(KGDT64_SYS_TSS); +} + +VOID +NTAPI +INIT_FUNCTION +KiInitializeKernelMachineDependent( + IN PKPRCB Prcb, + IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + /* Set boot-level flags */ + KeI386CpuType = Prcb->CpuType; + KeI386CpuStep = Prcb->CpuStep; + KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; + KeProcessorLevel = (USHORT)Prcb->CpuType; + if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep; + + /* Set basic CPU Features that user mode can read */ + SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = + (Prcb->FeatureBits & KF_MMX) ? TRUE: FALSE; + SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; + SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = + ((Prcb->FeatureBits & KF_FXSR) && (Prcb->FeatureBits & KF_XMMI)) ? TRUE: FALSE; + SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = + ((Prcb->FeatureBits & KF_FXSR) && (Prcb->FeatureBits & KF_XMMI64)) ? TRUE: FALSE; + SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = + (Prcb->FeatureBits & KF_3DNOW) ? TRUE: FALSE; + SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE; + + /* Set the default NX policy (opt-in) */ + SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN; + + /* Check if NPX is always on */ + if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSON")) + { + /* Set it always on */ + SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON; + Prcb->FeatureBits |= KF_NX_ENABLED; + } + else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT")) + { + /* Set it in opt-out mode */ + SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTOUT; + Prcb->FeatureBits |= KF_NX_ENABLED; + } + else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) || + (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE"))) + { + /* Set the feature bits */ + Prcb->FeatureBits |= KF_NX_ENABLED; + } + else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSOFF")) || + (strstr(KeLoaderBlock->LoadOptions, "EXECUTE"))) + { + /* Set disabled mode */ + SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSOFF; + Prcb->FeatureBits |= KF_NX_DISABLED; + } + +} + +static LDR_DATA_TABLE_ENTRY LdrCoreEntries[3]; + +void +KiInitModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PLDR_DATA_TABLE_ENTRY LdrEntry; + PLIST_ENTRY Entry; + ULONG i; + + /* Initialize the list head */ + InitializeListHead(&PsLoadedModuleList); + + /* Loop the first 3 entries */ + for (Entry = LoaderBlock->LoadOrderListHead.Flink, i = 0; + Entry != &LoaderBlock->LoadOrderListHead && i < 3; + Entry = Entry->Flink, i++) + { + /* Get the data table entry */ + LdrEntry = CONTAINING_RECORD(Entry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + /* Copy the entry */ + LdrCoreEntries[i] = *LdrEntry; + + /* Insert the copy into the list */ + InsertTailList(&PsLoadedModuleList, &LdrCoreEntries[i].InLoadOrderLinks); + } }
VOID NTAPI KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { - ULONG Cpu; + CCHAR Cpu; PKTHREAD InitialThread; ULONG64 InitialStack; PKIPCR Pcr; @@ -367,11 +351,12 @@ KeLoaderBlock = LoaderBlock;
/* Get the current CPU number */ - Cpu = KeNumberProcessors++; // FIXME + Cpu = (CCHAR)KeNumberProcessors++; // FIXME
/* LoaderBlock initialization for Cpu 0 */ if (Cpu == 0) { + FrLdrDbgPrint("LoaderBlock->Prcb=%p\n", LoaderBlock->Prcb); /* Set the initial stack, idle thread and process */ LoaderBlock->KernelStack = (ULONG_PTR)P0BootStack; LoaderBlock->Thread = (ULONG_PTR)&KiInitialThread; @@ -385,13 +370,6 @@ /* Set the PRCB for this Processor */ KiProcessorBlock[Cpu] = &Pcr->Prcb;
- /* Set GS base */ - __writemsr(X86_MSR_GSBASE, (ULONG64)Pcr); - __writemsr(X86_MSR_KERNEL_GSBASE, (ULONG64)Pcr); - - /* LDT is unused */ - __lldt(0); - /* Align stack to 16 bytes */ LoaderBlock->KernelStack &= ~(16 - 1);
@@ -399,9 +377,6 @@ InitialStack = LoaderBlock->KernelStack; // Checkme InitialThread = (PKTHREAD)LoaderBlock->Thread;
- /* Clean the APC List Head */ - InitializeListHead(&InitialThread->ApcState.ApcListHead[KernelMode]); - /* Set us as the current process */ InitialThread->ApcState.Process = (PVOID)LoaderBlock->Process;
@@ -409,34 +384,34 @@ KiInitializePcr(Pcr, Cpu, InitialThread, (PVOID)KiDoubleFaultStack);
/* Initialize the CPU features */ - KiInitializeCpuFeatures(Cpu); + KiInitializeCpu(&Pcr->Prcb);
/* Initial setup for the boot CPU */ if (Cpu == 0) { + /* Initialize the module list (ntos, hal, kdcom) */ + KiInitModuleList(LoaderBlock); + /* Setup the TSS descriptors and entries */ KiInitializeTss(Pcr->TssBase, InitialStack);
/* Setup the IDT */ KeInitExceptions();
- /* HACK: misuse this function to pass a function pointer to kdcom */ - KdDebuggerInitialize1((PVOID)FrLdrDbgPrint); - - /* Initialize debugging system */ + /* Initialize debugging system */ KdInitSystem(0, KeLoaderBlock);
/* Check for break-in */ if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
/* Hack! Wait for the debugger! */ -#ifdef _WINKD_ +#ifdef _WINKD_x while (!KdPollBreakIn()); DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); #endif }
- DPRINT("Pcr = %p, Gdt = %p, Idt = %p, Tss = %p\n", + DPRINT1("Pcr = %p, Gdt = %p, Idt = %p, Tss = %p\n", Pcr, Pcr->GdtBase, Pcr->IdtBase, Pcr->TssBase);
/* Acquire lock */ @@ -444,13 +419,13 @@ { /* Loop until lock is free */ while ((*(volatile KSPIN_LOCK*)&KiFreezeExecutionLock) & 1); - } + }
/* Initialize the Processor with HAL */ HalInitializeProcessor(Cpu, KeLoaderBlock);
/* Set processor as active */ - KeActiveProcessors |= 1 << Cpu; + KeActiveProcessors |= 1ULL << Cpu;
/* Release lock */ InterlockedAnd64((PLONG64)&KiFreezeExecutionLock, 0); @@ -458,45 +433,10 @@ /* Raise to HIGH_LEVEL */ KfRaiseIrql(HIGH_LEVEL);
+ /* Machine specific kernel initialization */ + if (Cpu == 0) KiInitializeKernelMachineDependent(&Pcr->Prcb, LoaderBlock); + /* Switch to new kernel stack and start kernel bootstrapping */ - KiSetupStackAndInitializeKernel(&KiInitialProcess.Pcb, - InitialThread, - (PVOID)InitialStack, - &Pcr->Prcb, - (CCHAR)Cpu, - KeLoaderBlock); -} - - -VOID -NTAPI -KiInitializeKernelAndGotoIdleLoop(IN PKPROCESS InitProcess, - IN PKTHREAD InitThread, - IN PVOID IdleStack, - IN PKPRCB Prcb, - IN CCHAR Number, - IN PLOADER_PARAMETER_BLOCK LoaderBlock) -{ -// DbgBreakPointWithStatus(0); - - /* Initialize kernel */ - KiInitializeKernel(InitProcess, - InitThread, - IdleStack, - Prcb, - Number, - KeLoaderBlock); - - /* Set the priority of this thread to 0 */ - InitThread->Priority = 0; - - /* Force interrupts enabled and lower IRQL back to DISPATCH_LEVEL */ - _enable(); - KeLowerIrql(DISPATCH_LEVEL); - - /* Set the right wait IRQL */ - InitThread->WaitIrql = DISPATCH_LEVEL; - - /* Jump into the idle loop */ - KiIdleLoop(); -} + KiSwitchToBootStack(InitialStack & ~3); +} +
Added: trunk/reactos/ntoskrnl/ke/amd64/krnlinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/krnlinit.... ============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/krnlinit.c (added) +++ trunk/reactos/ntoskrnl/ke/amd64/krnlinit.c [iso-8859-1] Thu Sep 15 19:32:13 2011 @@ -1,0 +1,235 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/krnlinit.c + * PURPOSE: Portable part of kernel initialization + * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) + * Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +extern ULONG_PTR MainSSDT[]; +extern UCHAR MainSSPT[]; + +/* FUNCTIONS *****************************************************************/ + +VOID +NTAPI +INIT_FUNCTION +KiInitializeKernel(IN PKPROCESS InitProcess, + IN PKTHREAD InitThread, + IN PVOID IdleStack, + IN PKPRCB Prcb, + IN PLOADER_PARAMETER_BLOCK LoaderBlock); + + +VOID +NTAPI +KiInitalizeHandBuiltThread( + IN PKTHREAD Thread, + IN PKPROCESS Process, + IN PVOID Stack) +{ + PKPRCB Prcb = KeGetCurrentPrcb(); + + /* Setup the Thread */ + KeInitializeThread(Process, Thread, NULL, NULL, NULL, NULL, NULL, Stack); + + Thread->NextProcessor = Prcb->Number; + Thread->Priority = HIGH_PRIORITY; + Thread->State = Running; + Thread->Affinity = (ULONG_PTR)1 << Prcb->Number; + Thread->WaitIrql = DISPATCH_LEVEL; + Process->ActiveProcessors |= (ULONG_PTR)1 << Prcb->Number; + +} + +VOID +NTAPI +INIT_FUNCTION +KiSystemStartupBootStack(VOID) +{ + PLOADER_PARAMETER_BLOCK LoaderBlock = KeLoaderBlock; // hack + PKPRCB Prcb = KeGetCurrentPrcb(); + PKTHREAD Thread = (PKTHREAD)KeLoaderBlock->Thread; + PKPROCESS Process = Thread->ApcState.Process; + PVOID KernelStack = (PVOID)KeLoaderBlock->KernelStack; + + /* Initialize the Power Management Support for this PRCB */ + PoInitializePrcb(Prcb); + + /* Save CPU state */ + KiSaveProcessorControlState(&Prcb->ProcessorState); + + /* Get cache line information for this CPU */ + KiGetCacheInformation(); + + /* Initialize spinlocks and DPC data */ + KiInitSpinLocks(Prcb, Prcb->Number); + + /* Set up the thread-related fields in the PRCB */ + Prcb->CurrentThread = Thread; + Prcb->NextThread = NULL; + Prcb->IdleThread = Thread; + + /* Initialize PRCB pool lookaside pointers */ + ExInitPoolLookasidePointers(); + + /* Check if this is the boot cpu */ + if (Prcb->Number == 0) + { + /* Initialize the kernel */ + KiInitializeKernel(Process, Thread, KernelStack, Prcb, LoaderBlock); + } + else + { + /* Initialize the startup thread */ + KiInitalizeHandBuiltThread(Thread, Process, KernelStack); + + /* Initialize cpu with HAL */ + if (!HalInitSystem(0, LoaderBlock)) + { + /* Initialization failed */ + KeBugCheck(HAL_INITIALIZATION_FAILED); + } + } + + /* Raise to Dispatch */ + KfRaiseIrql(DISPATCH_LEVEL); + + /* Set the Idle Priority to 0. This will jump into Phase 1 */ + KeSetPriorityThread(Thread, 0); + + /* If there's no thread scheduled, put this CPU in the Idle summary */ + KiAcquirePrcbLock(Prcb); + if (!Prcb->NextThread) KiIdleSummary |= (ULONG_PTR)1 << Prcb->Number; + KiReleasePrcbLock(Prcb); + + /* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */ + KfRaiseIrql(HIGH_LEVEL); + LoaderBlock->Prcb = 0; + + /* Set the priority of this thread to 0 */ + Thread = KeGetCurrentThread(); + Thread->Priority = 0; + + /* Force interrupts enabled and lower IRQL back to DISPATCH_LEVEL */ + _enable(); + KeLowerIrql(DISPATCH_LEVEL); + + /* Set the right wait IRQL */ + Thread->WaitIrql = DISPATCH_LEVEL; + + /* Jump into the idle loop */ + KiIdleLoop(); +} + +VOID +NTAPI +INIT_FUNCTION +KiInitializeKernel(IN PKPROCESS InitProcess, + IN PKTHREAD InitThread, + IN PVOID IdleStack, + IN PKPRCB Prcb, + IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + ULONG PageDirectory[2]; + PVOID DpcStack; + ULONG i; + + /* Set Node Data */ + KeNodeBlock[0] = &KiNode0; + Prcb->ParentNode = KeNodeBlock[0]; + KeNodeBlock[0]->ProcessorMask = Prcb->SetMember; + + /* Set boot-level flags */ + KeFeatureBits = Prcb->FeatureBits; + + /* Set the current MP Master KPRCB to the Boot PRCB */ + Prcb->MultiThreadSetMaster = Prcb; + + /* Lower to APC_LEVEL */ + KeLowerIrql(APC_LEVEL); + + /* Initialize Bugcheck Callback data */ + InitializeListHead(&KeBugcheckCallbackListHead); + InitializeListHead(&KeBugcheckReasonCallbackListHead); + KeInitializeSpinLock(&BugCheckCallbackLock); + + /* Initialize the Timer Expiration DPC */ + KeInitializeDpc(&KiTimerExpireDpc, KiTimerExpiration, NULL); + KeSetTargetProcessorDpc(&KiTimerExpireDpc, 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 the Swap event and all swap lists */ + KeInitializeEvent(&KiSwapEvent, SynchronizationEvent, FALSE); + InitializeListHead(&KiProcessInSwapListHead); + InitializeListHead(&KiProcessOutSwapListHead); + InitializeListHead(&KiStackInSwapListHead); + + /* Initialize the mutex for generic DPC calls */ + ExInitializeFastMutex(&KiGenericCallDpcMutex); + + /* Initialize the syscall table */ + KeServiceDescriptorTable[0].Base = MainSSDT; + KeServiceDescriptorTable[0].Count = NULL; + KeServiceDescriptorTable[0].Limit = KiServiceLimit; + KeServiceDescriptorTable[1].Limit = 0; + KeServiceDescriptorTable[0].Number = MainSSPT; + + /* Copy the the current table into the shadow table for win32k */ + RtlCopyMemory(KeServiceDescriptorTableShadow, + KeServiceDescriptorTable, + sizeof(KeServiceDescriptorTable)); + + /* Initialize the Idle Process and the Process Listhead */ + InitializeListHead(&KiProcessListHead); + PageDirectory[0] = 0; + PageDirectory[1] = 0; + KeInitializeProcess(InitProcess, + 0, + 0xFFFFFFFF, + PageDirectory, + FALSE); + InitProcess->QuantumReset = MAXCHAR; + + /* Initialize the startup thread */ + KiInitalizeHandBuiltThread(InitThread, InitProcess, IdleStack); + + /* Initialize the Kernel Executive */ + ExpInitializeExecutive(0, LoaderBlock); + + /* 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, 0); + if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0); + Prcb->DpcStack = DpcStack; +} +
Propchange: trunk/reactos/ntoskrnl/ke/amd64/krnlinit.c ------------------------------------------------------------------------------ svn:eol-style = native