1 /* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: ntoskrnl/ke/amd64/kiinit.c 5 * PURPOSE: Kernel Initialization for x86 CPUs 6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 7 * Timo Kreuzer (timo.kreuzer@reactos.org) 8 */ 9 10 /* INCLUDES *****************************************************************/ 11 12 #include <ntoskrnl.h> 13 #define NDEBUG 14 #include <debug.h> 15 16 #define REQUIRED_FEATURE_BITS (KF_RDTSC|KF_CR4|KF_CMPXCHG8B|KF_XMMI|KF_XMMI64| \ 17 KF_LARGE_PAGE|KF_FAST_SYSCALL|KF_GLOBAL_PAGE| \ 18 KF_CMOV|KF_PAT|KF_MMX|KF_FXSR|KF_NX_BIT|KF_MTRR) 19 20 /* GLOBALS *******************************************************************/ 21 22 /* Function pointer for early debug prints */ 23 ULONG (*FrLdrDbgPrint)(const char *Format, ...); 24 25 /* Spinlocks used only on X86 */ 26 KSPIN_LOCK KiFreezeExecutionLock; 27 28 29 KIPCR KiInitialPcr; 30 31 /* Boot and double-fault/NMI/DPC stack */ 32 UCHAR DECLSPEC_ALIGN(16) KiP0BootStackData[KERNEL_STACK_SIZE] = {0}; 33 UCHAR DECLSPEC_ALIGN(16) KiP0DoubleFaultStackData[KERNEL_STACK_SIZE] = {0}; 34 PVOID KiP0BootStack = &KiP0BootStackData[KERNEL_STACK_SIZE]; 35 PVOID KiP0DoubleFaultStack = &KiP0DoubleFaultStackData[KERNEL_STACK_SIZE]; 36 37 ULONGLONG BootCycles, BootCyclesEnd; 38 39 void KiInitializeSegments(); 40 void KiSystemCallEntry64(); 41 void KiSystemCallEntry32(); 42 43 /* FUNCTIONS *****************************************************************/ 44 45 CODE_SEG("INIT") 46 VOID 47 NTAPI 48 KiInitMachineDependent(VOID) 49 { 50 /* Check for large page support */ 51 if (KeFeatureBits & KF_LARGE_PAGE) 52 { 53 /* FIXME: Support this */ 54 DPRINT("Large Page support detected but not yet taken advantage of!\n"); 55 } 56 57 /* Check for global page support */ 58 if (KeFeatureBits & KF_GLOBAL_PAGE) 59 { 60 /* FIXME: Support this */ 61 DPRINT("Global Page support detected but not yet taken advantage of!\n"); 62 } 63 64 /* Check if we have MTRR */ 65 if (KeFeatureBits & KF_MTRR) 66 { 67 /* FIXME: Support this */ 68 DPRINT("MTRR support detected but not yet taken advantage of!\n"); 69 } 70 71 /* Check for PAT and/or MTRR support */ 72 if (KeFeatureBits & KF_PAT) 73 { 74 /* FIXME: Support this */ 75 DPRINT("PAT support detected but not yet taken advantage of!\n"); 76 } 77 78 // /* Allocate the IOPM save area */ 79 // Ki386IopmSaveArea = ExAllocatePoolWithTag(PagedPool, 80 // IOPM_SIZE, 81 // ' eK'); 82 // if (!Ki386IopmSaveArea) 83 // { 84 // /* Bugcheck. We need this for V86/VDM support. */ 85 // KeBugCheckEx(NO_PAGES_AVAILABLE, 2, IOPM_SIZE, 0, 0); 86 // } 87 88 } 89 90 static 91 VOID 92 KiInitializePcr( 93 _Out_ PKIPCR Pcr, 94 _In_ ULONG ProcessorNumber, 95 _In_ PKGDTENTRY64 GdtBase, 96 _In_ PKIDTENTRY64 IdtBase, 97 _In_ PKTSS64 TssBase, 98 _In_ PKTHREAD IdleThread, 99 _In_ PVOID DpcStack) 100 { 101 /* Zero out the PCR */ 102 RtlZeroMemory(Pcr, sizeof(KIPCR)); 103 104 /* Set pointers to ourselves */ 105 Pcr->Self = (PKPCR)Pcr; 106 Pcr->CurrentPrcb = &Pcr->Prcb; 107 108 /* Set the PCR Version */ 109 Pcr->MajorVersion = PCR_MAJOR_VERSION; 110 Pcr->MinorVersion = PCR_MINOR_VERSION; 111 112 /* Set the PRCB Version */ 113 Pcr->Prcb.MajorVersion = PRCB_MAJOR_VERSION; 114 Pcr->Prcb.MinorVersion = PRCB_MINOR_VERSION; 115 116 /* Set the Build Type */ 117 Pcr->Prcb.BuildType = 0; 118 #ifndef CONFIG_SMP 119 Pcr->Prcb.BuildType |= PRCB_BUILD_UNIPROCESSOR; 120 #endif 121 #if DBG 122 Pcr->Prcb.BuildType |= PRCB_BUILD_DEBUG; 123 #endif 124 125 /* Set the Processor Number and current Processor Mask */ 126 Pcr->Prcb.Number = (UCHAR)ProcessorNumber; 127 Pcr->Prcb.SetMember = 1ULL << ProcessorNumber; 128 129 /* Set GDT and IDT base */ 130 Pcr->GdtBase = GdtBase; 131 Pcr->IdtBase = IdtBase; 132 133 /* Set TssBase */ 134 Pcr->TssBase = TssBase; 135 136 Pcr->Prcb.RspBase = Pcr->TssBase->Rsp0; // FIXME 137 138 /* Set DPC Stack */ 139 Pcr->Prcb.DpcStack = DpcStack; 140 141 /* Setup the processor set */ 142 Pcr->Prcb.MultiThreadProcessorSet = Pcr->Prcb.SetMember; 143 144 /* Clear DR6/7 to cleanup bootloader debugging */ 145 Pcr->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0; 146 Pcr->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; 147 148 /* Initialize MXCSR (all exceptions masked) */ 149 Pcr->Prcb.MxCsr = INITIAL_MXCSR; 150 151 /* Set the Current Thread */ 152 Pcr->Prcb.CurrentThread = IdleThread; 153 154 /* Start us out at PASSIVE_LEVEL */ 155 Pcr->Irql = PASSIVE_LEVEL; 156 } 157 158 VOID 159 NTAPI 160 KiInitializeCpu(PKIPCR Pcr) 161 { 162 ULONG64 Pat; 163 ULONG64 FeatureBits; 164 165 /* Initialize gs */ 166 KiInitializeSegments(); 167 168 /* Set GS base */ 169 __writemsr(MSR_GS_BASE, (ULONG64)Pcr); 170 __writemsr(MSR_GS_SWAP, (ULONG64)Pcr); 171 172 /* Detect and set the CPU Type */ 173 KiSetProcessorType(); 174 175 /* Get the processor features for this CPU */ 176 FeatureBits = KiGetFeatureBits(); 177 178 /* Check if we support all needed features */ 179 if ((FeatureBits & REQUIRED_FEATURE_BITS) != REQUIRED_FEATURE_BITS) 180 { 181 /* If not, bugcheck system */ 182 FrLdrDbgPrint("CPU doesn't have needed features! Has: 0x%x, required: 0x%x\n", 183 FeatureBits, REQUIRED_FEATURE_BITS); 184 KeBugCheck(0); 185 } 186 187 /* Set DEP to always on */ 188 SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON; 189 FeatureBits |= KF_NX_ENABLED; 190 191 /* Save feature bits */ 192 Pcr->Prcb.FeatureBits = (ULONG)FeatureBits; 193 Pcr->Prcb.FeatureBitsHigh = FeatureBits >> 32; 194 195 /* Enable fx save restore support */ 196 __writecr4(__readcr4() | CR4_FXSR); 197 198 /* Enable XMMI exceptions */ 199 __writecr4(__readcr4() | CR4_XMMEXCPT); 200 201 /* Enable Write-Protection */ 202 __writecr0(__readcr0() | CR0_WP); 203 204 /* Disable fpu monitoring */ 205 __writecr0(__readcr0() & ~CR0_MP); 206 207 /* Disable x87 fpu exceptions */ 208 __writecr0(__readcr0() & ~CR0_NE); 209 210 /* LDT is unused */ 211 __lldt(0); 212 213 /* Set the systemcall entry points */ 214 __writemsr(MSR_LSTAR, (ULONG64)KiSystemCallEntry64); 215 __writemsr(MSR_CSTAR, (ULONG64)KiSystemCallEntry32); 216 217 __writemsr(MSR_STAR, ((ULONG64)KGDT64_R0_CODE << 32) | 218 ((ULONG64)(KGDT64_R3_CMCODE|RPL_MASK) << 48)); 219 220 /* Set the flags to be cleared when doing a syscall */ 221 __writemsr(MSR_SYSCALL_MASK, EFLAGS_IF_MASK | EFLAGS_TF | EFLAGS_DF | EFLAGS_NESTED_TASK); 222 223 /* Enable syscall instruction and no-execute support */ 224 __writemsr(MSR_EFER, __readmsr(MSR_EFER) | MSR_SCE | MSR_NXE); 225 226 /* Initialize the PAT */ 227 Pat = (PAT_WB << 0) | (PAT_WC << 8) | (PAT_UCM << 16) | (PAT_UC << 24) | 228 (PAT_WB << 32) | (PAT_WC << 40) | (PAT_UCM << 48) | (PAT_UC << 56); 229 __writemsr(MSR_PAT, Pat); 230 231 /* Initialize MXCSR */ 232 _mm_setcsr(INITIAL_MXCSR); 233 234 KeSetCurrentIrql(PASSIVE_LEVEL); 235 } 236 237 static 238 VOID 239 KiInitializeTss( 240 _In_ PKIPCR Pcr, 241 _Out_ PKTSS64 Tss, 242 _In_ PVOID InitialStack, 243 _In_ PVOID DoubleFaultStack, 244 _In_ PVOID NmiStack) 245 { 246 PKGDTENTRY64 TssEntry; 247 248 /* Get pointer to the GDT entry */ 249 TssEntry = KiGetGdtEntry(Pcr->GdtBase, KGDT64_SYS_TSS); 250 251 /* Initialize the GDT entry */ 252 KiInitGdtEntry(TssEntry, (ULONG64)Tss, sizeof(KTSS64), AMD64_TSS, 0); 253 254 /* Zero out the TSS */ 255 RtlZeroMemory(Tss, sizeof(KTSS64)); 256 257 /* FIXME: I/O Map? */ 258 Tss->IoMapBase = 0x68; 259 260 /* Setup ring 0 stack pointer */ 261 Tss->Rsp0 = (ULONG64)InitialStack; 262 263 /* Setup a stack for Double Fault Traps */ 264 Tss->Ist[1] = (ULONG64)DoubleFaultStack; 265 266 /* Setup a stack for CheckAbort Traps */ 267 Tss->Ist[2] = (ULONG64)DoubleFaultStack; 268 269 /* Setup a stack for NMI Traps */ 270 Tss->Ist[3] = (ULONG64)NmiStack; 271 } 272 273 CODE_SEG("INIT") 274 VOID 275 KiInitializeProcessorBootStructures( 276 _In_ ULONG ProcessorNumber, 277 _Out_ PKIPCR Pcr, 278 _In_ PKGDTENTRY64 GdtBase, 279 _In_ PKIDTENTRY64 IdtBase, 280 _In_ PKTSS64 TssBase, 281 _In_ PKTHREAD IdleThread, 282 _In_ PVOID KernelStack, 283 _In_ PVOID DpcStack, 284 _In_ PVOID DoubleFaultStack, 285 _In_ PVOID NmiStack) 286 { 287 /* Initialize the PCR */ 288 KiInitializePcr(Pcr, 289 ProcessorNumber, 290 GdtBase, 291 IdtBase, 292 TssBase, 293 IdleThread, 294 DpcStack); 295 296 297 /* Setup the TSS descriptor and entries */ 298 KiInitializeTss(Pcr, 299 TssBase, 300 KernelStack, 301 DoubleFaultStack, 302 NmiStack); 303 } 304 305 CODE_SEG("INIT") 306 static 307 VOID 308 KiInitializeP0BootStructures( 309 _Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock) 310 { 311 KDESCRIPTOR GdtDescriptor = {{0},0,0}, IdtDescriptor = {{0},0,0}; 312 PKGDTENTRY64 TssEntry; 313 PKTSS64 TssBase; 314 315 /* Set the initial stack, idle thread and process for processor 0 */ 316 LoaderBlock->KernelStack = (ULONG_PTR)KiP0BootStack; 317 LoaderBlock->Thread = (ULONG_PTR)&KiInitialThread; 318 LoaderBlock->Process = (ULONG_PTR)&KiInitialProcess.Pcb; 319 LoaderBlock->Prcb = (ULONG_PTR)&KiInitialPcr.Prcb; 320 321 /* Get GDT and IDT descriptors */ 322 __sgdt(&GdtDescriptor.Limit); 323 __sidt(&IdtDescriptor.Limit); 324 325 /* Get the boot TSS from the GDT */ 326 TssEntry = KiGetGdtEntry(GdtDescriptor.Base, KGDT64_SYS_TSS); 327 TssBase = KiGetGdtDescriptorBase(TssEntry); 328 329 /* Initialize PCR and TSS */ 330 KiInitializeProcessorBootStructures(0, 331 &KiInitialPcr, 332 GdtDescriptor.Base, 333 IdtDescriptor.Base, 334 TssBase, 335 &KiInitialThread.Tcb, 336 KiP0BootStack, 337 KiP0DoubleFaultStack, 338 KiP0DoubleFaultStack, 339 KiP0DoubleFaultStack); 340 } 341 342 CODE_SEG("INIT") 343 VOID 344 NTAPI 345 KiInitializeKernelMachineDependent( 346 IN PKPRCB Prcb, 347 IN PLOADER_PARAMETER_BLOCK LoaderBlock) 348 { 349 ULONG64 FeatureBits; 350 351 /* Set boot-level flags */ 352 KeI386CpuType = Prcb->CpuType; 353 KeI386CpuStep = Prcb->CpuStep; 354 KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; 355 KeProcessorLevel = (USHORT)Prcb->CpuType; 356 if (Prcb->CpuID) 357 KeProcessorRevision = Prcb->CpuStep; 358 359 FeatureBits = Prcb->FeatureBits | (ULONG64)Prcb->FeatureBitsHigh << 32; 360 361 /* Set basic CPU Features that user mode can read */ 362 SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE; 363 SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE; 364 SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; 365 SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = 366 (FeatureBits & KF_MMX) ? TRUE : FALSE; 367 SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = 368 ((FeatureBits & KF_FXSR) && (FeatureBits & KF_XMMI)) ? TRUE : FALSE; 369 SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = 370 (FeatureBits & KF_3DNOW) ? TRUE : FALSE; 371 SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE; 372 SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = TRUE; // ??? 373 SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = 374 ((FeatureBits & KF_FXSR) && (FeatureBits & KF_XMMI64)) ? TRUE : FALSE; 375 SharedUserData->ProcessorFeatures[PF_SSE_DAZ_MODE_AVAILABLE] = FALSE; // ??? 376 SharedUserData->ProcessorFeatures[PF_NX_ENABLED] = TRUE; 377 SharedUserData->ProcessorFeatures[PF_SSE3_INSTRUCTIONS_AVAILABLE] = 378 (FeatureBits & KF_SSE3) ? TRUE : FALSE; 379 SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE128] = 380 (FeatureBits & KF_CMPXCHG16B) ? TRUE : FALSE; 381 SharedUserData->ProcessorFeatures[PF_COMPARE64_EXCHANGE128] = FALSE; // ??? 382 SharedUserData->ProcessorFeatures[PF_CHANNELS_ENABLED] = FALSE; // ??? 383 SharedUserData->ProcessorFeatures[PF_XSAVE_ENABLED] = FALSE; // FIXME 384 SharedUserData->ProcessorFeatures[PF_SECOND_LEVEL_ADDRESS_TRANSLATION] = 385 (FeatureBits & KF_SLAT) ? TRUE : FALSE; 386 SharedUserData->ProcessorFeatures[PF_VIRT_FIRMWARE_ENABLED] = 387 (FeatureBits & KF_VIRT_FIRMWARE_ENABLED) ? TRUE : FALSE; 388 SharedUserData->ProcessorFeatures[PF_RDWRFSGSBASE_AVAILABLE] = 389 (FeatureBits & KF_RDWRFSGSBASE) ? TRUE : FALSE; 390 SharedUserData->ProcessorFeatures[PF_FASTFAIL_AVAILABLE] = TRUE; 391 SharedUserData->ProcessorFeatures[PF_RDRAND_INSTRUCTION_AVAILABLE] = 392 (FeatureBits & KF_RDRAND) ? TRUE : FALSE; 393 SharedUserData->ProcessorFeatures[PF_RDTSCP_INSTRUCTION_AVAILABLE] = 394 (FeatureBits & KF_RDTSCP) ? TRUE : FALSE; 395 SharedUserData->ProcessorFeatures[PF_RDPID_INSTRUCTION_AVAILABLE] = FALSE; // ??? 396 SharedUserData->ProcessorFeatures[PF_SSSE3_INSTRUCTIONS_AVAILABLE] = 397 (FeatureBits & KF_SSSE3) ? TRUE : FALSE; 398 SharedUserData->ProcessorFeatures[PF_SSE4_1_INSTRUCTIONS_AVAILABLE] = 399 (FeatureBits & KF_SSE4_1) ? TRUE : FALSE; 400 SharedUserData->ProcessorFeatures[PF_SSE4_2_INSTRUCTIONS_AVAILABLE] = 401 (FeatureBits & KF_SSE4_2) ? TRUE : FALSE; 402 SharedUserData->ProcessorFeatures[PF_AVX_INSTRUCTIONS_AVAILABLE] = FALSE; // FIXME 403 SharedUserData->ProcessorFeatures[PF_AVX2_INSTRUCTIONS_AVAILABLE] = FALSE; // FIXME 404 SharedUserData->ProcessorFeatures[PF_AVX512F_INSTRUCTIONS_AVAILABLE] = FALSE; // FIXME 405 406 /* Set the default NX policy (opt-in) */ 407 SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN; 408 409 /* Check if NPX is always on */ 410 if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSON")) 411 { 412 /* Set it always on */ 413 SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON; 414 Prcb->FeatureBits |= KF_NX_ENABLED; 415 } 416 else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT")) 417 { 418 /* Set it in opt-out mode */ 419 SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTOUT; 420 Prcb->FeatureBits |= KF_NX_ENABLED; 421 } 422 else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) || 423 (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE"))) 424 { 425 /* Set the feature bits */ 426 Prcb->FeatureBits |= KF_NX_ENABLED; 427 } 428 else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSOFF")) || 429 (strstr(KeLoaderBlock->LoadOptions, "EXECUTE"))) 430 { 431 /* Set disabled mode */ 432 SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSOFF; 433 Prcb->FeatureBits |= KF_NX_DISABLED; 434 } 435 436 #if DBG 437 /* Print applied kernel features/policies and boot CPU features */ 438 KiReportCpuFeatures(Prcb); 439 #endif 440 } 441 442 static LDR_DATA_TABLE_ENTRY LdrCoreEntries[3]; 443 444 void 445 KiInitModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 446 { 447 PLDR_DATA_TABLE_ENTRY LdrEntry; 448 PLIST_ENTRY Entry; 449 ULONG i; 450 451 /* Initialize the list head */ 452 InitializeListHead(&PsLoadedModuleList); 453 454 /* Loop the first 3 entries */ 455 for (Entry = LoaderBlock->LoadOrderListHead.Flink, i = 0; 456 Entry != &LoaderBlock->LoadOrderListHead && i < 3; 457 Entry = Entry->Flink, i++) 458 { 459 /* Get the data table entry */ 460 LdrEntry = CONTAINING_RECORD(Entry, 461 LDR_DATA_TABLE_ENTRY, 462 InLoadOrderLinks); 463 464 /* Copy the entry */ 465 LdrCoreEntries[i] = *LdrEntry; 466 467 /* Insert the copy into the list */ 468 InsertTailList(&PsLoadedModuleList, &LdrCoreEntries[i].InLoadOrderLinks); 469 } 470 } 471 472 CODE_SEG("INIT") 473 DECLSPEC_NORETURN 474 VOID 475 NTAPI 476 KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 477 { 478 CCHAR Cpu; 479 PKTHREAD InitialThread; 480 ULONG64 InitialStack; 481 PKIPCR Pcr; 482 483 /* Boot cycles timestamp */ 484 BootCycles = __rdtsc(); 485 486 /* HACK */ 487 FrLdrDbgPrint = LoaderBlock->u.I386.CommonDataArea; 488 //FrLdrDbgPrint("Hello from KiSystemStartup!!!\n"); 489 490 /* Get the current CPU number */ 491 Cpu = KeNumberProcessors++; // FIXME 492 493 /* LoaderBlock initialization for Cpu 0 */ 494 if (Cpu == 0) 495 { 496 /* Save the loader block */ 497 KeLoaderBlock = LoaderBlock; 498 499 /* Prepare LoaderBlock, PCR, TSS with the P0 boot data */ 500 KiInitializeP0BootStructures(LoaderBlock); 501 } 502 503 /* Get Pcr from loader block */ 504 Pcr = CONTAINING_RECORD(LoaderBlock->Prcb, KIPCR, Prcb); 505 506 /* Set the PRCB for this Processor */ 507 KiProcessorBlock[Cpu] = &Pcr->Prcb; 508 509 /* Align stack to 16 bytes */ 510 LoaderBlock->KernelStack &= ~(16 - 1); 511 512 /* Save the initial thread and stack */ 513 InitialStack = LoaderBlock->KernelStack; // Checkme 514 InitialThread = (PKTHREAD)LoaderBlock->Thread; 515 516 /* Set us as the current process */ 517 InitialThread->ApcState.Process = (PVOID)LoaderBlock->Process; 518 519 /* Initialize the CPU features */ 520 KiInitializeCpu(Pcr); 521 522 /* Initial setup for the boot CPU */ 523 if (Cpu == 0) 524 { 525 /* Initialize the module list (ntos, hal, kdcom) */ 526 KiInitModuleList(LoaderBlock); 527 528 /* Setup the IDT */ 529 KeInitExceptions(); 530 531 /* Initialize debugging system */ 532 KdInitSystem(0, KeLoaderBlock); 533 534 /* Check for break-in */ 535 if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); 536 } 537 538 DPRINT1("Pcr = %p, Gdt = %p, Idt = %p, Tss = %p\n", 539 Pcr, Pcr->GdtBase, Pcr->IdtBase, Pcr->TssBase); 540 541 /* Acquire lock */ 542 while (InterlockedBitTestAndSet64((PLONG64)&KiFreezeExecutionLock, 0)) 543 { 544 /* Loop until lock is free */ 545 while ((*(volatile KSPIN_LOCK*)&KiFreezeExecutionLock) & 1); 546 } 547 548 /* Initialize the Processor with HAL */ 549 HalInitializeProcessor(Cpu, KeLoaderBlock); 550 551 /* Set processor as active */ 552 KeActiveProcessors |= 1ULL << Cpu; 553 554 /* Release lock */ 555 InterlockedAnd64((PLONG64)&KiFreezeExecutionLock, 0); 556 557 /* Raise to HIGH_LEVEL */ 558 KfRaiseIrql(HIGH_LEVEL); 559 560 /* Machine specific kernel initialization */ 561 if (Cpu == 0) KiInitializeKernelMachineDependent(&Pcr->Prcb, LoaderBlock); 562 563 /* Switch to new kernel stack and start kernel bootstrapping */ 564 KiSwitchToBootStack(InitialStack & ~3); 565 } 566 567