Leaked source code of windows server 2003
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.

1237 lines
33 KiB

  1. /*++
  2. Copyright (c) 1990 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, and the processor control
  8. block.
  9. Author:
  10. Bernard Lint 8-Aug-1996
  11. Environment:
  12. Kernel mode only.
  13. Revision History:
  14. Based on MIPS version (David N. Cutler (davec) 11-Apr-1990)
  15. --*/
  16. #include "ki.h"
  17. //
  18. // Put all code for kernel initialization in the INIT section. It will be
  19. // deallocated by memory management when phase 1 initialization is completed.
  20. //
  21. VOID
  22. KiInitializeProcessorIds(
  23. IN PKPRCB Prcb
  24. );
  25. ULONG
  26. KiGetFeatureBits(
  27. IN PKPRCB Prcb
  28. );
  29. VOID
  30. FASTCALL
  31. KiZeroPages (
  32. IN PVOID PageBase,
  33. IN SIZE_T NumberOfPages
  34. );
  35. #if defined(ALLOC_PRAGMA)
  36. #pragma alloc_text(INIT, KiGetFeatureBits)
  37. #pragma alloc_text(INIT, KiInitializeProcessorIds)
  38. #pragma alloc_text(INIT, KiInitializeKernel)
  39. #pragma alloc_text(INIT, KiInitMachineDependent)
  40. #endif
  41. KE_ZERO_PAGE_ROUTINE KeZeroPages = KiZeroPages;
  42. KE_ZERO_PAGE_ROUTINE KeZeroPagesFromIdleThread = KiZeroPages;
  43. //
  44. // KiTbBroadcastLock - This is the spin lock that prevents the other processors
  45. // from issuing PTC.G (TB purge broadcast) operations.
  46. //
  47. KSPIN_LOCK KiTbBroadcastLock;
  48. //
  49. // KiMasterRidLock - This is the spin lock that prevents the other processors
  50. // from updating KiMasterRid.
  51. //
  52. KSPIN_LOCK KiMasterRidLock;
  53. //
  54. // KiRegionSwapLock - This is the lock that covers all context swap operations
  55. //
  56. KSPIN_LOCK KiRegionSwapLock;
  57. //
  58. // KiCacheFlushLock - This is the spin lock that ensures cache flush is only
  59. // done on one processor at a time. (SAL cache flush not yet MP safe).
  60. //
  61. KSPIN_LOCK KiCacheFlushLock;
  62. //
  63. // KiUserSharedDataPage - This holds the page number of UserSharedDataPage for
  64. // MP boot
  65. //
  66. ULONG_PTR KiUserSharedDataPage;
  67. //
  68. // KiKernelPcrPage - This holds the page number of per-processor PCR page for
  69. // MP boot
  70. //
  71. ULONG_PTR KiKernelPcrPage = 0i64;
  72. //
  73. // VHPT configuation variables
  74. //
  75. IA64_VM_SUMMARY1 KiIA64VmSummary1;
  76. IA64_VM_SUMMARY2 KiIA64VmSummary2;
  77. IA64_PTCE_INFO KiIA64PtceInfo;
  78. ULONG_PTR KiIA64PtaContents;
  79. ULONG_PTR KiIA64PtaHpwEnabled = 1;
  80. ULONG_PTR KiIA64VaSign;
  81. ULONG_PTR KiIA64VaSignedFill;
  82. ULONG_PTR KiIA64PtaBase;
  83. ULONG_PTR KiIA64PtaSign;
  84. ULONG KiIA64ImpVirtualMsb;
  85. ULONG KiNumberOfCacheLevels;
  86. IA64_CACHE_INFO1 KiCacheInfo1[2][CONFIG_INFO_CACHE_LEVELS]; // Pass several levels of cache information
  87. IA64_CACHE_INFO2 KiCacheInfo2[2][CONFIG_INFO_CACHE_LEVELS]; // One each for instruction and data.
  88. ULONG_PTR KiIA64RseNumOfPhysRegs;
  89. ULONG_PTR KiIA64RseNumOfMaxDirty;
  90. ULONG_PTR KiIA64RseHints;
  91. extern ULONG KiMaximumRid;
  92. //
  93. // KiExceptionDeferralMode - This holds the mode for the exception deferral
  94. // policy
  95. //
  96. ULONG KiExceptionDeferralMode;
  97. //
  98. // KiBackingStoreSecurityMode - This holds the security policy for the backing store
  99. //
  100. ULONG KiBackingStoreSecurityMode = 1;
  101. //
  102. // Initial DCR value
  103. //
  104. ULONGLONG KiIA64DCR = DCR_INITIAL;
  105. //
  106. // KiVectorLogMask - bitmap for enable/disable the interruption logging
  107. //
  108. LONGLONG KiVectorLogMask;
  109. //
  110. // KiHistoryBufferLogMask - bitmap for enable/disable the history buffer logging
  111. //
  112. LONGLONG KiHistoryBufferLogMask;
  113. //
  114. // Definition of bits that must be set in user's PSR value
  115. // N.B. Initial value of bit PSR_DI in UserPsrSetMask is 0.
  116. //
  117. ULONGLONG UserPsrSetMask = PSR_USER_SET;
  118. //
  119. // Ensure all the PSR bits are represented in all the mask once and only once.
  120. //
  121. C_ASSERT((PSR_KERNEL_CLR ^ PSR_KERNEL_SET ^ PSR_KERNEL_CPY) == -1);
  122. C_ASSERT((PSR_USER_CLR ^ PSR_USER_SET ^ PSR_USER_CPY) == -1);
  123. ULONG
  124. KiGetFeatureBits(
  125. PKPRCB Prcb
  126. )
  127. /*++
  128. Routine Description:
  129. This function returns the NT Feature Bits supported by the specified
  130. processor control block.
  131. Arguments:
  132. Prcb - Supplies a pointer to a processor control block for the specified
  133. processor.
  134. Return Value:
  135. None.
  136. Comments:
  137. This function is called after the initialization of the IA64 processor
  138. control block ProcessorFeatureBits field and after HalInitializeProcessor().
  139. --*/
  140. {
  141. // WARNING: NT system wide feature bits is a 32-bit type.
  142. ULONG features = (ULONG) Prcb->ProcessorFeatureBits;
  143. //
  144. // Check for Long Branch instruction support.
  145. //
  146. if ( features & 0x1 ) {
  147. features |= KF_BRL;
  148. }
  149. return features;
  150. } // KiGetFeatureBits()
  151. VOID
  152. KiInitializeProcessorIds(
  153. IN PKPRCB Prcb
  154. )
  155. /*++
  156. Routine Description:
  157. This function is called early in the initialization of the kernel
  158. to initialize the processor indentification registers located
  159. in the processor control block.
  160. This function is called for each processor and should be called b
  161. before the HAL is called.
  162. Arguments:
  163. Prcb - Supplies a pointer to a processor control block for the specified
  164. processor.
  165. Return Value:
  166. None.
  167. Comments:
  168. This function simply deals with IA64 architected CPUID registers.
  169. --*/
  170. {
  171. ULONGLONG val;
  172. // IA64 architected CPUID3: Version information.
  173. val = __getReg( CV_IA64_CPUID3 );
  174. Prcb->ProcessorRevision = (ULONG) ((val >> 8 ) & 0xFF);
  175. Prcb->ProcessorModel = (ULONG) ((val >> 16) & 0xFF);
  176. Prcb->ProcessorFamily = (ULONG) ((val >> 24) & 0xFF);
  177. Prcb->ProcessorArchRev = (ULONG) ((val >> 32) & 0xFF);
  178. // IA64 architected CPUID0 & CPUID1: Vendor Information.
  179. val = __getReg( CV_IA64_CPUID0 );
  180. strncpy( (PCHAR) Prcb->ProcessorVendorString , (PCHAR)&val, 8 );
  181. val = __getReg( CV_IA64_CPUID1 );
  182. strncpy( (PCHAR)&Prcb->ProcessorVendorString[8], (PCHAR)&val, 8 );
  183. // IA64 architected CPUID2: Processor Serial Number.
  184. Prcb->ProcessorSerialNumber = __getReg( CV_IA64_CPUID2 );
  185. // IA64 architected CPUID4: General Features / Capability bits.
  186. Prcb->ProcessorFeatureBits = __getReg( CV_IA64_CPUID4 );
  187. if ( (Prcb->ProcessorFamily != 0x7) && (Prcb->ProcessorFamily != 0x1F) ) {
  188. //
  189. // If it is neither Itanium nor Itanium2, ISA transition
  190. // is disabled
  191. //
  192. UserPsrSetMask |= MASK_IA64(PSR_DI, 1i64);
  193. }
  194. return;
  195. } // KiInitializeProcessorIds()
  196. #if defined(_MERCED_A0_)
  197. VOID
  198. KiProcessorWorkAround(
  199. );
  200. VOID
  201. KiSwitchToLogVector(
  202. VOID
  203. );
  204. extern BOOLEAN KiIpiTbShootdown;
  205. ULONGLONG KiConfigFlag;
  206. //
  207. // Process the boot loader configuration flags.
  208. //
  209. VOID
  210. KiProcessorConfigFlag(
  211. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  212. )
  213. {
  214. PCHAR ConfigFlag;
  215. ULONG ConfigFlagValue=0;
  216. ULONGLONG Cpuid3;
  217. ULONGLONG ItaniumId;
  218. ULONGLONG PalFeatureSet;
  219. LONGLONG Status;
  220. Cpuid3 = __getReg( CV_IA64_CPUID3 );
  221. ItaniumId = 0xFFFFFF0000I64 & Cpuid3;
  222. ConfigFlag = strstr(LoaderBlock->LoadOptions, "CONFIGFLAG");
  223. if (ConfigFlag != NULL) {
  224. ConfigFlag = strstr(ConfigFlag, "=");
  225. if (ConfigFlag != NULL) {
  226. ConfigFlagValue = atol(ConfigFlag+1);
  227. }
  228. } else {
  229. //
  230. // Set the recommened ConfigFlagValue for Itanium, B1/B2
  231. // if there is no CONFIGFLAG keyword
  232. //
  233. if (ItaniumId == 0x0007000000) {
  234. switch (Cpuid3) {
  235. case 0x0007000004: // Itanium, A stepping
  236. case 0x0007000104: // Itanium, B0 stepping
  237. ConfigFlagValue = 0;
  238. break;
  239. case 0x0007000204: // Itanium, B1 stepping
  240. case 0x0007000304: // Itanium, B2 stepping
  241. ConfigFlagValue = 1054;
  242. break;
  243. case 0x0007000404: // Itanium, B3 stepping
  244. case 0x0007000504: // Itanium, B4 stepping
  245. ConfigFlagValue = 19070;
  246. break;
  247. case 0x0007000604: // Itanium, C0 or later stepping
  248. ConfigFlagValue = 2943 | (1 << DISABLE_INTERRUPTION_LOG);
  249. break;
  250. default:
  251. ConfigFlagValue = 35711 | (1 << DISABLE_INTERRUPTION_LOG);
  252. }
  253. } else {
  254. //
  255. // Make ptc.g enabled by default
  256. //
  257. ConfigFlagValue = 32 | (1 << DISABLE_INTERRUPTION_LOG);
  258. }
  259. }
  260. //
  261. // Save config flag value.
  262. //
  263. KiConfigFlag = ConfigFlagValue;
  264. //
  265. // do the processor MSR workarounds
  266. //
  267. KiProcessorWorkAround(ConfigFlagValue);
  268. //
  269. // Call PAL to disable McKinley 692 workaround to improve
  270. // performance. Disable should not be done if kernel does a
  271. // br.ret from kernel to user mode.
  272. //
  273. if (ItaniumId == 0x001F000000) {
  274. // Get current feature settings
  275. Status = HalCallPal (PAL_PROC_GET_FEATURES, 0, 16, 0,
  276. NULL, NULL, &PalFeatureSet, NULL);
  277. if (Status == PAL_STATUS_SUCCESS) {
  278. // Disable workaround: bit 7 = 1
  279. PalFeatureSet |= 0x80;
  280. Status = HalCallPal (PAL_PROC_SET_FEATURES, PalFeatureSet, 16, 0,
  281. NULL, NULL, NULL, NULL);
  282. }
  283. }
  284. //
  285. // For Conditional Interrupt Logging
  286. // switch to shadow IVT depending on ConfigFlag
  287. //
  288. if (ConfigFlagValue & (1 << DISABLE_INTERRUPTION_LOG)) {
  289. KiVectorLogMask = 0;
  290. } else {
  291. //
  292. // By default disable logging of:
  293. // KiAltInstTlbVectorBit 3
  294. // KiAltDataTlbVectorBit 4
  295. //
  296. KiVectorLogMask = 0xffffffffffffffffI64;
  297. KiSwitchToLogVector();
  298. }
  299. if (ConfigFlagValue & (1 << ENABLE_HISTORY_BUFFER)) {
  300. KiHistoryBufferLogMask = 0xffffffffffffffffI64;
  301. } else {
  302. KiHistoryBufferLogMask = 0;
  303. }
  304. //
  305. // check to see if the VHPT walker should be disabled
  306. //
  307. if (ConfigFlagValue & (1 << DISABLE_VHPT_WALKER)) {
  308. KiIA64PtaHpwEnabled = 0;
  309. }
  310. }
  311. #endif
  312. ULONG
  313. KiInitializeKernelUnhandledExceptionFilter(
  314. IN PEXCEPTION_POINTERS ExceptionPointers
  315. )
  316. {
  317. KdPrint(("KE: Unhandled Kernel Mode Exception Pointers = 0x%p\n", ExceptionPointers));
  318. KdPrint(("Code %x Addr %p\nInfo0 %p Info1 %p Info2 %p\nInfo3 %p Info4 %p Info5 %p\n",
  319. ExceptionPointers->ExceptionRecord->ExceptionCode,
  320. (ULONG_PTR)ExceptionPointers->ExceptionRecord->ExceptionAddress,
  321. ExceptionPointers->ExceptionRecord->ExceptionInformation[0],
  322. ExceptionPointers->ExceptionRecord->ExceptionInformation[1],
  323. ExceptionPointers->ExceptionRecord->ExceptionInformation[2],
  324. ExceptionPointers->ExceptionRecord->ExceptionInformation[3],
  325. ExceptionPointers->ExceptionRecord->ExceptionInformation[4],
  326. ExceptionPointers->ExceptionRecord->ExceptionInformation[5]
  327. ));
  328. KeBugCheckEx(
  329. PHASE0_EXCEPTION,
  330. ExceptionPointers->ExceptionRecord->ExceptionCode,
  331. (ULONG_PTR)ExceptionPointers->ExceptionRecord->ExceptionAddress,
  332. ExceptionPointers->ExceptionRecord->ExceptionInformation[0],
  333. ExceptionPointers->ExceptionRecord->ExceptionInformation[1]
  334. );
  335. }
  336. VOID
  337. KiInitializeKernel (
  338. IN PKPROCESS Process,
  339. IN PKTHREAD Thread,
  340. IN PVOID IdleStack,
  341. IN PKPRCB Prcb,
  342. IN CCHAR Number,
  343. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  344. )
  345. /*++
  346. Routine Description:
  347. This function gains control after the system has been bootstrapped and
  348. before the system has been initialized. Its function is to initialize
  349. the kernel data structures, initialize the idle thread and process objects,
  350. initialize the processor control block, call the executive initialization
  351. routine, and then return to the system startup routine. This routine is
  352. also called to initialize the processor specific structures when a new
  353. processor is brought on line.
  354. Arguments:
  355. Process - Supplies a pointer to a control object of type process for
  356. the specified processor.
  357. Thread - Supplies a pointer to a dispatcher object of type thread for
  358. the specified processor.
  359. IdleStack - Supplies a pointer the base of the real kernel stack for
  360. idle thread on the specified processor.
  361. Prcb - Supplies a pointer to a processor control block for the specified
  362. processor.
  363. Number - Supplies the number of the processor that is being
  364. initialized.
  365. LoaderBlock - Supplies a pointer to the loader parameter block.
  366. Return Value:
  367. None.
  368. --*/
  369. {
  370. LONG Index;
  371. KIRQL OldIrql;
  372. ULONG_PTR DirectoryTableBase[2];
  373. PVOID KernelStack;
  374. USHORT ProcessorRevision;
  375. //
  376. // Perform Processor Identification Registers update.
  377. //
  378. // This has to be done before HalInitializeProcessor to offer
  379. // a possibility for the HAL to look at them.
  380. //
  381. KiInitializeProcessorIds( Prcb );
  382. //
  383. // Perform platform dependent processor initialization.
  384. //
  385. HalInitializeProcessor(Number, LoaderBlock);
  386. //
  387. // Apply processor config flag and workarounds
  388. //
  389. KiProcessorConfigFlag(LoaderBlock);
  390. //
  391. // Save the address of the loader parameter block.
  392. //
  393. KeLoaderBlock = LoaderBlock;
  394. //
  395. // Initialize the processor block.
  396. //
  397. Prcb->MinorVersion = PRCB_MINOR_VERSION;
  398. Prcb->MajorVersion = PRCB_MAJOR_VERSION;
  399. Prcb->BuildType = 0;
  400. #if DBG
  401. Prcb->BuildType |= PRCB_BUILD_DEBUG;
  402. #endif
  403. #if defined(NT_UP)
  404. Prcb->BuildType |= PRCB_BUILD_UNIPROCESSOR;
  405. #endif
  406. Prcb->CurrentThread = Thread;
  407. Prcb->NextThread = (PKTHREAD)NULL;
  408. Prcb->IdleThread = Thread;
  409. Prcb->Number = Number;
  410. Prcb->SetMember = AFFINITY_MASK(Number);
  411. Prcb->PcrPage = LoaderBlock->u.Ia64.PcrPage;
  412. //
  413. // initialize the per processor lock data.
  414. //
  415. KiInitSpinLocks(Prcb, Number);
  416. //
  417. // Initialize the interprocessor communication packet.
  418. //
  419. #if !defined(NT_UP)
  420. Prcb->TargetSet = 0;
  421. Prcb->WorkerRoutine = NULL;
  422. Prcb->RequestSummary = 0;
  423. Prcb->IpiFrozen = 0;
  424. #endif
  425. //
  426. // Set address of processor block.
  427. //
  428. KiProcessorBlock[Number] = Prcb;
  429. //
  430. // Initialize processors PowerState
  431. //
  432. PoInitializePrcb (Prcb);
  433. //
  434. // Set global processor architecture. Global processor level and
  435. // revision will be set on a least common denominator basis.
  436. //
  437. KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64;
  438. ProcessorRevision = (USHORT) ((Prcb->ProcessorModel << 8) |
  439. Prcb->ProcessorRevision);
  440. //
  441. // Initialize the address of the bus error routines / machine check
  442. //
  443. // **** TBD
  444. //
  445. // Initialize the idle thread initial kernel stack and limit address value.
  446. //
  447. PCR->InitialStack = (ULONGLONG)IdleStack;
  448. PCR->InitialBStore = (ULONGLONG)IdleStack;
  449. PCR->StackLimit = (ULONGLONG)((ULONG_PTR)IdleStack - KERNEL_STACK_SIZE);
  450. PCR->BStoreLimit = (ULONGLONG)((ULONG_PTR)IdleStack + KERNEL_BSTORE_SIZE);
  451. //
  452. // Initialize pointers to the SAL event resource structures.
  453. //
  454. PCR->OsMcaResourcePtr = (PSAL_EVENT_RESOURCES) &PCR->OsMcaResource;
  455. PCR->OsInitResourcePtr = (PSAL_EVENT_RESOURCES) &PCR->OsInitResource;
  456. //
  457. // Initialize all interrupt vectors to transfer control to the unexpected
  458. // interrupt routine.
  459. //
  460. // N.B. This interrupt object is never actually "connected" to an interrupt
  461. // vector via KeConnectInterrupt. It is initialized and then connected
  462. // by simply storing the address of the dispatch code in the interrupt
  463. // vector.
  464. //
  465. if (Number == 0) {
  466. //
  467. // Set default node. Used in non-multinode systems and in
  468. // multinode systems until the node topology is available.
  469. //
  470. extern KNODE KiNode0;
  471. KeNodeBlock[0] = &KiNode0;
  472. #if defined(KE_MULTINODE)
  473. for (Index = 1; Index < MAXIMUM_CCNUMA_NODES; Index++) {
  474. extern KNODE KiNodeInit[];
  475. //
  476. // Set temporary node.
  477. //
  478. KeNodeBlock[Index] = &KiNodeInit[Index];
  479. }
  480. #endif
  481. //
  482. // Set baseline global processor level and revision.
  483. //
  484. KeProcessorLevel = (USHORT) Prcb->ProcessorFamily;
  485. KeProcessorRevision = ProcessorRevision;
  486. Prcb->ParentNode = KeNodeBlock[0];
  487. KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
  488. //
  489. // Initialize system wide FeatureBits with BSP processor feature bits.
  490. //
  491. KeFeatureBits = KiGetFeatureBits( Prcb ) ;
  492. //
  493. // Initialize the Tb Broadcast spinlock.
  494. //
  495. KeInitializeSpinLock(&KiTbBroadcastLock);
  496. //
  497. // Initialize the Master Rid spinlock.
  498. //
  499. KeInitializeSpinLock(&KiMasterRidLock);
  500. //
  501. // Initialize the cache flush spinlock.
  502. //
  503. KeInitializeSpinLock(&KiCacheFlushLock);
  504. //
  505. // Initial the address of the interrupt dispatch routine.
  506. //
  507. KxUnexpectedInterrupt.DispatchAddress = KiUnexpectedInterrupt;
  508. //
  509. // Copy the interrupt dispatch function descriptor into the interrupt
  510. // object.
  511. //
  512. for (Index = 0; Index < DISPATCH_LENGTH; Index += 1) {
  513. KxUnexpectedInterrupt.DispatchCode[Index] =
  514. *(((PULONG)(ULONG_PTR)(KxUnexpectedInterrupt.DispatchAddress))+Index);
  515. }
  516. //
  517. // Set the default DMA I/O coherency attributes. IA64
  518. // architecture dictates that the D-Cache is fully coherent.
  519. //
  520. KiDmaIoCoherency = DMA_READ_DCACHE_INVALIDATE | DMA_WRITE_DCACHE_SNOOP;
  521. //
  522. // Set KiSharedUserData for MP boot
  523. //
  524. KiUserSharedDataPage = LoaderBlock->u.Ia64.PcrPage2;
  525. //
  526. // Get implementatoin specific VM info
  527. //
  528. KiIA64VmSummary1 = LoaderBlock->u.Ia64.ProcessorConfigInfo.VmSummaryInfo1;
  529. KiIA64VmSummary2 = LoaderBlock->u.Ia64.ProcessorConfigInfo.VmSummaryInfo2;
  530. KiIA64PtceInfo = LoaderBlock->u.Ia64.ProcessorConfigInfo.PtceInfo;
  531. KiMaximumRid = ((ULONG)1 << KiIA64VmSummary2.RidSize) - 1;
  532. //
  533. // Get implementation specific RSE info
  534. //
  535. KiIA64RseNumOfPhysRegs = LoaderBlock->u.Ia64.ProcessorConfigInfo.NumOfPhysStackedRegs;
  536. KiIA64RseHints = LoaderBlock->u.Ia64.ProcessorConfigInfo.RseHints;
  537. //
  538. // Initialize the VHPT variables
  539. //
  540. KiIA64ImpVirtualMsb = (ULONG)KiIA64VmSummary2.ImplVaMsb;
  541. KiIA64VaSign = (ULONGLONG)1 << KiIA64ImpVirtualMsb;
  542. KiIA64PtaSign = KiIA64VaSign >> (PAGE_SHIFT - PTE_SHIFT);
  543. KiIA64VaSignedFill =
  544. (ULONGLONG)((LONGLONG)VRN_MASK >> (60-KiIA64ImpVirtualMsb)) & ~VRN_MASK;
  545. KiIA64PtaBase =
  546. (ULONGLONG)((LONGLONG)(VRN_MASK|KiIA64VaSignedFill)
  547. >> (PAGE_SHIFT - PTE_SHIFT)) & ~VRN_MASK;
  548. KiIA64PtaContents =
  549. KiIA64PtaBase |
  550. ((KiIA64ImpVirtualMsb - PAGE_SHIFT + PTE_SHIFT + 1) << PS_SHIFT) |
  551. KiIA64PtaHpwEnabled;
  552. if (LoaderBlock->u.Ia64.ProcessorConfigInfo.NumberOfCacheLevels > 0) {
  553. KeLargestCacheLine = LoaderBlock->u.Ia64.ProcessorConfigInfo.LargestCacheLine;
  554. KiNumberOfCacheLevels = LoaderBlock->u.Ia64.ProcessorConfigInfo.NumberOfCacheLevels;
  555. memcpy(&KiCacheInfo1, &LoaderBlock->u.Ia64.ProcessorConfigInfo.CacheInfo1, sizeof(KiCacheInfo1));
  556. memcpy(&KiCacheInfo2, &LoaderBlock->u.Ia64.ProcessorConfigInfo.CacheInfo2, sizeof(KiCacheInfo2));
  557. }
  558. //
  559. // enable the VHPT
  560. //
  561. __setReg(CV_IA64_ApPTA, KiIA64PtaContents);
  562. __isrlz();
  563. //
  564. // Set up the NT page base addresses
  565. //
  566. PCR->PteUbase = UADDRESS_BASE | KiIA64PtaBase;
  567. PCR->PteKbase = KADDRESS_BASE | KiIA64PtaBase;
  568. PCR->PteSbase = SADDRESS_BASE | KiIA64PtaBase;
  569. PCR->PdeUbase = PCR->PteUbase | (PCR->PteUbase >> (PTI_SHIFT-PTE_SHIFT));
  570. PCR->PdeKbase = PCR->PteKbase | (PCR->PteKbase >> (PTI_SHIFT-PTE_SHIFT));
  571. PCR->PdeSbase = PCR->PteSbase | (PCR->PteSbase >> (PTI_SHIFT-PTE_SHIFT));
  572. PCR->PdeUtbase = PCR->PteUbase | (PCR->PdeUbase >> (PTI_SHIFT-PTE_SHIFT));
  573. PCR->PdeKtbase = PCR->PteKbase | (PCR->PdeKbase >> (PTI_SHIFT-PTE_SHIFT));
  574. PCR->PdeStbase = PCR->PteSbase | (PCR->PdeSbase >> (PTI_SHIFT-PTE_SHIFT));
  575. }
  576. else {
  577. //
  578. // Set global processor level and revision to least common denominator
  579. //
  580. if (KeProcessorLevel > (USHORT) Prcb->ProcessorFamily) {
  581. KeProcessorLevel = (USHORT) Prcb->ProcessorFamily;
  582. KeProcessorRevision = ProcessorRevision;
  583. } else if ((KeProcessorLevel == (USHORT) Prcb->ProcessorFamily) &&
  584. (KeProcessorRevision > ProcessorRevision)) {
  585. KeProcessorRevision = ProcessorRevision;
  586. }
  587. //
  588. // Mask off feature bits that are not supported on all processors.
  589. //
  590. KeFeatureBits &= KiGetFeatureBits( Prcb );
  591. }
  592. //
  593. // Initialize the cache sizes in the PCR. We currently assume the sizes are the same
  594. // on all processors.
  595. //
  596. if (KiNumberOfCacheLevels > 0) {
  597. PCR->FirstLevelDcacheSize = (ULONG) KiCacheInfo2[CONFIG_INFO_DCACHE][0].Size;
  598. PCR->FirstLevelDcacheFillSize = 1UL << KiCacheInfo1[CONFIG_INFO_DCACHE][0].LineSize;
  599. PCR->FirstLevelIcacheSize = (ULONG) KiCacheInfo2[CONFIG_INFO_ICACHE][0].Size;
  600. PCR->FirstLevelIcacheFillSize = 1UL << KiCacheInfo1[CONFIG_INFO_ICACHE][0].LineSize;
  601. }
  602. if (KeLargestCacheLine > 1) {
  603. PCR->SecondLevelDcacheSize = (ULONG) KiCacheInfo2[CONFIG_INFO_DCACHE][1].Size;
  604. PCR->SecondLevelDcacheFillSize = 1UL << KiCacheInfo1[CONFIG_INFO_DCACHE][1].LineSize;
  605. PCR->SecondLevelIcacheSize = (ULONG) KiCacheInfo2[CONFIG_INFO_ICACHE][1].Size;
  606. PCR->SecondLevelIcacheFillSize = 1UL << KiCacheInfo1[CONFIG_INFO_ICACHE][1].LineSize;
  607. }
  608. //
  609. // Point to UnexpectedInterrupt function pointer
  610. //
  611. for (Index = 0; Index < MAXIMUM_VECTOR; Index += 1) {
  612. PCR->InterruptRoutine[Index] =
  613. (PKINTERRUPT_ROUTINE)((ULONG_PTR)&KxUnexpectedInterrupt.DispatchCode);
  614. }
  615. //
  616. // Initialize the profile count and interval.
  617. //
  618. PCR->ProfileCount = 0;
  619. PCR->ProfileInterval = 0x200000;
  620. //
  621. // Initialize the passive release, APC, and DPC interrupt vectors.
  622. //
  623. PCR->InterruptRoutine[0] = KiPassiveRelease;
  624. PCR->InterruptRoutine[APC_VECTOR] = KiApcInterrupt;
  625. PCR->InterruptRoutine[DISPATCH_VECTOR] = KiDispatchInterrupt;
  626. //
  627. // N.B. Reserve levels, not vectors
  628. //
  629. PCR->ReservedVectors = (1 << PASSIVE_LEVEL) | (1 << APC_LEVEL) | (1 << DISPATCH_LEVEL);
  630. //
  631. // Initialize the set member for the current processor, set IRQL to
  632. // APC_LEVEL, and set the processor number.
  633. //
  634. KeLowerIrql(APC_LEVEL);
  635. PCR->SetMember = AFFINITY_MASK(Number);
  636. PCR->NotMember = ~PCR->SetMember;
  637. PCR->Number = Number;
  638. //
  639. // Set the initial stall execution scale factor. This value will be
  640. // recomputed later by the HAL.
  641. //
  642. PCR->StallScaleFactor = 50;
  643. //
  644. // Set address of process object in thread object.
  645. //
  646. Thread->ApcState.Process = Process;
  647. PCR->Pcb = (PVOID)Process;
  648. //
  649. // Initialize the idle process region id. Session ids are initialized
  650. // in memory management.
  651. //
  652. Process->ProcessRegion.RegionId = START_PROCESS_RID;
  653. Process->ProcessRegion.SequenceNumber = START_SEQUENCE;
  654. //
  655. // Set the appropriate member in the active processors set.
  656. //
  657. KeActiveProcessors |= AFFINITY_MASK(Number);
  658. //
  659. // Set the number of processors based on the maximum of the current
  660. // number of processors and the current processor number.
  661. //
  662. if ((Number + 1) > KeNumberProcessors) {
  663. KeNumberProcessors = (CCHAR)(Number + 1);
  664. }
  665. //
  666. // If the initial processor is being initialized, then initialize the
  667. // per system data structures.
  668. //
  669. if (Number == 0) {
  670. Prcb->RestartBlock = NULL;
  671. //
  672. // Initialize the kernel debugger.
  673. //
  674. if (KdInitSystem(0, LoaderBlock) == FALSE) {
  675. KeBugCheck(PHASE0_INITIALIZATION_FAILED);
  676. }
  677. //
  678. // Initialize processor block array.
  679. //
  680. for (Index = 1; Index < MAXIMUM_PROCESSORS; Index += 1) {
  681. KiProcessorBlock[Index] = (PKPRCB)NULL;
  682. }
  683. //
  684. // Perform architecture independent initialization.
  685. //
  686. KiInitSystem();
  687. //
  688. // Initialize idle thread process object and then set:
  689. //
  690. // 1. all the quantum values to the maximum possible.
  691. // 2. the process in the balance set.
  692. // 3. the active processor mask to the specified processor.
  693. //
  694. DirectoryTableBase[0] = 0;
  695. DirectoryTableBase[1] = 0;
  696. KeInitializeProcess(Process,
  697. (KPRIORITY)0,
  698. (KAFFINITY)(-1),
  699. &DirectoryTableBase[0],
  700. FALSE);
  701. Process->ThreadQuantum = MAXCHAR;
  702. }
  703. // Update processor features.
  704. // This assumes an iVE exists or other ability to emulate the ia32
  705. // instruction set at the ability of the iVE on Merced (Itanium).
  706. //
  707. SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
  708. SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
  709. SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
  710. SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
  711. //
  712. //
  713. // Initialize idle thread object and then set:
  714. //
  715. // 1. the initial kernel stack to the specified idle stack.
  716. // 2. the next processor number to the specified processor.
  717. // 3. the thread priority to the highest possible value.
  718. // 4. the state of the thread to running.
  719. // 5. the thread affinity to the specified processor.
  720. // 6. the specified processor member in the process active processors
  721. // set.
  722. //
  723. KernelStack = (PVOID)((ULONG_PTR)IdleStack - PAGE_SIZE);
  724. KeInitializeThread(Thread,
  725. KernelStack,
  726. (PKSYSTEM_ROUTINE)KeBugCheck,
  727. NULL,
  728. NULL,
  729. NULL,
  730. NULL,
  731. Process);
  732. Thread->InitialStack = IdleStack;
  733. Thread->InitialBStore = IdleStack;
  734. Thread->StackBase = IdleStack;
  735. Thread->StackLimit = (PVOID)((ULONG_PTR)IdleStack - KERNEL_STACK_SIZE);
  736. Thread->BStoreLimit = (PVOID)((ULONG_PTR)IdleStack + KERNEL_BSTORE_SIZE);
  737. Thread->NextProcessor = Number;
  738. Thread->Priority = HIGH_PRIORITY;
  739. Thread->State = Running;
  740. Thread->Affinity = AFFINITY_MASK(Number);
  741. Thread->WaitIrql = DISPATCH_LEVEL;
  742. //
  743. // If the current processor is 0, then set the appropriate bit in the
  744. // active summary of the idle process.
  745. //
  746. if (Number == 0) {
  747. Process->ActiveProcessors |= AFFINITY_MASK(Number);
  748. }
  749. //
  750. // Execute the executive initialization.
  751. //
  752. try {
  753. ExpInitializeExecutive(Number, LoaderBlock);
  754. } except (KiInitializeKernelUnhandledExceptionFilter(GetExceptionInformation())) {
  755. // WARNING: this code is unreachable, because
  756. // WARNING: KiInitializeKernelUnhandledExceptionFilter calls
  757. // WARNING: KeBugCheckEx!
  758. // KeBugCheck (PHASE0_EXCEPTION);
  759. }
  760. //
  761. // check for the exception deferral mode
  762. //
  763. if (KiExceptionDeferralMode != 0) {
  764. KiIA64DCR = DCR_INITIAL ^ (1 << DCR_DM);
  765. }
  766. //
  767. // initialize the DCR deferral bits
  768. //
  769. __setReg(CV_IA64_ApDCR, KiIA64DCR);
  770. //
  771. // If KiBackingStoreSecurityMode is non-zero then enable the srubing of the
  772. // RSE registres in kernel user transisions.
  773. //
  774. if (KiBackingStoreSecurityMode != 0) {
  775. KiIA64RseNumOfMaxDirty = KiIA64RseNumOfPhysRegs + ((KiIA64RseNumOfPhysRegs + 62) / 63);
  776. } else {
  777. //
  778. // making 0 makes no scrubbing performed on kernel-user transisions
  779. //
  780. KiIA64RseNumOfMaxDirty = 0;
  781. }
  782. //
  783. // If the initial processor is being initialized, then compute the
  784. // timer table reciprocal value and reset the PRCB values for the
  785. // controllable DPC behavior in order to reflect any registry
  786. // overrides.
  787. //
  788. if (Number == 0) {
  789. KiTimeIncrementReciprocal = KiComputeReciprocal((LONG)KeMaximumIncrement,
  790. &KiTimeIncrementShiftCount);
  791. Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
  792. Prcb->MinimumDpcRate = KiMinimumDpcRate;
  793. Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
  794. RtlInitializeHistoryTable();
  795. }
  796. //
  797. // Raise IRQL to dispatch level and set the priority of the idle thread
  798. // to zero. This will have the effect of immediately causing the phase
  799. // one initialization thread to get scheduled for execution. The idle
  800. // thread priority is then set to the lowest realtime priority. This is
  801. // necessary so that mutexes aquired at DPC level do not cause the active
  802. // matrix to get corrupted.
  803. //
  804. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  805. KeSetPriorityThread(Thread, (KPRIORITY)0);
  806. Thread->Priority = LOW_REALTIME_PRIORITY;
  807. //
  808. // Raise IRQL to the highest level.
  809. //
  810. KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  811. #if !defined(NT_UP)
  812. //
  813. // Indicate boot complete on secondary processor
  814. //
  815. LoaderBlock->Prcb = 0;
  816. //
  817. // If the current processor is not 0, then set the appropriate bit in
  818. // idle summary.
  819. //
  820. KiAcquirePrcbLock(Prcb);
  821. if ((Number != 0) && (Prcb->NextThread == NULL)) {
  822. KiIdleSummary |= AFFINITY_MASK(Number);
  823. }
  824. KiReleasePrcbLock(Prcb);
  825. #endif
  826. return;
  827. }
  828. BOOLEAN
  829. KiInitMachineDependent (
  830. VOID
  831. )
  832. /*++
  833. Routine Description:
  834. This function performs machine-specific initialization by querying the HAL.
  835. N.B. This function is only called during phase1 initialization.
  836. Arguments:
  837. None.
  838. Return Value:
  839. A value of TRUE is returned if initialization is successful. Otherwise,
  840. a value of FALSE is returned.
  841. --*/
  842. {
  843. HAL_PLATFORM_INFORMATION PlatformInfo;
  844. HAL_PROCESSOR_SPEED_INFORMATION ProcessorSpeedInfo;
  845. NTSTATUS Status;
  846. BOOLEAN UseFrameBufferCaching;
  847. ULONG Size;
  848. //
  849. // check to see if we should switch to PTC.G-based TB shootdown
  850. //
  851. Status = HalQuerySystemInformation(HalPlatformInformation,
  852. sizeof(PlatformInfo),
  853. &PlatformInfo,
  854. &Size);
  855. if (NT_SUCCESS(Status) &&
  856. (PlatformInfo.PlatformFlags & HAL_PLATFORM_DISABLE_PTCG)) {
  857. //
  858. // Will continue not to use PTC.G
  859. //
  860. }
  861. else {
  862. //
  863. // Use PTC.G if processor support is there.
  864. //
  865. if (KiConfigFlag & (1 << ENABLE_TB_BROADCAST)) {
  866. KiIpiTbShootdown = FALSE;
  867. }
  868. }
  869. //
  870. // If the HAL indicates write combining is not supported, drop it.
  871. //
  872. Status = HalQuerySystemInformation(HalFrameBufferCachingInformation,
  873. sizeof(UseFrameBufferCaching),
  874. &UseFrameBufferCaching,
  875. &Size);
  876. if (NT_SUCCESS(Status) && (UseFrameBufferCaching == FALSE)) {
  877. //
  878. // Hal says don't use.
  879. //
  880. NOTHING;
  881. }
  882. else {
  883. MmEnablePAT ();
  884. }
  885. //
  886. // Ask HAL for Processor Speed
  887. //
  888. Status = HalQuerySystemInformation(HalProcessorSpeedInformation,
  889. sizeof(ProcessorSpeedInfo),
  890. &ProcessorSpeedInfo,
  891. &Size);
  892. if (NT_SUCCESS(Status)) {
  893. PKPRCB Prcb;
  894. ULONG i;
  895. //
  896. // Put the Processor Speed into the Prcb structure so others
  897. // can reference it later.
  898. //
  899. for (i = 0; i < (ULONG)KeNumberProcessors; i++ ) {
  900. Prcb = KiProcessorBlock[i];
  901. Prcb->MHz = (USHORT)ProcessorSpeedInfo.ProcessorSpeed;
  902. }
  903. }
  904. return TRUE;
  905. }