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.

649 lines
15 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. David N. Cutler (davec) 11-Apr-1990
  11. Environment:
  12. Kernel mode only.
  13. Revision History:
  14. Joe Notarangelo 21-April-1992
  15. very minor changes for ALPHA
  16. - system time to 64bit integer
  17. - some data moved out of pcr
  18. --*/
  19. #include "ki.h"
  20. //
  21. // Define forward referenced prototypes.
  22. //
  23. ULONG
  24. KiGetFeatureBits (
  25. VOID
  26. );
  27. __inline
  28. ULONG
  29. amask(
  30. IN ULONG Feature
  31. )
  32. {
  33. return(__asm("amask %0, v0",Feature));
  34. }
  35. #ifdef ALLOC_PRAGMA
  36. #pragma alloc_text(INIT, KiInitializeKernel)
  37. #endif
  38. VOID
  39. KiInitializeKernel (
  40. IN PKPROCESS Process,
  41. IN PKTHREAD Thread,
  42. IN PVOID IdleStack,
  43. IN PKPRCB Prcb,
  44. IN CCHAR Number,
  45. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  46. )
  47. /*++
  48. Routine Description:
  49. This function gains control after the system has been bootstrapped and
  50. before the system has been initialized. Its function is to initialize
  51. the kernel data structures, initialize the idle thread and process objects,
  52. initialize the processor control block, call the executive initialization
  53. routine, and then return to the system startup routine. This routine is
  54. also called to initialize the processor specific structures when a new
  55. processor is brought on line.
  56. Arguments:
  57. Process - Supplies a pointer to a control object of type process for
  58. the specified processor.
  59. Thread - Supplies a pointer to a dispatcher object of type thread for
  60. the specified processor.
  61. IdleStack - Supplies a pointer the base of the real kernel stack for
  62. idle thread on the specified processor.
  63. Prcb - Supplies a pointer to a processor control block for the specified
  64. processor.
  65. Number - Supplies the number of the processor that is being
  66. initialized.
  67. LoaderBlock - Supplies a pointer to the loader parameter block.
  68. Return Value:
  69. None.
  70. --*/
  71. {
  72. UCHAR DataByte;
  73. ULONG DataLong;
  74. LONG Index;
  75. KIRQL OldIrql;
  76. PKPCR Pcr = PCR;
  77. struct _RESTART_BLOCK *RestartBlock;
  78. //
  79. // Save the address of the loader parameter block.
  80. //
  81. KeLoaderBlock = LoaderBlock;
  82. //
  83. // Set the appropriate member in the active processors set.
  84. //
  85. SetMember(Number, KeActiveProcessors);
  86. //
  87. // Set the number of processors based on the maximum of the current
  88. // number of processors and the current processor number.
  89. //
  90. if ((Number + 1) > KeNumberProcessors) {
  91. KeNumberProcessors = Number + 1;
  92. }
  93. //
  94. // Set the maximum address space number to the minimum of all maximum
  95. // address space numbers passed via the loader block.
  96. //
  97. if (Number == 0) {
  98. KiMaximumAsn = LoaderBlock->u.Alpha.MaximumAddressSpaceNumber;
  99. } else if (KiMaximumAsn > LoaderBlock->u.Alpha.MaximumAddressSpaceNumber) {
  100. KiMaximumAsn = LoaderBlock->u.Alpha.MaximumAddressSpaceNumber;
  101. }
  102. //
  103. // Initialize the passive release, APC, and DPC interrupt vectors.
  104. //
  105. Pcr->InterruptRoutine[0] = KiPassiveRelease;
  106. Pcr->InterruptRoutine[APC_LEVEL] = KiApcInterrupt;
  107. Pcr->InterruptRoutine[DISPATCH_LEVEL] = KiDispatchInterrupt;
  108. Pcr->ReservedVectors =
  109. (1 << PASSIVE_LEVEL) | (1 << APC_LEVEL) | (1 << DISPATCH_LEVEL);
  110. //
  111. // Initialize the processor id fields in the PCR.
  112. //
  113. Pcr->Number = Number;
  114. Pcr->SetMember = 1 << Number;
  115. Pcr->NotMember = ~Pcr->SetMember;
  116. //
  117. // Initialize the processor block.
  118. //
  119. Prcb->MinorVersion = PRCB_MINOR_VERSION;
  120. Prcb->MajorVersion = PRCB_MAJOR_VERSION;
  121. Prcb->BuildType = 0;
  122. #if DBG
  123. Prcb->BuildType |= PRCB_BUILD_DEBUG;
  124. #endif
  125. #ifdef NT_UP
  126. Prcb->BuildType |= PRCB_BUILD_UNIPROCESSOR;
  127. #endif
  128. Prcb->CurrentThread = Thread;
  129. Prcb->NextThread = (PKTHREAD)NULL;
  130. Prcb->IdleThread = Thread;
  131. Prcb->Number = Number;
  132. Prcb->SetMember = 1 << Number;
  133. KeInitializeDpc(&Prcb->QuantumEndDpc,
  134. (PKDEFERRED_ROUTINE)KiQuantumEnd,
  135. NIL);
  136. //
  137. // initialize the per processor lock queue entry for implemented locks.
  138. //
  139. KiInitQueuedSpinLocks(Prcb, Number);
  140. //
  141. // Set address of PCR in PRCB.
  142. //
  143. Prcb->Pcr = Pcr;
  144. //
  145. // Initialize the interprocessor communication packet.
  146. //
  147. #if !defined(NT_UP)
  148. Prcb->TargetSet = 0;
  149. Prcb->WorkerRoutine = NULL;
  150. Prcb->RequestSummary = 0;
  151. Prcb->IpiFrozen = 0;
  152. #if NT_INST
  153. Prcb->IpiCounts = &KiIpiCounts[Number];
  154. #endif //NT_INST
  155. #endif //NT_UP
  156. Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
  157. Prcb->MinimumDpcRate = KiMinimumDpcRate;
  158. Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
  159. //
  160. // Initialize DPC listhead and lock.
  161. //
  162. InitializeListHead(&Prcb->DpcListHead);
  163. KeInitializeSpinLock(&Prcb->DpcLock);
  164. //
  165. // Set address of processor block.
  166. //
  167. KiProcessorBlock[Number] = Prcb;
  168. //
  169. // Set address of process object in thread object.
  170. //
  171. Thread->ApcState.Process = Process;
  172. //
  173. // Set the appropriate member in the active processors set.
  174. //
  175. SetMember( Number, KeActiveProcessors );
  176. //
  177. // Set the number of processors based on the maximum of the current
  178. // number of processors and the current processor number.
  179. //
  180. if( (Number+1) > KeNumberProcessors ){
  181. KeNumberProcessors = Number + 1;
  182. }
  183. //
  184. // Initialize processors PowerState
  185. //
  186. PoInitializePrcb (Prcb);
  187. //
  188. // Set global processor architecture, level and revision. The
  189. // latter two are the least common denominator on an MP system.
  190. //
  191. #ifdef _AXP64_
  192. KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_ALPHA64;
  193. #else
  194. KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_ALPHA;
  195. #endif
  196. if ((KeProcessorLevel == 0) ||
  197. (KeProcessorLevel > (USHORT)Pcr->ProcessorType)) {
  198. KeProcessorLevel = (USHORT)Pcr->ProcessorType;
  199. }
  200. if ((KeProcessorRevision == 0) ||
  201. (KeProcessorRevision > (USHORT)Pcr->ProcessorRevision)) {
  202. KeProcessorRevision = (USHORT)Pcr->ProcessorRevision;
  203. }
  204. //
  205. // Initialize all interrupt vectors to transfer control to the unexpected
  206. // interrupt routine.
  207. //
  208. // N.B. This interrupt object is never actually "connected" to an interrupt
  209. // vector via KeConnectInterrupt. It is initialized and then connected
  210. // by simply storing the address of the dispatch code in the interrupt
  211. // vector.
  212. //
  213. if (Number == 0) {
  214. //
  215. // Set default node. Used in non-multinode systems and in
  216. // multinode systems until the node topology is available.
  217. //
  218. extern KNODE KiNode0;
  219. KeNodeBlock[0] = &KiNode0;
  220. #if defined(KE_MULTINODE)
  221. for (Index = 1; Index < MAXIMUM_CCNUMA_NODES; Index++) {
  222. extern KNODE KiNodeInit[];
  223. //
  224. // Set temporary node.
  225. //
  226. KeNodeBlock[Index] = &KiNodeInit[Index];
  227. }
  228. #endif
  229. Prcb->ParentNode = KeNodeBlock[0];
  230. KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
  231. KeFeatureBits = KiGetFeatureBits();
  232. //
  233. // Initial the address of the interrupt dispatch routine.
  234. //
  235. KxUnexpectedInterrupt.DispatchAddress = KiUnexpectedInterrupt;
  236. //
  237. // Copy the interrupt dispatch code template into the interrupt object
  238. // and flush the dcache on all processors that the current thread can
  239. // run on to ensure that the code is actually in memory.
  240. //
  241. for (Index = 0; Index < DISPATCH_LENGTH; Index += 1) {
  242. KxUnexpectedInterrupt.DispatchCode[Index] = KiInterruptTemplate[Index];
  243. }
  244. //
  245. // Sweep the instruction cache on the current processor.
  246. //
  247. KiImb();
  248. } else {
  249. //
  250. // Mask off feature bits that are not supported on all processors.
  251. //
  252. KeFeatureBits &= KiGetFeatureBits();
  253. }
  254. //
  255. // Update processor features
  256. //
  257. SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] =
  258. (KeFeatureBits & KF_BYTE) ? TRUE : FALSE;
  259. for (Index = DISPATCH_LEVEL+1; Index < MAXIMUM_VECTOR; Index += 1) {
  260. Pcr->InterruptRoutine[Index] = (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode);
  261. }
  262. //
  263. // Raise IRQL to APC level.
  264. //
  265. KeRaiseIrql(APC_LEVEL, &OldIrql);
  266. //
  267. // If the initial processor is being initialized, then initialize the
  268. // per system data structures.
  269. //
  270. if (Number == 0) {
  271. //
  272. // Initialize the address of the restart block for the boot master.
  273. //
  274. Prcb->RestartBlock = SYSTEM_BLOCK->RestartBlock;
  275. //
  276. // Initialize the kernel debugger if enabled by the load options.
  277. //
  278. if (KdInitSystem(0, LoaderBlock, FALSE) == FALSE) {
  279. KeBugCheck(PHASE0_INITIALIZATION_FAILED);
  280. }
  281. //
  282. // Initialize processor block array.
  283. //
  284. for (Index = 1; Index < MAXIMUM_PROCESSORS; Index += 1) {
  285. KiProcessorBlock[Index] = (PKPRCB)NULL;
  286. }
  287. //
  288. // Initialize default DMA coherency value for Alpha.
  289. //
  290. KiDmaIoCoherency = DMA_READ_DCACHE_INVALIDATE | DMA_WRITE_DCACHE_SNOOP;
  291. //
  292. // Perform architecture independent initialization.
  293. //
  294. KiInitSystem();
  295. //
  296. // Initialize idle thread process object and then set:
  297. //
  298. // 1. all the quantum values to the maximum possible.
  299. // 2. the process in the balance set.
  300. // 3. the active processor mask to the specified processor.
  301. //
  302. KeInitializeProcess(Process,
  303. (KPRIORITY)0,
  304. (KAFFINITY)(0xffffffff),
  305. (PULONG_PTR)PDE_SELFMAP,
  306. FALSE);
  307. Process->ThreadQuantum = MAXCHAR;
  308. }
  309. //
  310. // Initialize idle thread object and then set:
  311. //
  312. // 1. the initial kernel stack to the specified idle stack.
  313. // 2. the next processor number to the specified processor.
  314. // 3. the thread priority to the highest possible value.
  315. // 4. the state of the thread to running.
  316. // 5. the thread affinity to the specified processor.
  317. // 6. the specified processor member in the process active processors
  318. // set.
  319. //
  320. KeInitializeThread(Thread,
  321. (PVOID)((ULONG_PTR)IdleStack - PAGE_SIZE),
  322. (PKSYSTEM_ROUTINE)NULL,
  323. (PKSTART_ROUTINE)NULL,
  324. (PVOID)NULL,
  325. (PCONTEXT)NULL,
  326. (PVOID)NULL,
  327. Process);
  328. Thread->InitialStack = IdleStack;
  329. Thread->StackBase = IdleStack;
  330. Thread->StackLimit = (PVOID)((ULONG_PTR)IdleStack - KERNEL_STACK_SIZE);
  331. Thread->NextProcessor = Number;
  332. Thread->Priority = HIGH_PRIORITY;
  333. Thread->State = Running;
  334. Thread->Affinity = (KAFFINITY)(1 << Number);
  335. Thread->WaitIrql = DISPATCH_LEVEL;
  336. //
  337. // If the current processor is the boot master then set the appropriate
  338. // bit in the active summary of the idle process.
  339. //
  340. if (Number == 0) {
  341. SetMember(Number, Process->ActiveProcessors);
  342. }
  343. //
  344. // call the executive initialization routine.
  345. //
  346. try {
  347. ExpInitializeExecutive(Number, LoaderBlock);
  348. } except(KeBugCheckEx(PHASE0_EXCEPTION,
  349. (ULONG)GetExceptionCode(),
  350. (ULONG_PTR)GetExceptionInformation(),
  351. 0,0), EXCEPTION_EXECUTE_HANDLER) {
  352. ; // should never get here
  353. }
  354. //
  355. // If the initial processor is being initialized, then compute the
  356. // timer table reciprocal value and reset the PRCB values for
  357. // the controllable DPC behavior in order to reflect any registry
  358. // overrides.
  359. //
  360. if (Number == 0) {
  361. KiTimeIncrementReciprocal = KiComputeReciprocal((LONG)KeMaximumIncrement,
  362. &KiTimeIncrementShiftCount);
  363. Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
  364. Prcb->MinimumDpcRate = KiMinimumDpcRate;
  365. Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
  366. }
  367. //
  368. // Try to enable automatic PAL code fixups on this processor.
  369. // This must be done after the configuration values are read
  370. // out of the registry in ExpInitializeExecutive.
  371. //
  372. #if !defined(_AXP64_)
  373. //
  374. // Don't let the PAL fix up alignment exceptions for axp64, so that we can catch
  375. // and fix them as they occur.
  376. //
  377. KiDisableAlignmentExceptions();
  378. #endif
  379. //
  380. //
  381. // Raise IRQL to dispatch level and set the priority of the idle thread
  382. // to zero. This will have the effect of immediately causing the phase
  383. // one initialization thread to get scheduled for execution. The idle
  384. // thread priority is then set to the lowest realtime priority.
  385. //
  386. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  387. KeSetPriorityThread(Thread, (KPRIORITY)0);
  388. Thread->Priority = LOW_REALTIME_PRIORITY;
  389. //
  390. // Raise IRQL to the highest level.
  391. //
  392. KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  393. //
  394. // If a restart block exists for the current processor then set boot
  395. // completed.
  396. //
  397. #if !defined(NT_UP)
  398. RestartBlock = Prcb->RestartBlock;
  399. if (RestartBlock != NULL) {
  400. RestartBlock->BootStatus.BootFinished = 1;
  401. }
  402. //
  403. // If the current processor is a secondary processor and a thread has
  404. // not been selected for execution, then set the appropriate bit in the
  405. // idle summary.
  406. //
  407. if ((Number != 0) && (Prcb->NextThread == NULL)) {
  408. SetMember(Number, KiIdleSummary);
  409. }
  410. #endif //NT_UP
  411. return;
  412. }
  413. ULONG
  414. KiGetFeatureBits(
  415. VOID
  416. )
  417. /*++
  418. Return the NT feature bits supported by this processors
  419. --*/
  420. {
  421. ULONG Features = 0;
  422. //
  423. // Check for byte instructions.
  424. //
  425. if (amask(1) == 0) {
  426. Features |= KF_BYTE;
  427. }
  428. return Features;
  429. }
  430. #if defined(_AXP64_)
  431. VOID
  432. KiStartHalThread (
  433. IN PKTHREAD Thread,
  434. IN PVOID Stack,
  435. IN PKSTART_ROUTINE StartRoutine,
  436. IN ULONG_PTR Process
  437. )
  438. /*++
  439. Routine Description:
  440. This function is called to initialize and start a thread from the
  441. HAL to emulate BIOS calls.
  442. Arguments:
  443. Thread - Supplies a pointer to a dispatcher object of type thread.
  444. Stack - Supplies a pointer the base of the real kernel stack for
  445. thread.
  446. StartRoutine - Supplies the address of the start routine.
  447. Return Value:
  448. None.
  449. --*/
  450. {
  451. //
  452. // Initialize the specified thread object.
  453. //
  454. KeInitializeThread(Thread,
  455. Stack,
  456. (PKSYSTEM_ROUTINE)StartRoutine,
  457. NULL,
  458. NULL,
  459. NULL,
  460. NULL,
  461. (PKPROCESS)Process);
  462. //
  463. // Set thread priority.
  464. //
  465. Thread->Priority = (KPRIORITY) NORMAL_BASE_PRIORITY - 1;
  466. KeReadyThread(Thread);
  467. return;
  468. }
  469. #endif