Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1079 lines
24 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. initkr.c
  5. Abstract:
  6. This module contains the code to initialize the kernel data structures
  7. and to initialize the idle thread, its process, the processor control
  8. block, and the processor control region.
  9. Author:
  10. David N. Cutler (davec) 22-Apr-2000
  11. Environment:
  12. Kernel mode only.
  13. --*/
  14. #include "ki.h"
  15. //
  16. // Define default profile IRQL level.
  17. //
  18. KIRQL KiProfileIrql = PROFILE_LEVEL;
  19. //
  20. // Define the process and thread for the initial system process and startup
  21. // thread.
  22. //
  23. EPROCESS KiInitialProcess;
  24. ETHREAD KiInitialThread;
  25. //
  26. // Define macro to initialize an IDT entry.
  27. //
  28. // KiInitializeIdtEntry (
  29. // IN PKIDTENTRY64 Entry,
  30. // IN PVOID Address,
  31. // IN USHORT Level
  32. // )
  33. //
  34. // Arguments:
  35. //
  36. // Entry - Supplies a pointer to an IDT entry.
  37. //
  38. // Address - Supplies the address of the vector routine.
  39. //
  40. // Dpl - Descriptor privilege level.
  41. //
  42. // Ist - Interrupt stack index.
  43. //
  44. #define KiInitializeIdtEntry(Entry, Address, Level, Index) \
  45. (Entry)->OffsetLow = (USHORT)((ULONG64)(Address)); \
  46. (Entry)->Selector = KGDT64_R0_CODE; \
  47. (Entry)->IstIndex = Index; \
  48. (Entry)->Type = 0xe; \
  49. (Entry)->Dpl = (Level); \
  50. (Entry)->Present = 1; \
  51. (Entry)->OffsetMiddle = (USHORT)((ULONG64)(Address) >> 16); \
  52. (Entry)->OffsetHigh = (ULONG)((ULONG64)(Address) >> 32) \
  53. //
  54. // Define forward referenced prototypes.
  55. //
  56. ULONG
  57. KiFatalFilter (
  58. IN ULONG Code,
  59. IN PEXCEPTION_POINTERS Pointers
  60. );
  61. VOID
  62. KiSetCacheInformation (
  63. VOID
  64. );
  65. VOID
  66. KiSetCpuVendor (
  67. VOID
  68. );
  69. VOID
  70. KiSetFeatureBits (
  71. VOID
  72. );
  73. VOID
  74. KiSetProcessorType (
  75. VOID
  76. );
  77. #pragma alloc_text(INIT, KiFatalFilter)
  78. #pragma alloc_text(INIT, KiInitializeBootStructures)
  79. #pragma alloc_text(INIT, KiInitializeKernel)
  80. #pragma alloc_text(INIT, KiInitMachineDependent)
  81. #pragma alloc_text(INIT, KiSetCacheInformation)
  82. #pragma alloc_text(INIT, KiSetCpuVendor)
  83. #pragma alloc_text(INIT, KiSetFeatureBits)
  84. #pragma alloc_text(INIT, KiSetProcessorType)
  85. VOID
  86. KiInitializeKernel (
  87. IN PKPROCESS Process,
  88. IN PKTHREAD Thread,
  89. IN PVOID IdleStack,
  90. IN PKPRCB Prcb,
  91. IN CCHAR Number,
  92. PLOADER_PARAMETER_BLOCK LoaderBlock
  93. )
  94. /*++
  95. Routine Description:
  96. This function gains control after the system has been booted, but before
  97. the system has been completely initialized. Its function is to initialize
  98. the kernel data structures, initialize the idle thread and process objects,
  99. complete the initialization of the processor control block (PRCB) and
  100. processor control region (PCR), call the executive initialization routine,
  101. then return to the system startup routine. This routine is also called to
  102. initialize the processor specific structures when a new processor is
  103. brought on line.
  104. Arguments:
  105. Process - Supplies a pointer to a control object of type process for
  106. the specified processor.
  107. Thread - Supplies a pointer to a dispatcher object of type thread for
  108. the specified processor.
  109. IdleStack - Supplies a pointer the base of the real kernel stack for
  110. idle thread on the specified processor.
  111. Prcb - Supplies a pointer to a processor control block for the specified
  112. processor.
  113. Number - Supplies the number of the processor that is being
  114. initialized.
  115. LoaderBlock - Supplies a pointer to the loader parameter block.
  116. Return Value:
  117. None.
  118. --*/
  119. {
  120. ULONG FeatureBits;
  121. LONG Index;
  122. ULONG64 DirectoryTableBase[2];
  123. KIRQL OldIrql;
  124. PKPCR Pcr = KeGetPcr();
  125. //
  126. // Set CPU vendor.
  127. //
  128. KiSetCpuVendor();
  129. //
  130. // Set processor type.
  131. //
  132. KiSetProcessorType();
  133. //
  134. // Set the processor feature bits.
  135. //
  136. KiSetFeatureBits();
  137. FeatureBits = Prcb->FeatureBits;
  138. //
  139. // If this is the boot processor, then enable global pages, set the page
  140. // attributes table, set machine check enable, set large page enable, and
  141. // enable debug extensions.
  142. //
  143. // N.B. This only happens on the boot processor and at a time when there
  144. // can be no coherency problem. On subsequent, processors this happens
  145. // during the transistion into 64-bit mode which is also at a time
  146. // that there can be no coherency problems.
  147. //
  148. if (Number == 0) {
  149. //
  150. // Flush the entire TB and enable global pages.
  151. //
  152. KeFlushCurrentTb();
  153. //
  154. // Set page attributes table and flush cache.
  155. //
  156. KiSetPageAttributesTable();
  157. WritebackInvalidate();
  158. //
  159. // Set machine check enable, large page enable, and debugger extensions.
  160. //
  161. WriteCR4(ReadCR4() | CR4_DE | CR4_MCE | CR4_PSE);
  162. //
  163. // Flush the entire TB.
  164. //
  165. KeFlushCurrentTb();
  166. }
  167. //
  168. // set processor cache size information.
  169. //
  170. KiSetCacheInformation();
  171. //
  172. // Initialize DPC listhead, spin lock, and queuing parameters.
  173. //
  174. InitializeListHead(&Prcb->DpcListHead);
  175. KeInitializeSpinLock(&Prcb->DpcLock);
  176. Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
  177. Prcb->MinimumDpcRate = KiMinimumDpcRate;
  178. Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
  179. //
  180. // Initialize power state information.
  181. //
  182. PoInitializePrcb(Prcb);
  183. //
  184. // initialize the per processor lock queue entry for implemented locks.
  185. //
  186. KiInitQueuedSpinLocks(Prcb, Number);
  187. //
  188. // If the initial processor is being initialized, then initialize the
  189. // per system data structures.
  190. //
  191. if (Number == 0) {
  192. //
  193. // Set default node until the node topology is available.
  194. //
  195. KeNodeBlock[0] = &KiNode0;
  196. #if defined(KE_MULTINODE)
  197. for (Index = 1; Index < MAXIMUM_CCNUMA_NODES; Index += 1) {
  198. KeNodeBlock[Index] = &KiNodeInit[Index];
  199. }
  200. #endif
  201. Prcb->ParentNode = KeNodeBlock[0];
  202. KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
  203. //
  204. // Set global architecture and feature information.
  205. //
  206. KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
  207. KeProcessorLevel = (USHORT)Prcb->CpuType;
  208. KeProcessorRevision = Prcb->CpuStep;
  209. KeFeatureBits = FeatureBits;
  210. //
  211. // Lower IRQL to APC level.
  212. //
  213. KeLowerIrql(APC_LEVEL);
  214. //
  215. // Initialize kernel internal spinlocks
  216. //
  217. KeInitializeSpinLock(&KiFreezeExecutionLock);
  218. //
  219. // Performance architecture independent initialization.
  220. //
  221. KiInitSystem();
  222. //
  223. // Initialize idle thread process object and then set:
  224. //
  225. // 1. the process quantum.
  226. //
  227. DirectoryTableBase[0] = 0;
  228. DirectoryTableBase[1] = 0;
  229. KeInitializeProcess(Process,
  230. (KPRIORITY)0,
  231. (KAFFINITY)(-1),
  232. &DirectoryTableBase[0],
  233. FALSE);
  234. Process->ThreadQuantum = MAXCHAR;
  235. } else {
  236. //
  237. // If the CPU feature bits are not identical, then bugcheck.
  238. //
  239. // N.B. This will probably need to be relaxed at some point.
  240. //
  241. if (FeatureBits != KeFeatureBits) {
  242. KeBugCheckEx(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
  243. (ULONG64)FeatureBits,
  244. (ULONG64)KeFeatureBits,
  245. 0,
  246. 0);
  247. }
  248. //
  249. // Lower IRQL to DISPATCH level.
  250. //
  251. KeLowerIrql(DISPATCH_LEVEL);
  252. }
  253. //
  254. // Set global processor features.
  255. //
  256. SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
  257. SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
  258. SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
  259. SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = TRUE;
  260. SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
  261. SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = TRUE;
  262. SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
  263. //
  264. // Initialize idle thread object and then set:
  265. //
  266. // 1. the next processor number to the specified processor.
  267. // 2. the thread priority to the highest possible value.
  268. // 3. the state of the thread to running.
  269. // 4. the thread affinity to the specified processor.
  270. // 5. the specified member in the process active processors set.
  271. //
  272. KeInitializeThread(Thread,
  273. (PVOID)((ULONG64)IdleStack),
  274. NULL,
  275. NULL,
  276. NULL,
  277. NULL,
  278. NULL,
  279. Process);
  280. Thread->NextProcessor = Number;
  281. Thread->Priority = HIGH_PRIORITY;
  282. Thread->State = Running;
  283. Thread->Affinity = AFFINITY_MASK(Number);
  284. Thread->WaitIrql = DISPATCH_LEVEL;
  285. Process->ActiveProcessors |= AFFINITY_MASK(Number);
  286. //
  287. // Call the executive initialization routine.
  288. //
  289. try {
  290. ExpInitializeExecutive(Number, LoaderBlock);
  291. } except(KiFatalFilter(GetExceptionCode(), GetExceptionInformation())) {
  292. }
  293. //
  294. // If the initial processor is being initialized, then compute the timer
  295. // table reciprocal value, reset the PRCB values for the controllable DPC
  296. // behavior in order to reflect any registry overrides, and initialize the
  297. // global unwind history table.
  298. //
  299. if (Number == 0) {
  300. KiTimeIncrementReciprocal = KiComputeReciprocal((LONG)KeMaximumIncrement,
  301. &KiTimeIncrementShiftCount);
  302. Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
  303. Prcb->MinimumDpcRate = KiMinimumDpcRate;
  304. Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
  305. RtlInitializeHistoryTable();
  306. }
  307. //
  308. // Raise IRQL to dispatch level and eet the priority of the idle thread
  309. // to zero. This will have the effect of immediately causing the phase
  310. // one initialization thread to get scheduled for execution. The idle
  311. // thread priority is then set ot the lowest realtime priority.
  312. //
  313. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  314. KeSetPriorityThread(Thread, 0);
  315. Thread->Priority = LOW_REALTIME_PRIORITY;
  316. //
  317. // Raise IRQL to highest level.
  318. //
  319. KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  320. //
  321. // If the current processor is a secondary processor and a thread has
  322. // not been selected for execution, then set the appropriate bit in the
  323. // idle summary.
  324. //
  325. #if !defined(NT_UP)
  326. if ((Number != 0) && (Prcb->NextThread == NULL)) {
  327. KiIdleSummary |= AFFINITY_MASK(Number);
  328. }
  329. #endif
  330. //
  331. // Signal that this processor has completed its initialization.
  332. //
  333. LoaderBlock->Prcb = (ULONG64)NULL;
  334. return;
  335. }
  336. VOID
  337. KiInitializeBootStructures (
  338. PLOADER_PARAMETER_BLOCK LoaderBlock
  339. )
  340. /*++
  341. Routine Description:
  342. This function initializes the boot structures for a processor. It is only
  343. called by the system start up code. Certain fields in the boot structures
  344. have already been initialized. In particular:
  345. The address and limit of the GDT and IDT in the PCR.
  346. The address of the system TSS in the PCR.
  347. The processor number in the PCR.
  348. The special registers in the PRCB.
  349. N.B. All uninitialized fields are zero.
  350. Arguments:
  351. LoaderBlock - Supplies a pointer to the loader block that has been
  352. initialized for this processor.
  353. Return Value:
  354. None.
  355. --*/
  356. {
  357. PKIDTENTRY64 IdtBase;
  358. ULONG Index;
  359. PKPCR Pcr = KeGetPcr();
  360. PKPRCB Prcb = KeGetCurrentPrcb();
  361. UCHAR Number;
  362. PKTHREAD Thread;
  363. PKTSS64 TssBase;
  364. //
  365. // Initialize the PCR major and minor version numbers.
  366. //
  367. Pcr->MajorVersion = PCR_MAJOR_VERSION;
  368. Pcr->MinorVersion = PCR_MINOR_VERSION;
  369. //
  370. // initialize the PRCB major and minor version numbers and build type.
  371. //
  372. Prcb->MajorVersion = PRCB_MAJOR_VERSION;
  373. Prcb->MinorVersion = PRCB_MINOR_VERSION;
  374. Prcb->BuildType = 0;
  375. #if DBG
  376. Prcb->BuildType |= PRCB_BUILD_DEBUG;
  377. #endif
  378. #if defined(NT_UP)
  379. Prcb->BuildType |= PRCB_BUILD_UNIPROCESSOR;
  380. #endif
  381. //
  382. // Initialize the PRCR processor number and the PCR and PRCB set member.
  383. //
  384. Number = Pcr->Number;
  385. Prcb->Number = Number;
  386. Prcb->SetMember = AFFINITY_MASK(Number);
  387. Prcb->NotSetMember = ~Prcb->SetMember;
  388. //
  389. // If this is processor zero, then initialize the address of the system
  390. // process and initial thread.
  391. //
  392. if (Number == 0) {
  393. LoaderBlock->Process = (ULONG64)&KiInitialProcess;
  394. LoaderBlock->Thread = (ULONG64)&KiInitialThread;
  395. }
  396. //
  397. // Initialize the PRCB scheduling thread address and the thread process
  398. // address.
  399. //
  400. Thread = (PVOID)LoaderBlock->Thread;
  401. Prcb->CurrentThread = Thread;
  402. Prcb->NextThread = NULL;
  403. Prcb->IdleThread = Thread;
  404. Thread->ApcState.Process = (PKPROCESS)LoaderBlock->Process;
  405. //
  406. // Initialize the processor block address.
  407. //
  408. KiProcessorBlock[Number] = Prcb;
  409. //
  410. // Initialize the PRCB address of the DPC stack.
  411. //
  412. Prcb->DpcStack = (PVOID)LoaderBlock->KernelStack;
  413. //
  414. // Initialize the PRCB symmetric multithreading member.
  415. //
  416. Prcb->MultiThreadProcessorSet = Prcb->SetMember;
  417. //
  418. // Initialize the IDT.
  419. //
  420. IdtBase = Pcr->IdtBase;
  421. KiInitializeIdtEntry(&IdtBase[0], &KiDivideErrorFault, 0, 0);
  422. KiInitializeIdtEntry(&IdtBase[1], &KiDebugTrapOrFault, 0, 0);
  423. KiInitializeIdtEntry(&IdtBase[2], &KiNmiInterrupt, 0, TSS_IST_PANIC);
  424. KiInitializeIdtEntry(&IdtBase[3], &KiBreakpointTrap, 3, 0);
  425. KiInitializeIdtEntry(&IdtBase[4], &KiOverflowTrap, 3, 0);
  426. KiInitializeIdtEntry(&IdtBase[5], &KiBoundFault, 0, 0);
  427. KiInitializeIdtEntry(&IdtBase[6], &KiInvalidOpcodeFault, 0, 0);
  428. KiInitializeIdtEntry(&IdtBase[7], &KiNpxNotAvailableFault, 0, 0);
  429. KiInitializeIdtEntry(&IdtBase[8], &KiDoubleFaultAbort, 0, TSS_IST_PANIC);
  430. KiInitializeIdtEntry(&IdtBase[9], &KiNpxSegmentOverrunAbort, 0, 0);
  431. KiInitializeIdtEntry(&IdtBase[10], &KiInvalidTssFault, 0, 0);
  432. KiInitializeIdtEntry(&IdtBase[11], &KiSegmentNotPresentFault, 0, 0);
  433. KiInitializeIdtEntry(&IdtBase[12], &KiStackFault, 0, 0);
  434. KiInitializeIdtEntry(&IdtBase[13], &KiGeneralProtectionFault, 0, 0);
  435. KiInitializeIdtEntry(&IdtBase[14], &KiPageFault, 0, 0);
  436. KiInitializeIdtEntry(&IdtBase[15], &KxUnexpectedInterrupt0[15], 0, 0);
  437. KiInitializeIdtEntry(&IdtBase[16], &KiFloatingErrorFault, 0, 0);
  438. KiInitializeIdtEntry(&IdtBase[17], &KiAlignmentFault, 0, 0);
  439. KiInitializeIdtEntry(&IdtBase[18], &KiMcheckAbort, 0, TSS_IST_MCA);
  440. KiInitializeIdtEntry(&IdtBase[19], &KiXmmException, 0, 0);
  441. KiInitializeIdtEntry(&IdtBase[20], &KxUnexpectedInterrupt0[20], 0, 0);
  442. KiInitializeIdtEntry(&IdtBase[21], &KxUnexpectedInterrupt0[21], 0, 0);
  443. KiInitializeIdtEntry(&IdtBase[22], &KxUnexpectedInterrupt0[22], 0, 0);
  444. KiInitializeIdtEntry(&IdtBase[23], &KxUnexpectedInterrupt0[23], 0, 0);
  445. KiInitializeIdtEntry(&IdtBase[24], &KxUnexpectedInterrupt0[24], 0, 0);
  446. KiInitializeIdtEntry(&IdtBase[25], &KxUnexpectedInterrupt0[25], 0, 0);
  447. KiInitializeIdtEntry(&IdtBase[26], &KxUnexpectedInterrupt0[26], 0, 0);
  448. KiInitializeIdtEntry(&IdtBase[27], &KxUnexpectedInterrupt0[27], 0, 0);
  449. KiInitializeIdtEntry(&IdtBase[28], &KxUnexpectedInterrupt0[28], 0, 0);
  450. KiInitializeIdtEntry(&IdtBase[29], &KxUnexpectedInterrupt0[29], 0, 0);
  451. KiInitializeIdtEntry(&IdtBase[30], &KxUnexpectedInterrupt0[30], 0, 0);
  452. KiInitializeIdtEntry(&IdtBase[31], &KiApcInterrupt, 0, 0);
  453. KiInitializeIdtEntry(&IdtBase[32], &KxUnexpectedInterrupt0[32], 0, 0);
  454. KiInitializeIdtEntry(&IdtBase[33], &KxUnexpectedInterrupt0[33], 0, 0);
  455. KiInitializeIdtEntry(&IdtBase[34], &KxUnexpectedInterrupt0[34], 0, 0);
  456. KiInitializeIdtEntry(&IdtBase[35], &KxUnexpectedInterrupt0[35], 0, 0);
  457. KiInitializeIdtEntry(&IdtBase[36], &KxUnexpectedInterrupt0[36], 0, 0);
  458. KiInitializeIdtEntry(&IdtBase[37], &KxUnexpectedInterrupt0[37], 0, 0);
  459. KiInitializeIdtEntry(&IdtBase[38], &KxUnexpectedInterrupt0[38], 0, 0);
  460. KiInitializeIdtEntry(&IdtBase[39], &KxUnexpectedInterrupt0[39], 0, 0);
  461. KiInitializeIdtEntry(&IdtBase[40], &KxUnexpectedInterrupt0[40], 0, 0);
  462. KiInitializeIdtEntry(&IdtBase[41], &KxUnexpectedInterrupt0[41], 0, 0);
  463. KiInitializeIdtEntry(&IdtBase[42], &KxUnexpectedInterrupt0[42], 0, 0);
  464. KiInitializeIdtEntry(&IdtBase[43], &KxUnexpectedInterrupt0[43], 0, 0);
  465. KiInitializeIdtEntry(&IdtBase[44], &KxUnexpectedInterrupt0[44], 0, 0);
  466. KiInitializeIdtEntry(&IdtBase[45], &KiDebugServiceTrap, 3, 0);
  467. KiInitializeIdtEntry(&IdtBase[46], &KxUnexpectedInterrupt0[46], 0, 0);
  468. KiInitializeIdtEntry(&IdtBase[47], &KiDpcInterrupt, 0, 0);
  469. //
  470. // Initialize unexpected interrupt entries.
  471. //
  472. for (Index = PRIMARY_VECTOR_BASE; Index <= MAXIMUM_IDTVECTOR; Index += 1) {
  473. KiInitializeIdtEntry(&IdtBase[Index],
  474. &KxUnexpectedInterrupt0[Index],
  475. 0,
  476. 0);
  477. }
  478. //
  479. // Initialize the system TSS I/O Map.
  480. //
  481. TssBase = Pcr->TssBase;
  482. RtlFillMemory(&TssBase->IoMap[0], sizeof(KIO_ACCESS_MAP), -1);
  483. TssBase->IoMapEnd = -1;
  484. TssBase->IoMapBase = KiComputeIopmOffset(FALSE);
  485. //
  486. // Initialize the stack base and limit.
  487. //
  488. Pcr->NtTib.StackBase = (PVOID)(TssBase->Rsp0);
  489. Pcr->NtTib.StackLimit = (PVOID)(TssBase->Rsp0 - KERNEL_STACK_SIZE);
  490. //
  491. // Initialize the system call MSRs.
  492. //
  493. // N.B. CSTAR must be written before LSTAR to work around a bug in the
  494. // simulator.
  495. //
  496. WriteMSR(MSR_STAR,
  497. ((ULONG64)KGDT64_R0_CODE << 32) | (((ULONG64)KGDT64_R3_CMCODE | RPL_MASK) << 48));
  498. WriteMSR(MSR_CSTAR, (ULONG64)&KiSystemCall32);
  499. WriteMSR(MSR_LSTAR, (ULONG64)&KiSystemCall64);
  500. WriteMSR(MSR_SYSCALL_MASK, EFLAGS_IF_MASK | EFLAGS_TF_MASK);
  501. //
  502. // Initialize the HAL for this processor.
  503. //
  504. HalInitializeProcessor(Number, LoaderBlock);
  505. //
  506. // Set the appropriate member in the active processors set.
  507. //
  508. KeActiveProcessors |= AFFINITY_MASK(Number);
  509. //
  510. // Set the number of processors based on the maximum of the current
  511. // number of processors and the current processor number.
  512. //
  513. if ((Number + 1) > KeNumberProcessors) {
  514. KeNumberProcessors = Number + 1;
  515. }
  516. return;
  517. }
  518. ULONG
  519. KiFatalFilter (
  520. IN ULONG Code,
  521. IN PEXCEPTION_POINTERS Pointers
  522. )
  523. /*++
  524. Routine Description:
  525. This function is executed if an unhandled exception occurs during
  526. phase 0 initialization. Its function is to bug check the system
  527. with all the context information still on the stack.
  528. Arguments:
  529. Code - Supplies the exception code.
  530. Pointers - Supplies a pointer to the exception information.
  531. Return Value:
  532. None - There is no return from this routine even though it appears there
  533. is.
  534. --*/
  535. {
  536. KeBugCheckEx(PHASE0_EXCEPTION,
  537. Code,
  538. (ULONG64)Pointers,
  539. 0,
  540. 0);
  541. return EXCEPTION_EXECUTE_HANDLER;
  542. }
  543. BOOLEAN
  544. KiInitMachineDependent (
  545. VOID
  546. )
  547. /*++
  548. Routine Description:
  549. This function initializes machine dependent data structures and hardware.
  550. Arguments:
  551. None.
  552. Return Value:
  553. None.
  554. --*/
  555. {
  556. ULONG Size;
  557. NTSTATUS Status;
  558. BOOLEAN UseFrameBufferCaching;
  559. //
  560. // Query the HAL to determine if the write combining can be used for the
  561. // frame buffer.
  562. //
  563. Status = HalQuerySystemInformation(HalFrameBufferCachingInformation,
  564. sizeof(BOOLEAN),
  565. &UseFrameBufferCaching,
  566. &Size);
  567. //
  568. // If the status is successful and frame buffer caching is disabled,
  569. // then don't enable write combining.
  570. //
  571. if (!NT_SUCCESS(Status) || (UseFrameBufferCaching != FALSE)) {
  572. MmEnablePAT();
  573. }
  574. return TRUE;
  575. }
  576. VOID
  577. KiSetCacheInformation (
  578. VOID
  579. )
  580. /*++
  581. Routine Description:
  582. This function sets the current processor cache information in the PCR.
  583. Arguments:
  584. None.
  585. Return Value:
  586. None.
  587. --*/
  588. {
  589. UCHAR Associativity;
  590. ULONG CacheSize;
  591. CPU_INFO CpuInfo;
  592. ULONG LineSize;
  593. PKPCR Pcr = KeGetPcr();
  594. //
  595. // Get the CPU L2 cache information.
  596. //
  597. KiCpuId(0x80000006, &CpuInfo);
  598. //
  599. // Get the L2 cache line size.
  600. //
  601. LineSize = CpuInfo.Ecx & 0xff;
  602. //
  603. // Get the L2 cache size.
  604. //
  605. CacheSize = (CpuInfo.Ecx >> 16) << 10;
  606. //
  607. // Compute the L2 cache associativity.
  608. //
  609. switch ((CpuInfo.Ecx >> 12) & 0xf) {
  610. //
  611. // Two way set associative.
  612. //
  613. case 2:
  614. Associativity = 2;
  615. break;
  616. //
  617. // Four way set associative.
  618. //
  619. case 4:
  620. Associativity = 4;
  621. break;
  622. //
  623. // Six way set associative.
  624. //
  625. case 6:
  626. Associativity = 6;
  627. break;
  628. //
  629. // Eight way set associative.
  630. //
  631. case 8:
  632. Associativity = 8;
  633. break;
  634. //
  635. // Fully associative.
  636. //
  637. case 255:
  638. Associativity = 16;
  639. break;
  640. //
  641. // Direct mapped.
  642. //
  643. default:
  644. Associativity = 1;
  645. break;
  646. }
  647. //
  648. // Set L2 cache information.
  649. //
  650. Pcr->SecondLevelCacheAssociativity = Associativity;
  651. Pcr->SecondLevelCacheSize = CacheSize;
  652. //
  653. // If the line size is greater then the current largest line size, then
  654. // set the new largest line size.
  655. //
  656. if (LineSize > KeLargestCacheLine) {
  657. KeLargestCacheLine = LineSize;
  658. }
  659. return;
  660. }
  661. VOID
  662. KiSetCpuVendor (
  663. VOID
  664. )
  665. /*++
  666. Routine Description:
  667. Set the current processor cpu vendor information in the PRCB.
  668. Arguments:
  669. None.
  670. Return Value:
  671. None.
  672. --*/
  673. {
  674. PKPRCB Prcb = KeGetCurrentPrcb();
  675. CPU_INFO CpuInfo;
  676. ULONG Temp;
  677. //
  678. // Get the CPU vendor string.
  679. //
  680. KiCpuId(0, &CpuInfo);
  681. //
  682. // Copy vendor string to PRCB.
  683. //
  684. Temp = CpuInfo.Ecx;
  685. CpuInfo.Ecx = CpuInfo.Edx;
  686. CpuInfo.Edx = Temp;
  687. RtlCopyMemory(Prcb->VendorString,
  688. &CpuInfo.Ebx,
  689. sizeof(Prcb->VendorString) - 1);
  690. Prcb->VendorString[sizeof(Prcb->VendorString) - 1] = '\0';
  691. return;
  692. }
  693. VOID
  694. KiSetFeatureBits (
  695. VOID
  696. )
  697. /*++
  698. Routine Description:
  699. Set the current processor feature bits in the PRCB.
  700. Arguments:
  701. None.
  702. Return Value:
  703. None.
  704. --*/
  705. {
  706. CPU_INFO CpuInfo;
  707. ULONG FeatureBits;
  708. PKPRCB Prcb = KeGetCurrentPrcb();
  709. //
  710. // Get CPU feature information.
  711. //
  712. KiCpuId(1, &CpuInfo);
  713. //
  714. // Set the initial APIC ID.
  715. //
  716. Prcb->InitialApicId = (UCHAR)(CpuInfo.Ebx >> 24);
  717. //
  718. // If the required fetures are not present, then bugcheck.
  719. //
  720. if ((CpuInfo.Edx & HF_REQUIRED) != HF_REQUIRED) {
  721. KeBugCheckEx(UNSUPPORTED_PROCESSOR, CpuInfo.Edx, 0, 0, 0);
  722. }
  723. FeatureBits = KF_REQUIRED;
  724. if (CpuInfo.Edx & 0x00200000) {
  725. FeatureBits |= KF_DTS;
  726. }
  727. //
  728. // Get extended CPU feature information.
  729. //
  730. KiCpuId(0x80000000, &CpuInfo);
  731. //
  732. // Check the extended feature bits.
  733. //
  734. if (CpuInfo.Edx & 0x80000000) {
  735. FeatureBits |= KF_3DNOW;
  736. }
  737. Prcb->LogicalProcessorsPerPhysicalProcessor = 1;
  738. Prcb->FeatureBits = FeatureBits;
  739. return;
  740. }
  741. VOID
  742. KiSetProcessorType (
  743. VOID
  744. )
  745. /*++
  746. Routine Description:
  747. This function sets the current processor family and stepping in the PRCB.
  748. Arguments:
  749. None.
  750. Return Value:
  751. None.
  752. --*/
  753. {
  754. CPU_INFO CpuInfo;
  755. PKPRCB Prcb = KeGetCurrentPrcb();
  756. //
  757. // Get cpu feature information.
  758. //
  759. KiCpuId(1, &CpuInfo);
  760. //
  761. // Set processor family and stepping information.
  762. //
  763. Prcb->CpuID = TRUE;
  764. Prcb->CpuType = (CCHAR)((CpuInfo.Eax >> 8) & 0xf);
  765. Prcb->CpuStep = (USHORT)(((CpuInfo.Eax << 4) & 0xf00) | (CpuInfo.Eax & 0xf));
  766. return;
  767. }
  768. VOID
  769. KeOptimizeProcessorControlState (
  770. VOID
  771. )
  772. /*++
  773. Routine Description:
  774. This function performs no operation on AMD64.
  775. Arguments:
  776. None.
  777. Return Value:
  778. None.
  779. --*/
  780. {
  781. return;
  782. }