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.

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