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.

1417 lines
34 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. allproc.c
  5. Abstract:
  6. This module allocates and initializes kernel resources required
  7. to start a new processor, and passes a complete process_state
  8. structre to the hal to obtain a new processor. This is done
  9. for every processor.
  10. Author:
  11. Ken Reneris (kenr) 22-Jan-92
  12. Environment:
  13. Kernel mode only.
  14. Phase 1 of bootup
  15. Revision History:
  16. --*/
  17. #include "ki.h"
  18. #include "pool.h"
  19. //
  20. // KiSMTProcessorsPresent is used to indicate whether or not any SMT
  21. // processors have been started. This is used to determine whether to
  22. // check for processor licensing before or after starting the
  23. // processor and to trigger additional work after processor startup if
  24. // SMT processors are present.
  25. //
  26. BOOLEAN KiSMTProcessorsPresent;
  27. //
  28. // KiUnlicensedProcessorPresent is used so that the processor feature
  29. // enable code is aware that there are logical processors present that
  30. // have a state dependency on the processor features that were enabled
  31. // when it was put into a holding state because we couldn't license
  32. // the processor.
  33. //
  34. BOOLEAN KiUnlicensedProcessorPresent;
  35. #ifdef NT_UP
  36. VOID
  37. KeStartAllProcessors (
  38. VOID
  39. )
  40. {
  41. // UP Build - this function is a nop
  42. }
  43. #else
  44. static VOID
  45. KiCloneDescriptor (
  46. IN PKDESCRIPTOR pSrcDescriptorInfo,
  47. IN PKDESCRIPTOR pDestDescriptorInfo,
  48. IN PVOID Base
  49. );
  50. static VOID
  51. KiCloneSelector (
  52. IN ULONG SrcSelector,
  53. IN PKGDTENTRY pNGDT,
  54. IN PKDESCRIPTOR pDestDescriptor,
  55. IN PVOID Base
  56. );
  57. VOID
  58. KiAdjustSimultaneousMultiThreadingCharacteristics(
  59. VOID
  60. );
  61. VOID
  62. KiProcessorStart(
  63. VOID
  64. );
  65. BOOLEAN
  66. KiStartWaitAcknowledge(
  67. VOID
  68. );
  69. VOID
  70. KiSetHaltedNmiandDoubleFaultHandler(
  71. VOID
  72. );
  73. VOID
  74. KiDummyNmiHandler (
  75. VOID
  76. );
  77. VOID
  78. KiDummyDoubleFaultHandler(
  79. VOID
  80. );
  81. VOID
  82. KiClearBusyBitInTssDescriptor(
  83. IN ULONG DescriptorOffset
  84. );
  85. VOID
  86. KiHaltThisProcessor(
  87. VOID
  88. ) ;
  89. #if defined(KE_MULTINODE)
  90. NTSTATUS
  91. KiNotNumaQueryProcessorNode(
  92. IN ULONG ProcessorNumber,
  93. OUT PUSHORT Identifier,
  94. OUT PUCHAR Node
  95. );
  96. #ifdef ALLOC_PRAGMA
  97. #pragma alloc_text(INIT, KiNotNumaQueryProcessorNode)
  98. #endif
  99. #endif
  100. #ifdef ALLOC_PRAGMA
  101. #pragma alloc_text(INIT,KeStartAllProcessors)
  102. #pragma alloc_text(INIT,KiCloneDescriptor)
  103. #pragma alloc_text(INIT,KiCloneSelector)
  104. #pragma alloc_text(INIT,KiAllProcessorsStarted)
  105. #pragma alloc_text(INIT,KiAdjustSimultaneousMultiThreadingCharacteristics)
  106. #pragma alloc_text(INIT,KiStartWaitAcknowledge)
  107. #endif
  108. enum {
  109. KcStartContinue,
  110. KcStartWait,
  111. KcStartGetId,
  112. KcStartDoNotStart,
  113. KcStartCommandError = 0xff
  114. } KiProcessorStartControl = KcStartContinue;
  115. ULONG KiProcessorStartData[4];
  116. ULONG KiBarrierWait = 0;
  117. //
  118. // KeNumprocSpecified is set to the number of processors specified with
  119. // /NUMPROC in OSLOADOPTIONS. This will bypass the license increase for
  120. // logical processors limiting the total number of processors to the number
  121. // specified.
  122. //
  123. ULONG KeNumprocSpecified;
  124. #if defined(KE_MULTINODE)
  125. PHALNUMAQUERYPROCESSORNODE KiQueryProcessorNode = KiNotNumaQueryProcessorNode;
  126. //
  127. // Statically preallocate enough KNODE structures to allow MM
  128. // to allocate pages by node during system initialization. As
  129. // processors are brought online, real KNODE structures are
  130. // allocated in the appropriate memory for the node.
  131. //
  132. // This statically allocated set will be deallocated once the
  133. // system is initialized.
  134. //
  135. #ifdef ALLOC_DATA_PRAGMA
  136. #pragma data_seg("INITDATA")
  137. #endif
  138. KNODE KiNodeInit[MAXIMUM_CCNUMA_NODES];
  139. #ifdef ALLOC_DATA_PRAGMA
  140. #pragma data_seg()
  141. #endif
  142. #endif
  143. #define ROUNDUP16(x) (((x)+15) & ~15)
  144. VOID
  145. KeStartAllProcessors (
  146. VOID
  147. )
  148. /*++
  149. Routine Description:
  150. Called by p0 during phase 1 of bootup. This function implements
  151. the x86 specific code to contact the hal for each system processor.
  152. Arguments:
  153. Return Value:
  154. All available processors are sent to KiSystemStartup.
  155. --*/
  156. {
  157. KPROCESSOR_STATE ProcessorState;
  158. KDESCRIPTOR Descriptor;
  159. KDESCRIPTOR TSSDesc, DFTSSDesc, NMITSSDesc, PCRDesc;
  160. PKGDTENTRY pGDT;
  161. PVOID pStack;
  162. PVOID pDpcStack;
  163. PUCHAR pThreadObject;
  164. PULONG pTopOfStack;
  165. ULONG NewProcessorNumber;
  166. BOOLEAN NewProcessor;
  167. PKTSS pTSS;
  168. SIZE_T ProcessorDataSize;
  169. UCHAR NodeNumber = 0;
  170. PVOID PerProcessorAllocation;
  171. PUCHAR Base;
  172. ULONG IdtOffset;
  173. ULONG GdtOffset;
  174. BOOLEAN NewLicense;
  175. PKPRCB NewPrcb;
  176. #if defined(KE_MULTINODE)
  177. USHORT ProcessorId;
  178. PKNODE Node;
  179. NTSTATUS Status;
  180. #endif
  181. //
  182. // Do not start additional processors if the RELOCATEPHYSICAL loader
  183. // switch has been specified.
  184. //
  185. if (KeLoaderBlock->LoadOptions != NULL) {
  186. if (strstr(KeLoaderBlock->LoadOptions, "RELOCATEPHYSICAL") != NULL) {
  187. return;
  188. }
  189. }
  190. //
  191. // If the boot processor has PII spec A27 errata (also present in
  192. // early Pentium Pro chips), then use only one processor to avoid
  193. // unpredictable eflags corruption.
  194. //
  195. // Note this only affects some (but not all) chips @ 333Mhz and below.
  196. //
  197. if (!(KeFeatureBits & KF_WORKING_PTE)) {
  198. return;
  199. }
  200. #if defined(KE_MULTINODE)
  201. //
  202. // In the unlikely event that processor 0 is not on node
  203. // 0, fix it.
  204. //
  205. if (KeNumberNodes > 1) {
  206. Status = KiQueryProcessorNode(0,
  207. &ProcessorId,
  208. &NodeNumber);
  209. if (NT_SUCCESS(Status)) {
  210. //
  211. // Adjust the data structures to reflect that P0 is not on Node 0.
  212. //
  213. if (NodeNumber != 0) {
  214. ASSERT(KeNodeBlock[0] == &KiNode0);
  215. KeNodeBlock[0]->ProcessorMask &= ~1;
  216. KiNodeInit[0] = *KeNodeBlock[0];
  217. KeNodeBlock[0] = &KiNodeInit[0];
  218. KiNode0 = *KeNodeBlock[NodeNumber];
  219. KeNodeBlock[NodeNumber] = &KiNode0;
  220. KeNodeBlock[NodeNumber]->ProcessorMask |= 1;
  221. }
  222. }
  223. }
  224. #endif
  225. //
  226. // Calculate the size of the per processor data. This includes
  227. // PCR (+PRCB)
  228. // TSS
  229. // Idle Thread Object
  230. // NMI TSS
  231. // Double Fault TSS
  232. // Double Fault Stack
  233. // GDT
  234. // IDT
  235. //
  236. // If this is a multinode system, the KNODE structure is allocated
  237. // as well. It isn't very big so we waste a few bytes for
  238. // processors that aren't the first in a node.
  239. //
  240. // A DPC and Idle stack are also allocated but these are done
  241. // seperately.
  242. //
  243. ProcessorDataSize = ROUNDUP16(sizeof(KPCR)) +
  244. ROUNDUP16(sizeof(KTSS)) +
  245. ROUNDUP16(sizeof(ETHREAD)) +
  246. ROUNDUP16(FIELD_OFFSET(KTSS, IoMaps)) +
  247. ROUNDUP16(FIELD_OFFSET(KTSS, IoMaps)) +
  248. ROUNDUP16(DOUBLE_FAULT_STACK_SIZE);
  249. #if defined(KE_MULTINODE)
  250. ProcessorDataSize += ROUNDUP16(sizeof(KNODE));
  251. #endif
  252. //
  253. // Add sizeof GDT
  254. //
  255. GdtOffset = ProcessorDataSize;
  256. _asm {
  257. sgdt Descriptor.Limit
  258. }
  259. ProcessorDataSize += Descriptor.Limit + 1;
  260. //
  261. // Add sizeof IDT
  262. //
  263. IdtOffset = ProcessorDataSize;
  264. _asm {
  265. sidt Descriptor.Limit
  266. }
  267. ProcessorDataSize += Descriptor.Limit + 1;
  268. //
  269. // If the registered number of processors is greater than the maximum
  270. // number of processors supported, then only allow the maximum number
  271. // of supported processors.
  272. //
  273. if (KeRegisteredProcessors > MAXIMUM_PROCESSORS) {
  274. KeRegisteredProcessors = MAXIMUM_PROCESSORS;
  275. }
  276. //
  277. // Set barrier that will prevent any other processor from entering the
  278. // idle loop until all processors have been started.
  279. //
  280. KiBarrierWait = 1;
  281. //
  282. // Loop asking the HAL for the next processor. Stop when the
  283. // HAL says there aren't any more.
  284. //
  285. for (NewProcessorNumber = 1;
  286. NewProcessorNumber < MAXIMUM_PROCESSORS;
  287. NewProcessorNumber++) {
  288. if (!KiSMTProcessorsPresent) {
  289. //
  290. // If some of the processors in the system support Simultaneous
  291. // Multi-Threading we allow the additional logical processors
  292. // in a set to run under the same license as the first logical
  293. // processor in a set.
  294. //
  295. // Otherwise, do not attempt to start more processors than
  296. // there are licenses for. (This is because as of Whistler
  297. // Beta2 we are having problems with systems that send SMIs
  298. // to processors that are not in "wait for SIPI" state. The
  299. // code to scan for additional logical processors causes
  300. // processors not licensed to be in a halted state).
  301. //
  302. // PeterJ 03/02/01.
  303. //
  304. if (NewProcessorNumber >= KeRegisteredProcessors) {
  305. break;
  306. }
  307. }
  308. RetryStartProcessor:
  309. #if defined(KE_MULTINODE)
  310. Status = KiQueryProcessorNode(NewProcessorNumber,
  311. &ProcessorId,
  312. &NodeNumber);
  313. if (!NT_SUCCESS(Status)) {
  314. //
  315. // No such processor, advance to next.
  316. //
  317. continue;
  318. }
  319. Node = KeNodeBlock[NodeNumber];
  320. #endif
  321. //
  322. // Allocate memory for the new processor specific data. If
  323. // the allocation fails, stop starting processors.
  324. //
  325. PerProcessorAllocation =
  326. MmAllocateIndependentPages (ProcessorDataSize, NodeNumber);
  327. if (PerProcessorAllocation == NULL) {
  328. break;
  329. }
  330. //
  331. // Allocate a pool tag table for the new processor.
  332. //
  333. if (ExCreatePoolTagTable (NewProcessorNumber, NodeNumber) == NULL) {
  334. MmFreeIndependentPages ( PerProcessorAllocation, ProcessorDataSize);
  335. break;
  336. }
  337. Base = (PUCHAR)PerProcessorAllocation;
  338. //
  339. // Build up a processor state for new processor.
  340. //
  341. RtlZeroMemory ((PVOID) &ProcessorState, sizeof ProcessorState);
  342. //
  343. // Give the new processor its own GDT.
  344. //
  345. _asm {
  346. sgdt Descriptor.Limit
  347. }
  348. KiCloneDescriptor (&Descriptor,
  349. &ProcessorState.SpecialRegisters.Gdtr,
  350. Base + GdtOffset);
  351. pGDT = (PKGDTENTRY) ProcessorState.SpecialRegisters.Gdtr.Base;
  352. //
  353. // Give new processor its own IDT.
  354. //
  355. _asm {
  356. sidt Descriptor.Limit
  357. }
  358. KiCloneDescriptor (&Descriptor,
  359. &ProcessorState.SpecialRegisters.Idtr,
  360. Base + IdtOffset);
  361. //
  362. // Give new processor its own TSS and PCR.
  363. //
  364. KiCloneSelector (KGDT_R0_PCR, pGDT, &PCRDesc, Base);
  365. RtlZeroMemory (Base, ROUNDUP16(sizeof(KPCR)));
  366. Base += ROUNDUP16(sizeof(KPCR));
  367. KiCloneSelector (KGDT_TSS, pGDT, &TSSDesc, Base);
  368. Base += ROUNDUP16(sizeof(KTSS));
  369. //
  370. // Idle Thread thread object.
  371. //
  372. pThreadObject = Base;
  373. RtlZeroMemory(Base, sizeof(ETHREAD));
  374. Base += ROUNDUP16(sizeof(ETHREAD));
  375. //
  376. // NMI TSS and double-fault TSS & stack.
  377. //
  378. KiCloneSelector (KGDT_DF_TSS, pGDT, &DFTSSDesc, Base);
  379. Base += ROUNDUP16(FIELD_OFFSET(KTSS, IoMaps));
  380. KiCloneSelector (KGDT_NMI_TSS, pGDT, &NMITSSDesc, Base);
  381. Base += ROUNDUP16(FIELD_OFFSET(KTSS, IoMaps));
  382. Base += DOUBLE_FAULT_STACK_SIZE;
  383. pTSS = (PKTSS)DFTSSDesc.Base;
  384. pTSS->Esp0 = (ULONG)Base;
  385. pTSS->Esp = (ULONG)Base;
  386. pTSS = (PKTSS)NMITSSDesc.Base;
  387. pTSS->Esp0 = (ULONG)Base;
  388. pTSS->Esp = (ULONG)Base;
  389. //
  390. // Set other SpecialRegisters in processor state.
  391. //
  392. _asm {
  393. mov eax, cr0
  394. and eax, NOT (CR0_AM or CR0_WP)
  395. mov ProcessorState.SpecialRegisters.Cr0, eax
  396. mov eax, cr3
  397. mov ProcessorState.SpecialRegisters.Cr3, eax
  398. pushfd
  399. pop eax
  400. mov ProcessorState.ContextFrame.EFlags, eax
  401. and ProcessorState.ContextFrame.EFlags, NOT EFLAGS_INTERRUPT_MASK
  402. }
  403. ProcessorState.SpecialRegisters.Tr = KGDT_TSS;
  404. pGDT[KGDT_TSS>>3].HighWord.Bytes.Flags1 = 0x89;
  405. #if defined(_X86PAE_)
  406. ProcessorState.SpecialRegisters.Cr4 = CR4_PAE;
  407. #endif
  408. //
  409. // Allocate a DPC stack, idle thread stack and ThreadObject for
  410. // the new processor.
  411. //
  412. pStack = MmCreateKernelStack (FALSE, NodeNumber);
  413. pDpcStack = MmCreateKernelStack (FALSE, NodeNumber);
  414. //
  415. // Setup context - push variables onto new stack.
  416. //
  417. pTopOfStack = (PULONG) pStack;
  418. pTopOfStack[-1] = (ULONG) KeLoaderBlock;
  419. ProcessorState.ContextFrame.Esp = (ULONG) (pTopOfStack-2);
  420. ProcessorState.ContextFrame.Eip = (ULONG) KiSystemStartup;
  421. ProcessorState.ContextFrame.SegCs = KGDT_R0_CODE;
  422. ProcessorState.ContextFrame.SegDs = KGDT_R3_DATA;
  423. ProcessorState.ContextFrame.SegEs = KGDT_R3_DATA;
  424. ProcessorState.ContextFrame.SegFs = KGDT_R0_PCR;
  425. ProcessorState.ContextFrame.SegSs = KGDT_R0_DATA;
  426. //
  427. // Initialize new processor's PCR & Prcb.
  428. //
  429. KiInitializePcr (
  430. (ULONG) NewProcessorNumber,
  431. (PKPCR) PCRDesc.Base,
  432. (PKIDTENTRY) ProcessorState.SpecialRegisters.Idtr.Base,
  433. (PKGDTENTRY) ProcessorState.SpecialRegisters.Gdtr.Base,
  434. (PKTSS) TSSDesc.Base,
  435. (PKTHREAD) pThreadObject,
  436. (PVOID) pDpcStack
  437. );
  438. NewPrcb = ((PKPCR)(PCRDesc.Base))->Prcb;
  439. //
  440. // Assume new processor will be the first processor in its
  441. // SMT set. (Right choice for non SMT processors, adjusted
  442. // later if not correct).
  443. //
  444. NewPrcb->MultiThreadSetMaster = NewPrcb;
  445. #if defined(KE_MULTINODE)
  446. //
  447. // If this is the first processor on this node, use the
  448. // space allocated for KNODE as the KNODE.
  449. //
  450. if (KeNodeBlock[NodeNumber] == &KiNodeInit[NodeNumber]) {
  451. Node = (PKNODE)Base;
  452. *Node = KiNodeInit[NodeNumber];
  453. KeNodeBlock[NodeNumber] = Node;
  454. }
  455. Base += ROUNDUP16(sizeof(KNODE));
  456. NewPrcb->ParentNode = Node;
  457. #else
  458. NewPrcb->ParentNode = KeNodeBlock[0];
  459. #endif
  460. ASSERT(((PUCHAR)PerProcessorAllocation + GdtOffset) == Base);
  461. //
  462. // Adjust LoaderBlock so it has the next processors state
  463. //
  464. KeLoaderBlock->KernelStack = (ULONG) pTopOfStack;
  465. KeLoaderBlock->Thread = (ULONG) pThreadObject;
  466. KeLoaderBlock->Prcb = (ULONG) NewPrcb;
  467. //
  468. // Get CPUID(1) info from the starting processor.
  469. //
  470. KiProcessorStartData[0] = 1;
  471. KiProcessorStartControl = KcStartGetId;
  472. //
  473. // Contact hal to start new processor.
  474. //
  475. NewProcessor = HalStartNextProcessor (KeLoaderBlock, &ProcessorState);
  476. if (!NewProcessor) {
  477. //
  478. // There wasn't another processor, so free resources and break.
  479. //
  480. KiProcessorBlock[NewProcessorNumber] = NULL;
  481. ExDeletePoolTagTable (NewProcessorNumber);
  482. MmFreeIndependentPages ( PerProcessorAllocation, ProcessorDataSize);
  483. MmDeleteKernelStack ( pStack, FALSE);
  484. MmDeleteKernelStack ( pDpcStack, FALSE);
  485. break;
  486. }
  487. //
  488. // Wait for the new processor to fill in the CPUID data requested.
  489. //
  490. NewLicense = TRUE;
  491. if (KiStartWaitAcknowledge() == TRUE) {
  492. if (KiProcessorStartData[3] & 0x10000000) {
  493. //
  494. // This processor might support SMT, in which case, if this
  495. // is not the first logical processor in an SMT set, it should
  496. // not be charged a license. If it is the first in a set,
  497. // and the total number of sets exceeds the number of licensed
  498. // processors, this processor should not be allowed to start.
  499. //
  500. ULONG ApicMask;
  501. ULONG ApicId;
  502. ULONG i;
  503. PKPRCB SmtCheckPrcb;
  504. UCHAR LogicalProcessors;
  505. //
  506. // Retrieve logical processor count.
  507. //
  508. LogicalProcessors = (UCHAR) (KiProcessorStartData[1] >> 16);
  509. //
  510. // If this physical processor supports greater than 1
  511. // logical processors (threads), then it supports SMT
  512. // and should only be charged a license if it
  513. // represents a new physical processor.
  514. //
  515. if (LogicalProcessors > 1) {
  516. //
  517. // Round number of logical processors per physical processor
  518. // up to a power of two then subtract 1 to get the logical
  519. // processor apic mask.
  520. //
  521. ApicMask = LogicalProcessors + LogicalProcessors - 1;
  522. KeFindFirstSetLeftMember(ApicMask, &ApicMask);
  523. ApicMask = ~((1 << ApicMask) - 1);
  524. ApicId = (KiProcessorStartData[1] >> 24) & ApicMask;
  525. //
  526. // Check to see if any started processor is in the same set.
  527. //
  528. for (i = 0; i < NewProcessorNumber; i++) {
  529. SmtCheckPrcb = KiProcessorBlock[i];
  530. if (SmtCheckPrcb) {
  531. if ((SmtCheckPrcb->InitialApicId & ApicMask) == ApicId) {
  532. NewLicense = FALSE;
  533. NewPrcb->MultiThreadSetMaster = SmtCheckPrcb;
  534. break;
  535. }
  536. }
  537. }
  538. }
  539. }
  540. }
  541. if ((NewLicense == FALSE) &&
  542. ((KeNumprocSpecified == 0) ||
  543. (KeRegisteredProcessors < KeNumprocSpecified))) {
  544. //
  545. // This processor is a logical processor in the same SMT
  546. // set as another logical processor. Don't charge a
  547. // license for it.
  548. //
  549. KeRegisteredProcessors++;
  550. } else {
  551. //
  552. // The new processor is the first or only logical processor
  553. // in a physical processor. If the number of physical
  554. // processors exceeds the license, don't start this processor.
  555. //
  556. if ((ULONG)KeNumberProcessors >= KeRegisteredProcessors) {
  557. KiProcessorStartControl = KcStartDoNotStart;
  558. KiStartWaitAcknowledge();
  559. //
  560. // Free resources not being used by processor we
  561. // weren't able to license.
  562. //
  563. KiProcessorBlock[NewProcessorNumber] = NULL;
  564. MmDeleteKernelStack ( pDpcStack, FALSE);
  565. ExDeletePoolTagTable (NewProcessorNumber);
  566. //
  567. // The new processor has been put into a HLT loop with
  568. // interrupts disabled and handlers for NMI/double
  569. // faults. Because this processor is dependent on
  570. // page table state as it exists now, avoid turning on
  571. // large page support later.
  572. //
  573. KiUnlicensedProcessorPresent = TRUE;
  574. //
  575. // Ask the HAL to start the next processor but without
  576. // advancing the processor number.
  577. //
  578. goto RetryStartProcessor;
  579. }
  580. }
  581. KiProcessorStartControl = KcStartContinue;
  582. #if defined(KE_MULTINODE)
  583. Node->ProcessorMask |= 1 << NewProcessorNumber;
  584. #endif
  585. //
  586. // Wait for processor to initialize in kernel, then loop for another.
  587. //
  588. while (*((volatile ULONG *) &KeLoaderBlock->Prcb) != 0) {
  589. KeYieldProcessor();
  590. }
  591. }
  592. //
  593. // All processors have been started.
  594. //
  595. KiAllProcessorsStarted();
  596. //
  597. // Reset and synchronize the performance counters of all processors, by
  598. // applying a null adjustment to the interrupt time.
  599. //
  600. KeAdjustInterruptTime (0);
  601. //
  602. // Allow all processors that were started to enter the idle loop and
  603. // begin execution.
  604. //
  605. KiBarrierWait = 0;
  606. }
  607. static VOID
  608. KiCloneSelector (
  609. IN ULONG SrcSelector,
  610. IN PKGDTENTRY pNGDT,
  611. IN PKDESCRIPTOR pDestDescriptor,
  612. IN PVOID Base
  613. )
  614. /*++
  615. Routine Description:
  616. Makes a copy of the current selector's data, and updates the new
  617. GDT's linear address to point to the new copy.
  618. Arguments:
  619. SrcSelector - Selector value to clone
  620. pNGDT - New gdt table which is being built
  621. DescDescriptor - descriptor structure to fill in with resulting memory
  622. Base - Base memory for the new descriptor.
  623. Return Value:
  624. None.
  625. --*/
  626. {
  627. KDESCRIPTOR Descriptor;
  628. PKGDTENTRY pGDT;
  629. ULONG CurrentBase;
  630. ULONG NewBase;
  631. ULONG Limit;
  632. _asm {
  633. sgdt fword ptr [Descriptor.Limit] ; Get GDT's addr
  634. }
  635. pGDT = (PKGDTENTRY) Descriptor.Base;
  636. pGDT += SrcSelector >> 3;
  637. pNGDT += SrcSelector >> 3;
  638. CurrentBase = pGDT->BaseLow | (pGDT->HighWord.Bits.BaseMid << 16) |
  639. (pGDT->HighWord.Bits.BaseHi << 24);
  640. Descriptor.Base = CurrentBase;
  641. Descriptor.Limit = pGDT->LimitLow;
  642. if (pGDT->HighWord.Bits.Granularity & GRAN_PAGE) {
  643. Limit = (Descriptor.Limit << PAGE_SHIFT) - 1;
  644. Descriptor.Limit = (USHORT) Limit;
  645. ASSERT (Descriptor.Limit == Limit);
  646. }
  647. KiCloneDescriptor (&Descriptor, pDestDescriptor, Base);
  648. NewBase = pDestDescriptor->Base;
  649. pNGDT->BaseLow = (USHORT) NewBase & 0xffff;
  650. pNGDT->HighWord.Bits.BaseMid = (UCHAR) (NewBase >> 16) & 0xff;
  651. pNGDT->HighWord.Bits.BaseHi = (UCHAR) (NewBase >> 24) & 0xff;
  652. }
  653. static VOID
  654. KiCloneDescriptor (
  655. IN PKDESCRIPTOR pSrcDescriptor,
  656. IN PKDESCRIPTOR pDestDescriptor,
  657. IN PVOID Base
  658. )
  659. /*++
  660. Routine Description:
  661. Makes a copy of the specified descriptor, and supplies a return
  662. descriptor for the new copy
  663. Arguments:
  664. pSrcDescriptor - descriptor to clone
  665. pDescDescriptor - the cloned descriptor
  666. Base - Base memory for the new descriptor.
  667. Return Value:
  668. None.
  669. --*/
  670. {
  671. ULONG Size;
  672. Size = pSrcDescriptor->Limit + 1;
  673. pDestDescriptor->Limit = (USHORT) Size -1;
  674. pDestDescriptor->Base = (ULONG) Base;
  675. RtlCopyMemory(Base, (PVOID)pSrcDescriptor->Base, Size);
  676. }
  677. VOID
  678. KiAdjustSimultaneousMultiThreadingCharacteristics(
  679. VOID
  680. )
  681. /*++
  682. Routine Description:
  683. This routine is called (possibly while the dispatcher lock is held)
  684. after processors are added to or removed from the system. It runs
  685. thru the PRCBs for each processor in the system and adjusts scheduling
  686. data.
  687. Arguments:
  688. None.
  689. Return Value:
  690. None.
  691. --*/
  692. {
  693. ULONG ProcessorNumber;
  694. ULONG BuddyNumber;
  695. KAFFINITY ProcessorSet;
  696. PKPRCB Prcb;
  697. PKPRCB BuddyPrcb;
  698. ULONG ApicMask;
  699. ULONG ApicId;
  700. if (!KiSMTProcessorsPresent) {
  701. //
  702. // Nobody doing SMT, nothing to do.
  703. //
  704. return;
  705. }
  706. for (ProcessorNumber = 0;
  707. ProcessorNumber < (ULONG)KeNumberProcessors;
  708. ProcessorNumber++) {
  709. Prcb = KiProcessorBlock[ProcessorNumber];
  710. //
  711. // Skip processors which are not present or which do not
  712. // support Simultaneous Multi Threading.
  713. //
  714. if ((Prcb == NULL) ||
  715. (Prcb->LogicalProcessorsPerPhysicalProcessor == 1)) {
  716. continue;
  717. }
  718. //
  719. // Find all processors with the same physical processor APIC ID.
  720. // The APIC ID for the physical processor is the upper portion
  721. // of the APIC ID, the number of bits in the lower portion is
  722. // log 2 (number logical processors per physical rounded up to
  723. // a power of 2).
  724. //
  725. ApicId = Prcb->InitialApicId;
  726. //
  727. // Round number of logical processors up to a power of 2
  728. // then subtract one to get the logical processor apic mask.
  729. //
  730. ASSERT(Prcb->LogicalProcessorsPerPhysicalProcessor);
  731. ApicMask = Prcb->LogicalProcessorsPerPhysicalProcessor;
  732. ApicMask = ApicMask + ApicMask - 1;
  733. KeFindFirstSetLeftMember(ApicMask, &ApicMask);
  734. ApicMask = ~((1 << ApicMask) - 1);
  735. ApicId &= ApicMask;
  736. ProcessorSet = 1 << Prcb->Number;
  737. //
  738. // Examine each remaining processor to see if it is part of
  739. // the same set.
  740. //
  741. for (BuddyNumber = ProcessorNumber + 1;
  742. BuddyNumber < (ULONG)KeNumberProcessors;
  743. BuddyNumber++) {
  744. BuddyPrcb = KiProcessorBlock[BuddyNumber];
  745. //
  746. // Skip not present, not SMT.
  747. //
  748. if ((BuddyPrcb == NULL) ||
  749. (BuddyPrcb->LogicalProcessorsPerPhysicalProcessor == 1)) {
  750. continue;
  751. }
  752. //
  753. // Does this processor have the same ID as the one
  754. // we're looking for?
  755. //
  756. if ((BuddyPrcb->InitialApicId & ApicMask) != ApicId) {
  757. continue;
  758. }
  759. //
  760. // Match.
  761. //
  762. ASSERT(Prcb->LogicalProcessorsPerPhysicalProcessor ==
  763. BuddyPrcb->LogicalProcessorsPerPhysicalProcessor);
  764. ProcessorSet |= 1 << BuddyPrcb->Number;
  765. BuddyPrcb->MultiThreadProcessorSet |= ProcessorSet;
  766. }
  767. Prcb->MultiThreadProcessorSet |= ProcessorSet;
  768. }
  769. }
  770. VOID
  771. KiAllProcessorsStarted(
  772. VOID
  773. )
  774. /*++
  775. Routine Description:
  776. This routine is called once all processors in the system
  777. have been started.
  778. Arguments:
  779. None.
  780. Return Value:
  781. None.
  782. --*/
  783. {
  784. #if defined(KE_MULTINODE)
  785. ULONG i;
  786. #endif
  787. //
  788. // If the system contains Simultaneous Multi Threaded processors,
  789. // adjust grouping information now that each processor is started.
  790. //
  791. KiAdjustSimultaneousMultiThreadingCharacteristics();
  792. #if defined(KE_MULTINODE)
  793. //
  794. // Make sure there are no references to the temporary nodes
  795. // used during initialization.
  796. //
  797. for (i = 0; i < KeNumberNodes; i++) {
  798. if (KeNodeBlock[i] == &KiNodeInit[i]) {
  799. //
  800. // No processor started on this node so no new node
  801. // structure has been allocated. This is possible
  802. // if the node contains only memory or IO busses. At
  803. // this time we need to allocate a permanent node
  804. // structure for the node.
  805. //
  806. KeNodeBlock[i] = ExAllocatePoolWithTag(NonPagedPool,
  807. sizeof(KNODE),
  808. ' eK');
  809. if (KeNodeBlock[i]) {
  810. *KeNodeBlock[i] = KiNodeInit[i];
  811. }
  812. }
  813. //
  814. // Set the node number.
  815. //
  816. KeNodeBlock[i]->NodeNumber = (UCHAR)i;
  817. }
  818. for (i = KeNumberNodes; i < MAXIMUM_CCNUMA_NODES; i++) {
  819. KeNodeBlock[i] = NULL;
  820. }
  821. #endif
  822. if (KeNumberNodes == 1) {
  823. //
  824. // For Non NUMA machines, Node 0 gets all processors.
  825. //
  826. KeNodeBlock[0]->ProcessorMask = KeActiveProcessors;
  827. }
  828. }
  829. #if defined(KE_MULTINODE)
  830. NTSTATUS
  831. KiNotNumaQueryProcessorNode(
  832. IN ULONG ProcessorNumber,
  833. OUT PUSHORT Identifier,
  834. OUT PUCHAR Node
  835. )
  836. /*++
  837. Routine Description:
  838. This routine is a stub used on non NUMA systems to provide a
  839. consistent method of determining the NUMA configuration rather
  840. than checking for the presense of multiple nodes inline.
  841. Arguments:
  842. ProcessorNumber supplies the system logical processor number.
  843. Identifier supplies the address of a variable to receive
  844. the unique identifier for this processor.
  845. NodeNumber supplies the address of a variable to receive
  846. the number of the node this processor resides on.
  847. Return Value:
  848. Returns success.
  849. --*/
  850. {
  851. *Identifier = (USHORT)ProcessorNumber;
  852. *Node = 0;
  853. return STATUS_SUCCESS;
  854. }
  855. #endif
  856. VOID
  857. KiProcessorStart(
  858. VOID
  859. )
  860. /*++
  861. Routine Description:
  862. This routine is a called when a processor begins execution.
  863. It is used to pass processor characteristic information to
  864. the boot processor and to control the starting or non-starting
  865. of this processor.
  866. Arguments:
  867. None.
  868. Return Value:
  869. None.
  870. --*/
  871. {
  872. while (TRUE) {
  873. switch (KiProcessorStartControl) {
  874. case KcStartContinue:
  875. return;
  876. case KcStartWait:
  877. KeYieldProcessor();
  878. break;
  879. case KcStartGetId:
  880. CPUID(KiProcessorStartData[0],
  881. &KiProcessorStartData[0],
  882. &KiProcessorStartData[1],
  883. &KiProcessorStartData[2],
  884. &KiProcessorStartData[3]);
  885. KiProcessorStartControl = KcStartWait;
  886. break;
  887. case KcStartDoNotStart:
  888. //
  889. // The boot processor has determined that this processor
  890. // should NOT be started.
  891. //
  892. // Acknowledge the command so the boot processor will
  893. // continue, disable interrupts (should already be
  894. // the case here) and HALT the processor.
  895. //
  896. KiProcessorStartControl = KcStartWait;
  897. KiSetHaltedNmiandDoubleFaultHandler();
  898. _disable();
  899. while(1) {
  900. _asm { hlt };
  901. }
  902. default:
  903. //
  904. // Not much we can do with unknown commands.
  905. //
  906. KiProcessorStartControl = KcStartCommandError;
  907. break;
  908. }
  909. }
  910. }
  911. BOOLEAN
  912. KiStartWaitAcknowledge(
  913. VOID
  914. )
  915. {
  916. while (KiProcessorStartControl != KcStartWait) {
  917. if (KiProcessorStartControl == KcStartCommandError) {
  918. return FALSE;
  919. }
  920. KeYieldProcessor();
  921. }
  922. return TRUE;
  923. }
  924. VOID
  925. KiSetHaltedNmiandDoubleFaultHandler(
  926. VOID
  927. )
  928. /*++
  929. Routine Description:
  930. This routine is a called before the application processor that is not
  931. going to be started is put into halt. It is used to hook a dummy Nmi and
  932. double fault handler.
  933. Arguments:
  934. None.
  935. Return Value:
  936. None.
  937. --*/
  938. {
  939. PKPCR Pcr;
  940. PKGDTENTRY GdtPtr;
  941. ULONG TssAddr;
  942. Pcr = KeGetPcr();
  943. GdtPtr = (PKGDTENTRY)&(Pcr->GDT[Pcr->IDT[IDT_NMI_VECTOR].Selector >> 3]);
  944. TssAddr = (((GdtPtr->HighWord.Bits.BaseHi << 8) +
  945. GdtPtr->HighWord.Bits.BaseMid) << 16) + GdtPtr->BaseLow;
  946. ((PKTSS)TssAddr)->Eip = (ULONG)KiDummyNmiHandler;
  947. GdtPtr = (PKGDTENTRY)&(Pcr->GDT[Pcr->IDT[IDT_DFH_VECTOR].Selector >> 3]);
  948. TssAddr = (((GdtPtr->HighWord.Bits.BaseHi << 8) +
  949. GdtPtr->HighWord.Bits.BaseMid) << 16) + GdtPtr->BaseLow;
  950. ((PKTSS)TssAddr)->Eip = (ULONG)KiDummyDoubleFaultHandler;
  951. return;
  952. }
  953. VOID
  954. KiDummyNmiHandler (
  955. VOID
  956. )
  957. /*++
  958. Routine Description:
  959. This is the dummy handler that is executed by the processor
  960. that is not started. We are just being paranoid about clearing
  961. the busy bit for the NMI and Double Fault Handler TSS.
  962. Arguments:
  963. None.
  964. Return Value:
  965. Does not return
  966. --*/
  967. {
  968. KiClearBusyBitInTssDescriptor(NMI_TSS_DESC_OFFSET);
  969. KiHaltThisProcessor();
  970. }
  971. VOID
  972. KiDummyDoubleFaultHandler(
  973. VOID
  974. )
  975. /*++
  976. Routine Description:
  977. This is the dummy handler that is executed by the processor
  978. that is not started. We are just being paranoid about clearing
  979. the busy bit for the NMI and Double Fault Handler TSS.
  980. Arguments:
  981. None.
  982. Return Value:
  983. Does not return
  984. --*/
  985. {
  986. KiClearBusyBitInTssDescriptor(DF_TSS_DESC_OFFSET);
  987. KiHaltThisProcessor();
  988. }
  989. VOID
  990. KiClearBusyBitInTssDescriptor(
  991. IN ULONG DescriptorOffset
  992. )
  993. /*++
  994. Routine Description:
  995. Called to clear busy bit in descriptor from the NMI and double
  996. Fault Handlers
  997. Arguments:
  998. None.
  999. Return Value:
  1000. None.
  1001. --*/
  1002. {
  1003. PKPCR Pcr;
  1004. PKGDTENTRY GdtPtr;
  1005. Pcr = KeGetPcr();
  1006. GdtPtr =(PKGDTENTRY)(Pcr->GDT);
  1007. GdtPtr =(PKGDTENTRY)((ULONG)GdtPtr + DescriptorOffset);
  1008. GdtPtr->HighWord.Bytes.Flags1 = 0x89; // 32bit. dpl=0. present, TSS32, not busy
  1009. }
  1010. VOID
  1011. KiHaltThisProcessor(
  1012. VOID
  1013. )
  1014. /*++
  1015. Routine Description:
  1016. After Clearing the busy bit (just being paranoid here) we halt
  1017. this processor.
  1018. Arguments:
  1019. None.
  1020. Return Value:
  1021. None.
  1022. --*/
  1023. {
  1024. while(1) {
  1025. _asm {
  1026. hlt
  1027. }
  1028. }
  1029. }
  1030. #endif // !NT_UP