TianoCore EDK2 master
Loading...
Searching...
No Matches
CpuFeaturesInitialize.c
Go to the documentation of this file.
1
10
11CHAR16 *mDependTypeStr[] = { L"None", L"Thread", L"Core", L"Package", L"Invalid" };
12
20VOID
22 IN UINT8 *SupportedFeatureMask,
23 IN UINTN BitMaskSize
24 )
25{
26 EFI_STATUS Status;
27
28 Status = PcdSetPtrS (PcdCpuFeaturesCapability, &BitMaskSize, SupportedFeatureMask);
29 ASSERT_EFI_ERROR (Status);
30}
31
38VOID
40 IN UINT8 *SupportedFeatureMask,
41 IN UINTN BitMaskSize
42 )
43{
44 EFI_STATUS Status;
45
46 Status = PcdSetPtrS (PcdCpuFeaturesSetting, &BitMaskSize, SupportedFeatureMask);
47 ASSERT_EFI_ERROR (Status);
48}
49
55VOID
58 )
59{
63 UINT32 DisplayedFamily;
64 UINT32 DisplayedModel;
65
66 AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, &Ecx.Uint32, &Edx.Uint32);
67
68 DisplayedFamily = Eax.Bits.FamilyId;
69 if (Eax.Bits.FamilyId == 0x0F) {
70 DisplayedFamily += Eax.Bits.ExtendedFamilyId;
71 }
72
73 DisplayedModel = Eax.Bits.Model;
74 if ((Eax.Bits.FamilyId == 0x06) || (Eax.Bits.FamilyId == 0x0f)) {
75 DisplayedModel += (Eax.Bits.ExtendedModelId << 4);
76 }
77
78 CpuInfo->DisplayFamily = DisplayedFamily;
79 CpuInfo->DisplayModel = DisplayedModel;
80 CpuInfo->SteppingId = Eax.Bits.SteppingId;
81 CpuInfo->ProcessorType = Eax.Bits.ProcessorType;
82 CpuInfo->CpuIdVersionInfoEcx.Uint32 = Ecx.Uint32;
83 CpuInfo->CpuIdVersionInfoEdx.Uint32 = Edx.Uint32;
84}
85
90VOID
92 VOID
93 )
94{
95 EFI_STATUS Status;
96 UINTN ProcessorNumber;
97 EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;
98 CPU_FEATURES_ENTRY *CpuFeature;
99 CPU_FEATURES_INIT_ORDER *InitOrder;
100 CPU_FEATURES_DATA *CpuFeaturesData;
101 LIST_ENTRY *Entry;
102 UINT32 Core;
103 UINT32 Package;
104 UINT32 Thread;
106 UINT32 PackageIndex;
107 UINT32 CoreIndex;
108 UINTN Pages;
109 UINT32 FirstPackage;
110 UINT32 *FirstCore;
111 UINT32 *FirstThread;
112 ACPI_CPU_DATA *AcpiCpuData;
113 CPU_STATUS_INFORMATION *CpuStatus;
114 UINT32 *ThreadCountPerPackage;
115 UINT8 *ThreadCountPerCore;
116 UINTN NumberOfCpus;
117 UINTN NumberOfEnabledProcessors;
118
119 Core = 0;
120 Package = 0;
121 Thread = 0;
122
123 CpuFeaturesData = GetCpuFeaturesData ();
124
125 //
126 // Initialize CpuFeaturesData->MpService as early as possile, so later function can use it.
127 //
128 CpuFeaturesData->MpService = GetMpService ();
129
130 GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);
131
132 CpuFeaturesData->InitOrder = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus));
133 ASSERT (CpuFeaturesData->InitOrder != NULL);
134 ZeroMem (CpuFeaturesData->InitOrder, sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus);
135
136 //
137 // Collect CPU Features information
138 //
139 Entry = GetFirstNode (&CpuFeaturesData->FeatureList);
140 while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
141 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
142 ASSERT (CpuFeature->InitializeFunc != NULL);
143 if (CpuFeature->GetConfigDataFunc != NULL) {
144 CpuFeature->ConfigData = CpuFeature->GetConfigDataFunc (NumberOfCpus);
145 }
146
147 Entry = Entry->ForwardLink;
148 }
149
150 CpuFeaturesData->NumberOfCpus = (UINT32)NumberOfCpus;
151
152 AcpiCpuData = GetAcpiCpuData ();
153 ASSERT (AcpiCpuData != NULL);
154 CpuFeaturesData->AcpiCpuData = AcpiCpuData;
155
156 CpuStatus = &AcpiCpuData->CpuFeatureInitData.CpuStatus;
157 Location = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EFI_CPU_PHYSICAL_LOCATION) * NumberOfCpus));
158 ASSERT (Location != NULL);
159 ZeroMem (Location, sizeof (EFI_CPU_PHYSICAL_LOCATION) * NumberOfCpus);
160 AcpiCpuData->CpuFeatureInitData.ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)Location;
161
162 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
163 InitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber];
164 InitOrder->FeaturesSupportedMask = AllocateZeroPool (CpuFeaturesData->BitMaskSize);
165 ASSERT (InitOrder->FeaturesSupportedMask != NULL);
166 InitializeListHead (&InitOrder->OrderList);
167 Status = GetProcessorInformation (ProcessorNumber, &ProcessorInfoBuffer);
168 ASSERT_EFI_ERROR (Status);
169 CopyMem (
170 &InitOrder->CpuInfo.ProcessorInfo,
171 &ProcessorInfoBuffer,
173 );
174 CopyMem (
175 &Location[ProcessorNumber],
176 &ProcessorInfoBuffer.Location,
178 );
179
180 //
181 // Collect CPU package count info.
182 //
183 if (Package < ProcessorInfoBuffer.Location.Package) {
184 Package = ProcessorInfoBuffer.Location.Package;
185 }
186
187 //
188 // Collect CPU max core count info.
189 //
190 if (Core < ProcessorInfoBuffer.Location.Core) {
191 Core = ProcessorInfoBuffer.Location.Core;
192 }
193
194 //
195 // Collect CPU max thread count info.
196 //
197 if (Thread < ProcessorInfoBuffer.Location.Thread) {
198 Thread = ProcessorInfoBuffer.Location.Thread;
199 }
200 }
201
202 CpuStatus->PackageCount = Package + 1;
203 CpuStatus->MaxCoreCount = Core + 1;
204 CpuStatus->MaxThreadCount = Thread + 1;
205 DEBUG ((
206 DEBUG_INFO,
207 "Processor Info: Package: %d, MaxCore : %d, MaxThread: %d\n",
208 CpuStatus->PackageCount,
209 CpuStatus->MaxCoreCount,
210 CpuStatus->MaxThreadCount
211 ));
212
213 //
214 // Collect valid core count in each package because not all cores are valid.
215 //
216 ThreadCountPerPackage = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (UINT32) * CpuStatus->PackageCount));
217 ASSERT (ThreadCountPerPackage != NULL);
218 ZeroMem (ThreadCountPerPackage, sizeof (UINT32) * CpuStatus->PackageCount);
219 CpuStatus->ThreadCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)ThreadCountPerPackage;
220
221 ThreadCountPerCore = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (UINT8) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount));
222 ASSERT (ThreadCountPerCore != NULL);
223 ZeroMem (ThreadCountPerCore, sizeof (UINT8) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount);
224 CpuStatus->ThreadCountPerCore = (EFI_PHYSICAL_ADDRESS)(UINTN)ThreadCountPerCore;
225
226 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
227 Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;
228 ThreadCountPerPackage[Location->Package]++;
229 ThreadCountPerCore[Location->Package * CpuStatus->MaxCoreCount + Location->Core]++;
230 }
231
232 for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) {
233 if (ThreadCountPerPackage[PackageIndex] != 0) {
234 DEBUG ((DEBUG_INFO, "P%02d: Thread Count = %d\n", PackageIndex, ThreadCountPerPackage[PackageIndex]));
235 for (CoreIndex = 0; CoreIndex < CpuStatus->MaxCoreCount; CoreIndex++) {
236 if (ThreadCountPerCore[PackageIndex * CpuStatus->MaxCoreCount + CoreIndex] != 0) {
237 DEBUG ((
238 DEBUG_INFO,
239 " P%02d C%04d, Thread Count = %d\n",
240 PackageIndex,
241 CoreIndex,
242 ThreadCountPerCore[PackageIndex * CpuStatus->MaxCoreCount + CoreIndex]
243 ));
244 }
245 }
246 }
247 }
248
249 CpuFeaturesData->CpuFlags.CoreSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount);
250 ASSERT (CpuFeaturesData->CpuFlags.CoreSemaphoreCount != NULL);
251 CpuFeaturesData->CpuFlags.PackageSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount);
252 ASSERT (CpuFeaturesData->CpuFlags.PackageSemaphoreCount != NULL);
253
254 //
255 // Initialize CpuFeaturesData->InitOrder[].CpuInfo.First
256 // Use AllocatePages () instead of AllocatePool () because pool cannot be freed in PEI phase but page can.
257 //
258 Pages = EFI_SIZE_TO_PAGES (CpuStatus->PackageCount * sizeof (UINT32) + CpuStatus->PackageCount * CpuStatus->MaxCoreCount * sizeof (UINT32));
259 FirstCore = AllocatePages (Pages);
260 ASSERT (FirstCore != NULL);
261 FirstThread = FirstCore + CpuStatus->PackageCount;
262
263 //
264 // Set FirstPackage, FirstCore[], FirstThread[] to maximum package ID, core ID, thread ID.
265 //
266 FirstPackage = MAX_UINT32;
267 SetMem32 (FirstCore, CpuStatus->PackageCount * sizeof (UINT32), MAX_UINT32);
268 SetMem32 (FirstThread, CpuStatus->PackageCount * CpuStatus->MaxCoreCount * sizeof (UINT32), MAX_UINT32);
269
270 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
271 Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;
272
273 //
274 // Save the minimum package ID in the platform.
275 //
276 FirstPackage = MIN (Location->Package, FirstPackage);
277
278 //
279 // Save the minimum core ID per package.
280 //
281 FirstCore[Location->Package] = MIN (Location->Core, FirstCore[Location->Package]);
282
283 //
284 // Save the minimum thread ID per core.
285 //
286 FirstThread[Location->Package * CpuStatus->MaxCoreCount + Location->Core] = MIN (
287 Location->Thread,
288 FirstThread[Location->Package * CpuStatus->MaxCoreCount + Location->Core]
289 );
290 }
291
292 //
293 // Update the First field.
294 //
295 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
296 Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;
297
298 if (Location->Package == FirstPackage) {
299 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Package = 1;
300 }
301
302 //
303 // Set First.Die/Tile/Module for each thread assuming:
304 // single Die under each package, single Tile under each Die, single Module under each Tile
305 //
306 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Die = 1;
307 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Tile = 1;
308 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Module = 1;
309
310 if (Location->Core == FirstCore[Location->Package]) {
311 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Core = 1;
312 }
313
314 if (Location->Thread == FirstThread[Location->Package * CpuStatus->MaxCoreCount + Location->Core]) {
315 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Thread = 1;
316 }
317 }
318
319 FreePages (FirstCore, Pages);
320}
321
330VOID
332 IN UINT8 *SupportedFeatureMask,
333 IN UINT8 *OrFeatureBitMask,
334 IN UINT32 BitMaskSize
335 )
336{
337 UINTN Index;
338 UINT8 *Data1;
339 UINT8 *Data2;
340
341 Data1 = SupportedFeatureMask;
342 Data2 = OrFeatureBitMask;
343 for (Index = 0; Index < BitMaskSize; Index++) {
344 *(Data1++) |= *(Data2++);
345 }
346}
347
356VOID
358 IN UINT8 *SupportedFeatureMask,
359 IN CONST UINT8 *AndFeatureBitMask,
360 IN UINT32 BitMaskSize
361 )
362{
363 UINTN Index;
364 UINT8 *Data1;
365 CONST UINT8 *Data2;
366
367 Data1 = SupportedFeatureMask;
368 Data2 = AndFeatureBitMask;
369 for (Index = 0; Index < BitMaskSize; Index++) {
370 *(Data1++) &= *(Data2++);
371 }
372}
373
381VOID
383 IN UINT8 *SupportedFeatureMask,
384 IN UINT8 *AndFeatureBitMask,
385 IN UINT32 BitMaskSize
386 )
387{
388 UINTN Index;
389 UINT8 *Data1;
390 UINT8 *Data2;
391
392 Data1 = SupportedFeatureMask;
393 Data2 = AndFeatureBitMask;
394 for (Index = 0; Index < BitMaskSize; Index++) {
395 *(Data1++) &= ~(*(Data2++));
396 }
397}
398
412BOOLEAN
414 IN UINT8 *SupportedFeatureMask,
415 IN UINT8 *ComparedFeatureBitMask,
416 IN UINT32 BitMaskSize
417 )
418{
419 UINTN Index;
420 UINT8 *Data1;
421 UINT8 *Data2;
422
423 Data1 = SupportedFeatureMask;
424 Data2 = ComparedFeatureBitMask;
425 for (Index = 0; Index < BitMaskSize; Index++) {
426 if (((*(Data1++)) & (*(Data2++))) != 0) {
427 return TRUE;
428 }
429 }
430
431 return FALSE;
432}
433
439VOID
440EFIAPI
442 IN OUT VOID *Buffer
443 )
444{
445 UINTN ProcessorNumber;
446 CPU_FEATURES_ENTRY *CpuFeature;
448 LIST_ENTRY *Entry;
449 CPU_FEATURES_DATA *CpuFeaturesData;
450
451 CpuFeaturesData = (CPU_FEATURES_DATA *)Buffer;
452 ProcessorNumber = GetProcessorIndex (CpuFeaturesData);
453 CpuInfo = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo;
454 //
455 // collect processor information
456 //
457 FillProcessorInfo (CpuInfo);
458 Entry = GetFirstNode (&CpuFeaturesData->FeatureList);
459 while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
460 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
461 if (CpuFeature->SupportFunc == NULL) {
462 //
463 // If SupportFunc is NULL, then the feature is supported.
464 //
466 CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask,
467 CpuFeature->FeatureMask,
468 CpuFeaturesData->BitMaskSize
469 );
470 } else if (CpuFeature->SupportFunc (ProcessorNumber, CpuInfo, CpuFeature->ConfigData)) {
472 CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask,
473 CpuFeature->FeatureMask,
474 CpuFeaturesData->BitMaskSize
475 );
476 }
477
478 Entry = Entry->ForwardLink;
479 }
480}
481
489VOID
491 IN UINTN ProcessorNumber
492 )
493{
494 CPU_FEATURES_DATA *CpuFeaturesData;
495 UINTN FeatureIndex;
496 CPU_REGISTER_TABLE *RegisterTable;
497 CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
498 CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead;
499 UINT32 DebugPrintErrorLevel;
500
501 DebugPrintErrorLevel = (ProcessorNumber == 0) ? DEBUG_INFO : DEBUG_VERBOSE;
502 CpuFeaturesData = GetCpuFeaturesData ();
503 //
504 // Debug information
505 //
506 RegisterTable = &CpuFeaturesData->RegisterTable[ProcessorNumber];
507 DEBUG ((DebugPrintErrorLevel, "RegisterTable->TableLength = %d\n", RegisterTable->TableLength));
508
509 RegisterTableEntryHead = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry;
510
511 for (FeatureIndex = 0; FeatureIndex < RegisterTable->TableLength; FeatureIndex++) {
512 RegisterTableEntry = &RegisterTableEntryHead[FeatureIndex];
513 switch (RegisterTableEntry->RegisterType) {
514 case Msr:
515 DEBUG ((
516 DebugPrintErrorLevel,
517 "Processor: %04d: Index %04d, MSR : %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",
518 (UINT32)ProcessorNumber,
519 (UINT32)FeatureIndex,
520 RegisterTableEntry->Index,
521 RegisterTableEntry->ValidBitStart,
522 RegisterTableEntry->ValidBitLength,
523 RegisterTableEntry->Value
524 ));
525 break;
526 case ControlRegister:
527 DEBUG ((
528 DebugPrintErrorLevel,
529 "Processor: %04d: Index %04d, CR : %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",
530 (UINT32)ProcessorNumber,
531 (UINT32)FeatureIndex,
532 RegisterTableEntry->Index,
533 RegisterTableEntry->ValidBitStart,
534 RegisterTableEntry->ValidBitLength,
535 RegisterTableEntry->Value
536 ));
537 break;
538 case MemoryMapped:
539 DEBUG ((
540 DebugPrintErrorLevel,
541 "Processor: %04d: Index %04d, MMIO : %016lx, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",
542 (UINT32)ProcessorNumber,
543 (UINT32)FeatureIndex,
544 RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32),
545 RegisterTableEntry->ValidBitStart,
546 RegisterTableEntry->ValidBitLength,
547 RegisterTableEntry->Value
548 ));
549 break;
550 case CacheControl:
551 DEBUG ((
552 DebugPrintErrorLevel,
553 "Processor: %04d: Index %04d, CACHE: %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",
554 (UINT32)ProcessorNumber,
555 (UINT32)FeatureIndex,
556 RegisterTableEntry->Index,
557 RegisterTableEntry->ValidBitStart,
558 RegisterTableEntry->ValidBitLength,
559 RegisterTableEntry->Value
560 ));
561 break;
562 case Semaphore:
563 DEBUG ((
564 DebugPrintErrorLevel,
565 "Processor: %04d: Index %04d, SEMAP: %s\r\n",
566 (UINT32)ProcessorNumber,
567 (UINT32)FeatureIndex,
568 mDependTypeStr[MIN ((UINT32)RegisterTableEntry->Value, InvalidDepType)]
569 ));
570 break;
571
572 default:
573 break;
574 }
575 }
576}
577
589CPU_FEATURE_DEPENDENCE_TYPE
591 IN CPU_FEATURE_DEPENDENCE_TYPE BeforeDep,
592 IN CPU_FEATURE_DEPENDENCE_TYPE AfterDep,
593 IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep,
594 IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep
595 )
596{
597 CPU_FEATURE_DEPENDENCE_TYPE Bigger;
598
599 Bigger = MAX (BeforeDep, AfterDep);
600 Bigger = MAX (Bigger, NoneNeibBeforeDep);
601 return MAX (Bigger, NoneNeibAfterDep);
602}
603
610VOID
612 IN UINTN NumberOfCpus
613 )
614{
615 EFI_STATUS Status;
616 UINTN ProcessorNumber;
617 CPU_FEATURES_ENTRY *CpuFeature;
618 CPU_FEATURES_ENTRY *CpuFeatureInOrder;
619 CPU_FEATURES_INIT_ORDER *CpuInitOrder;
621 LIST_ENTRY *Entry;
622 CPU_FEATURES_DATA *CpuFeaturesData;
623 LIST_ENTRY *NextEntry;
624 CPU_FEATURES_ENTRY *NextCpuFeatureInOrder;
625 BOOLEAN Success;
626 CPU_FEATURE_DEPENDENCE_TYPE BeforeDep;
627 CPU_FEATURE_DEPENDENCE_TYPE AfterDep;
628 CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep;
629 CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep;
630
631 CpuFeaturesData = GetCpuFeaturesData ();
632 CpuFeaturesData->CapabilityPcd = AllocatePool (CpuFeaturesData->BitMaskSize);
633 ASSERT (CpuFeaturesData->CapabilityPcd != NULL);
634 SetMem (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize, 0xFF);
635 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
636 CpuInitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber];
637 //
638 // Calculate the last capability on all processors
639 //
640 SupportedMaskAnd (CpuFeaturesData->CapabilityPcd, CpuInitOrder->FeaturesSupportedMask, CpuFeaturesData->BitMaskSize);
641 }
642
643 //
644 // Calculate the last setting
645 //
646 CpuFeaturesData->SettingPcd = AllocateCopyPool (CpuFeaturesData->BitMaskSize, CpuFeaturesData->CapabilityPcd);
647 ASSERT (CpuFeaturesData->SettingPcd != NULL);
648 SupportedMaskAnd (CpuFeaturesData->SettingPcd, PcdGetPtr (PcdCpuFeaturesSetting), CpuFeaturesData->BitMaskSize);
649
650 //
651 // Dump the last CPU feature list
652 //
654 DEBUG ((DEBUG_INFO, "Last CPU features list...\n"));
655 Entry = GetFirstNode (&CpuFeaturesData->FeatureList);
656 while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
657 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
658 if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize)) {
659 if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize)) {
660 DEBUG ((DEBUG_INFO, "[Enable ] "));
661 } else {
662 DEBUG ((DEBUG_INFO, "[Disable ] "));
663 }
664 } else {
665 DEBUG ((DEBUG_INFO, "[Unsupport] "));
666 }
667
668 DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);
669 Entry = Entry->ForwardLink;
670 }
671
672 DEBUG ((DEBUG_INFO, "PcdCpuFeaturesCapability:\n"));
673 DumpCpuFeatureMask (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize);
674 DEBUG ((DEBUG_INFO, "Origin PcdCpuFeaturesSetting:\n"));
675 DumpCpuFeatureMask (PcdGetPtr (PcdCpuFeaturesSetting), CpuFeaturesData->BitMaskSize);
676 DEBUG ((DEBUG_INFO, "Final PcdCpuFeaturesSetting:\n"));
677 DumpCpuFeatureMask (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize);
679
680 //
681 // Save PCDs and display CPU PCDs
682 //
683 SetCapabilityPcd (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize);
684 SetSettingPcd (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize);
685
686 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
687 CpuInitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber];
688 Entry = GetFirstNode (&CpuFeaturesData->FeatureList);
689 while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
690 //
691 // Insert each feature into processor's order list
692 //
693 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
694 if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize)) {
695 CpuFeatureInOrder = AllocateCopyPool (sizeof (CPU_FEATURES_ENTRY), CpuFeature);
696 ASSERT (CpuFeatureInOrder != NULL);
697 InsertTailList (&CpuInitOrder->OrderList, &CpuFeatureInOrder->Link);
698 }
699
700 Entry = Entry->ForwardLink;
701 }
702
703 //
704 // Go through ordered feature list to initialize CPU features
705 //
706 CpuInfo = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo;
707 Entry = GetFirstNode (&CpuInitOrder->OrderList);
708 while (!IsNull (&CpuInitOrder->OrderList, Entry)) {
709 CpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
710
711 Success = FALSE;
712 if (IsBitMaskMatch (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize)) {
713 Status = CpuFeatureInOrder->InitializeFunc (ProcessorNumber, CpuInfo, CpuFeatureInOrder->ConfigData, TRUE);
714 if (EFI_ERROR (Status)) {
715 //
716 // Clean the CpuFeatureInOrder->FeatureMask in setting PCD.
717 //
718 SupportedMaskCleanBit (CpuFeaturesData->SettingPcd, CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize);
719 if (CpuFeatureInOrder->FeatureName != NULL) {
720 DEBUG ((DEBUG_WARN, "Warning :: Failed to enable Feature: Name = %a.\n", CpuFeatureInOrder->FeatureName));
721 } else {
722 DEBUG ((DEBUG_WARN, "Warning :: Failed to enable Feature: Mask = "));
723 DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize);
724 }
725 } else {
726 Success = TRUE;
727 }
728 } else {
729 Status = CpuFeatureInOrder->InitializeFunc (ProcessorNumber, CpuInfo, CpuFeatureInOrder->ConfigData, FALSE);
730 if (EFI_ERROR (Status)) {
731 if (CpuFeatureInOrder->FeatureName != NULL) {
732 DEBUG ((DEBUG_WARN, "Warning :: Failed to disable Feature: Name = %a.\n", CpuFeatureInOrder->FeatureName));
733 } else {
734 DEBUG ((DEBUG_WARN, "Warning :: Failed to disable Feature: Mask = "));
735 DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize);
736 }
737 } else {
738 Success = TRUE;
739 }
740 }
741
742 if (Success) {
743 NextEntry = Entry->ForwardLink;
744 if (!IsNull (&CpuInitOrder->OrderList, NextEntry)) {
745 NextCpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry);
746
747 //
748 // If feature has dependence with the next feature (ONLY care core/package dependency).
749 // and feature initialize succeed, add sync semaphere here.
750 //
751 BeforeDep = DetectFeatureScope (CpuFeatureInOrder, TRUE, NextCpuFeatureInOrder->FeatureMask);
752 AfterDep = DetectFeatureScope (NextCpuFeatureInOrder, FALSE, CpuFeatureInOrder->FeatureMask);
753 //
754 // Check whether next feature has After type dependence with not neighborhood CPU
755 // Features in former CPU features.
756 //
757 NoneNeibAfterDep = DetectNoneNeighborhoodFeatureScope (NextCpuFeatureInOrder, FALSE, &CpuInitOrder->OrderList);
758 } else {
759 BeforeDep = NoneDepType;
760 AfterDep = NoneDepType;
761 NoneNeibAfterDep = NoneDepType;
762 }
763
764 //
765 // Check whether current feature has Before type dependence with none neighborhood
766 // CPU features in after Cpu features.
767 //
768 NoneNeibBeforeDep = DetectNoneNeighborhoodFeatureScope (CpuFeatureInOrder, TRUE, &CpuInitOrder->OrderList);
769
770 //
771 // Get the biggest dependence and add semaphore for it.
772 // PackageDepType > CoreDepType > ThreadDepType > NoneDepType.
773 //
774 BeforeDep = BiggestDep (BeforeDep, AfterDep, NoneNeibBeforeDep, NoneNeibAfterDep);
775 if (BeforeDep > ThreadDepType) {
776 CPU_REGISTER_TABLE_WRITE32 (ProcessorNumber, Semaphore, 0, BeforeDep);
777 }
778 }
779
780 Entry = Entry->ForwardLink;
781 }
782
783 //
784 // Dump PcdCpuFeaturesSetting again because this value maybe updated
785 // again during initialize the features.
786 //
787 DEBUG ((DEBUG_INFO, "Dump final value for PcdCpuFeaturesSetting:\n"));
788 DumpCpuFeatureMask (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize);
789
790 //
791 // Dump the RegisterTable
792 //
793 DumpRegisterTableOnProcessor (ProcessorNumber);
794 }
795}
796
803VOID
805 IN OUT volatile UINT32 *Sem
806 )
807{
809}
810
821VOID
823 IN OUT volatile UINT32 *Sem
824 )
825{
826 UINT32 Value;
827
828 do {
829 Value = *Sem;
830 } while (Value == 0 ||
832 Sem,
833 Value,
834 Value - 1
835 ) != Value);
836}
837
847UINTN
849 IN UINT32 CrIndex,
850 IN BOOLEAN Read,
851 IN OUT UINTN *CrValue
852 )
853{
854 switch (CrIndex) {
855 case 0:
856 if (Read) {
857 *CrValue = AsmReadCr0 ();
858 } else {
859 AsmWriteCr0 (*CrValue);
860 }
861
862 break;
863 case 2:
864 if (Read) {
865 *CrValue = AsmReadCr2 ();
866 } else {
867 AsmWriteCr2 (*CrValue);
868 }
869
870 break;
871 case 3:
872 if (Read) {
873 *CrValue = AsmReadCr3 ();
874 } else {
875 AsmWriteCr3 (*CrValue);
876 }
877
878 break;
879 case 4:
880 if (Read) {
881 *CrValue = AsmReadCr4 ();
882 } else {
883 AsmWriteCr4 (*CrValue);
884 }
885
886 break;
887 default:
888 return EFI_UNSUPPORTED;
889 }
890
891 return EFI_SUCCESS;
892}
893
904VOID
906 IN CPU_REGISTER_TABLE *RegisterTable,
907 IN EFI_CPU_PHYSICAL_LOCATION *ApLocation,
908 IN CPU_STATUS_INFORMATION *CpuStatus,
910 )
911{
912 CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
913 UINTN Index;
914 UINTN Value;
915 CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead;
916 volatile UINT32 *SemaphorePtr;
917 UINT32 FirstThread;
918 UINT32 CurrentThread;
919 UINT32 CurrentCore;
920 UINTN ProcessorIndex;
921 UINT32 *ThreadCountPerPackage;
922 UINT8 *ThreadCountPerCore;
923 EFI_STATUS Status;
924 UINT64 CurrentValue;
925
926 //
927 // Traverse Register Table of this logical processor
928 //
929 RegisterTableEntryHead = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry;
930
931 for (Index = 0; Index < RegisterTable->TableLength; Index++) {
932 RegisterTableEntry = &RegisterTableEntryHead[Index];
933
934 //
935 // Check the type of specified register
936 //
937 switch (RegisterTableEntry->RegisterType) {
938 //
939 // The specified register is Control Register
940 //
941 case ControlRegister:
942 Status = ReadWriteCr (RegisterTableEntry->Index, TRUE, &Value);
943 if (EFI_ERROR (Status)) {
944 break;
945 }
946
947 if (RegisterTableEntry->TestThenWrite) {
948 CurrentValue = BitFieldRead64 (
949 Value,
950 RegisterTableEntry->ValidBitStart,
951 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1
952 );
953 if (CurrentValue == RegisterTableEntry->Value) {
954 break;
955 }
956 }
957
958 Value = (UINTN)BitFieldWrite64 (
959 Value,
960 RegisterTableEntry->ValidBitStart,
961 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
962 RegisterTableEntry->Value
963 );
964 ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value);
965 break;
966
967 //
968 // The specified register is Model Specific Register
969 //
970 case Msr:
971 if (RegisterTableEntry->TestThenWrite) {
972 Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index);
973 if (RegisterTableEntry->ValidBitLength >= 64) {
974 if (Value == RegisterTableEntry->Value) {
975 break;
976 }
977 } else {
978 CurrentValue = BitFieldRead64 (
979 Value,
980 RegisterTableEntry->ValidBitStart,
981 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1
982 );
983 if (CurrentValue == RegisterTableEntry->Value) {
984 break;
985 }
986 }
987 }
988
989 if (RegisterTableEntry->ValidBitLength >= 64) {
990 //
991 // If length is not less than 64 bits, then directly write without reading
992 //
994 RegisterTableEntry->Index,
995 RegisterTableEntry->Value
996 );
997 } else {
998 //
999 // Set the bit section according to bit start and length
1000 //
1002 RegisterTableEntry->Index,
1003 RegisterTableEntry->ValidBitStart,
1004 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
1005 RegisterTableEntry->Value
1006 );
1007 }
1008
1009 break;
1010 //
1011 // MemoryMapped operations
1012 //
1013 case MemoryMapped:
1014 AcquireSpinLock (&CpuFlags->MemoryMappedLock);
1016 (UINTN)(RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32)),
1017 RegisterTableEntry->ValidBitStart,
1018 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
1019 (UINT32)RegisterTableEntry->Value
1020 );
1021 ReleaseSpinLock (&CpuFlags->MemoryMappedLock);
1022 break;
1023 //
1024 // Enable or disable cache
1025 //
1026 case CacheControl:
1027 //
1028 // If value of the entry is 0, then disable cache. Otherwise, enable cache.
1029 //
1030 if (RegisterTableEntry->Value == 0) {
1031 AsmDisableCache ();
1032 } else {
1033 AsmEnableCache ();
1034 }
1035
1036 break;
1037
1038 case Semaphore:
1039 // Semaphore works logic like below:
1040 //
1041 // V(x) = LibReleaseSemaphore (Semaphore[FirstThread + x]);
1042 // P(x) = LibWaitForSemaphore (Semaphore[FirstThread + x]);
1043 //
1044 // All threads (T0...Tn) waits in P() line and continues running
1045 // together.
1046 //
1047 //
1048 // T0 T1 ... Tn
1049 //
1050 // V(0...n) V(0...n) ... V(0...n)
1051 // n * P(0) n * P(1) ... n * P(n)
1052 //
1053 switch (RegisterTableEntry->Value) {
1054 case CoreDepType:
1055 SemaphorePtr = CpuFlags->CoreSemaphoreCount;
1056 ThreadCountPerCore = (UINT8 *)(UINTN)CpuStatus->ThreadCountPerCore;
1057
1058 CurrentCore = ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core;
1059 //
1060 // Get Offset info for the first thread in the core which current thread belongs to.
1061 //
1062 FirstThread = CurrentCore * CpuStatus->MaxThreadCount;
1063 CurrentThread = FirstThread + ApLocation->Thread;
1064
1065 //
1066 // Different cores may have different valid threads in them. If driver maintail clearly
1067 // thread index in different cores, the logic will be much complicated.
1068 // Here driver just simply records the max thread number in all cores and use it as expect
1069 // thread number for all cores.
1070 // In below two steps logic, first current thread will Release semaphore for each thread
1071 // in current core. Maybe some threads are not valid in this core, but driver don't
1072 // care. Second, driver will let current thread wait semaphore for all valid threads in
1073 // current core. Because only the valid threads will do release semaphore for this
1074 // thread, driver here only need to wait the valid thread count.
1075 //
1076
1077 //
1078 // First Notify ALL THREADs in current Core that this thread is ready.
1079 //
1080 for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex++) {
1081 LibReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
1082 }
1083
1084 //
1085 // Second, check whether all VALID THREADs (not all threads) in current core are ready.
1086 //
1087 for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerCore[CurrentCore]; ProcessorIndex++) {
1088 LibWaitForSemaphore (&SemaphorePtr[CurrentThread]);
1089 }
1090
1091 break;
1092
1093 case PackageDepType:
1094 SemaphorePtr = CpuFlags->PackageSemaphoreCount;
1095 ThreadCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ThreadCountPerPackage;
1096 //
1097 // Get Offset info for the first thread in the package which current thread belongs to.
1098 //
1099 FirstThread = ApLocation->Package * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount;
1100 //
1101 // Get the possible threads count for current package.
1102 //
1103 CurrentThread = FirstThread + CpuStatus->MaxThreadCount * ApLocation->Core + ApLocation->Thread;
1104
1105 //
1106 // Different packages may have different valid threads in them. If driver maintail clearly
1107 // thread index in different packages, the logic will be much complicated.
1108 // Here driver just simply records the max thread number in all packages and use it as expect
1109 // thread number for all packages.
1110 // In below two steps logic, first current thread will Release semaphore for each thread
1111 // in current package. Maybe some threads are not valid in this package, but driver don't
1112 // care. Second, driver will let current thread wait semaphore for all valid threads in
1113 // current package. Because only the valid threads will do release semaphore for this
1114 // thread, driver here only need to wait the valid thread count.
1115 //
1116
1117 //
1118 // First Notify ALL THREADS in current package that this thread is ready.
1119 //
1120 for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount; ProcessorIndex++) {
1121 LibReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
1122 }
1123
1124 //
1125 // Second, check whether VALID THREADS (not all threads) in current package are ready.
1126 //
1127 for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerPackage[ApLocation->Package]; ProcessorIndex++) {
1128 LibWaitForSemaphore (&SemaphorePtr[CurrentThread]);
1129 }
1130
1131 break;
1132
1133 default:
1134 break;
1135 }
1136
1137 break;
1138
1139 default:
1140 break;
1141 }
1142 }
1143}
1144
1151VOID
1152EFIAPI
1154 IN OUT VOID *Buffer
1155 )
1156{
1157 CPU_FEATURES_DATA *CpuFeaturesData;
1158 CPU_REGISTER_TABLE *RegisterTable;
1159 CPU_REGISTER_TABLE *RegisterTables;
1160 UINT32 InitApicId;
1161 UINTN ProcIndex;
1162 UINTN Index;
1163 ACPI_CPU_DATA *AcpiCpuData;
1164
1165 CpuFeaturesData = (CPU_FEATURES_DATA *)Buffer;
1166 AcpiCpuData = CpuFeaturesData->AcpiCpuData;
1167
1168 RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.RegisterTable;
1169
1170 InitApicId = GetInitialApicId ();
1171 RegisterTable = NULL;
1172 ProcIndex = (UINTN)-1;
1173 for (Index = 0; Index < AcpiCpuData->NumberOfCpus; Index++) {
1174 if (RegisterTables[Index].InitialApicId == InitApicId) {
1175 RegisterTable = &RegisterTables[Index];
1176 ProcIndex = Index;
1177 break;
1178 }
1179 }
1180
1181 ASSERT (RegisterTable != NULL);
1182
1184 RegisterTable,
1185 (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)AcpiCpuData->CpuFeatureInitData.ApLocation + ProcIndex,
1186 &AcpiCpuData->CpuFeatureInitData.CpuStatus,
1187 &CpuFeaturesData->CpuFlags
1188 );
1189}
1190
1199VOID
1200EFIAPI
1202 VOID
1203 )
1204{
1205 CPU_FEATURES_DATA *CpuFeaturesData;
1206
1207 CpuFeaturesData = GetCpuFeaturesData ();
1208
1210
1211 if (CpuFeaturesData->NumberOfCpus > 1) {
1212 //
1213 // Wakeup all APs for data collection.
1214 //
1216 }
1217
1218 //
1219 // Collect data on BSP
1220 //
1221 CollectProcessorData (CpuFeaturesData);
1222
1223 AnalysisProcessorFeatures (CpuFeaturesData->NumberOfCpus);
1224}
UINT64 UINTN
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define MAX(a, b)
Definition: Base.h:992
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
UINT64 EFIAPI BitFieldWrite64(IN UINT64 Operand, IN UINTN StartBit, IN UINTN EndBit, IN UINT64 Value)
Definition: BitField.c:755
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
UINT64 EFIAPI BitFieldRead64(IN UINT64 Operand, IN UINTN StartBit, IN UINTN EndBit)
Definition: BitField.c:719
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
VOID *EFIAPI SetMem32(OUT VOID *Buffer, IN UINTN Length, IN UINT32 Value)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID SetSettingPcd(IN UINT8 *SupportedFeatureMask, IN UINTN BitMaskSize)
VOID SetCapabilityPcd(IN UINT8 *SupportedFeatureMask, IN UINTN BitMaskSize)
VOID FillProcessorInfo(IN OUT REGISTER_CPU_FEATURE_INFORMATION *CpuInfo)
VOID ProgramProcessorRegister(IN CPU_REGISTER_TABLE *RegisterTable, IN EFI_CPU_PHYSICAL_LOCATION *ApLocation, IN CPU_STATUS_INFORMATION *CpuStatus, IN PROGRAM_CPU_REGISTER_FLAGS *CpuFlags)
VOID DumpRegisterTableOnProcessor(IN UINTN ProcessorNumber)
UINTN ReadWriteCr(IN UINT32 CrIndex, IN BOOLEAN Read, IN OUT UINTN *CrValue)
VOID LibWaitForSemaphore(IN OUT volatile UINT32 *Sem)
BOOLEAN IsBitMaskMatch(IN UINT8 *SupportedFeatureMask, IN UINT8 *ComparedFeatureBitMask, IN UINT32 BitMaskSize)
VOID SupportedMaskAnd(IN UINT8 *SupportedFeatureMask, IN CONST UINT8 *AndFeatureBitMask, IN UINT32 BitMaskSize)
VOID EFIAPI CpuFeaturesDetect(VOID)
VOID SupportedMaskOr(IN UINT8 *SupportedFeatureMask, IN UINT8 *OrFeatureBitMask, IN UINT32 BitMaskSize)
CPU_FEATURE_DEPENDENCE_TYPE BiggestDep(IN CPU_FEATURE_DEPENDENCE_TYPE BeforeDep, IN CPU_FEATURE_DEPENDENCE_TYPE AfterDep, IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep, IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep)
VOID AnalysisProcessorFeatures(IN UINTN NumberOfCpus)
VOID SupportedMaskCleanBit(IN UINT8 *SupportedFeatureMask, IN UINT8 *AndFeatureBitMask, IN UINT32 BitMaskSize)
VOID EFIAPI SetProcessorRegister(IN OUT VOID *Buffer)
VOID EFIAPI CollectProcessorData(IN OUT VOID *Buffer)
VOID CpuInitDataInitialize(VOID)
VOID LibReleaseSemaphore(IN OUT volatile UINT32 *Sem)
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:445
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:537
#define DEBUG(Expression)
Definition: DebugLib.h:422
#define DEBUG_CODE_END()
Definition: DebugLib.h:548
UINT32 GetProcessorIndex(VOID)
Definition: DebugMp.c:97
VOID EFIAPI AsmDisableCache(VOID)
Definition: DisableCache.c:18
CPU_FEATURES_DATA * GetCpuFeaturesData(VOID)
VOID GetNumberOfProcessor(OUT UINTN *NumberOfCpus, OUT UINTN *NumberOfEnabledProcessors)
EFI_STATUS GetProcessorInformation(IN UINTN ProcessorNumber, OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer)
VOID StartupAllAPsWorker(IN EFI_AP_PROCEDURE Procedure, IN EFI_EVENT MpEvent)
MP_SERVICES GetMpService(VOID)
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
VOID EFIAPI AsmEnableCache(VOID)
Definition: EnableCache.c:18
UINTN EFIAPI AsmReadCr3(VOID)
UINTN EFIAPI AsmWriteCr2(UINTN Cr2)
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
Definition: GccInlinePriv.c:60
UINTN EFIAPI AsmWriteCr3(UINTN Cr3)
UINTN EFIAPI AsmWriteCr4(UINTN Cr4)
UINTN EFIAPI AsmReadCr0(VOID)
UINTN EFIAPI AsmWriteCr0(UINTN Cr0)
UINTN EFIAPI AsmReadCr2(VOID)
UINT64 EFIAPI AsmWriteMsr64(IN UINT32 Index, IN UINT64 Value)
UINTN EFIAPI AsmReadCr4(VOID)
UINT32 EFIAPI MmioBitFieldWrite32(IN UINTN Address, IN UINTN StartBit, IN UINTN EndBit, IN UINT32 Value)
Definition: IoHighLevel.c:1912
UINT32 EFIAPI GetInitialApicId(VOID)
Definition: BaseXApicLib.c:298
#define CPUID_VERSION_INFO
Definition: Cpuid.h:81
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuId.c:36
#define PcdSetPtrS(TokenName, SizeOfBuffer, Buffer)
Definition: PcdLib.h:534
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
VOID DumpCpuFeature(IN CPU_FEATURES_ENTRY *CpuFeature, IN UINT32 BitMaskSize)
VOID DumpCpuFeatureMask(IN UINT8 *FeatureMask, IN UINT32 BitMaskSize)
CPU_FEATURE_DEPENDENCE_TYPE DetectNoneNeighborhoodFeatureScope(IN CPU_FEATURES_ENTRY *CpuFeature, IN BOOLEAN Before, IN LIST_ENTRY *FeatureList)
ACPI_CPU_DATA * GetAcpiCpuData(VOID)
CPU_FEATURE_DEPENDENCE_TYPE DetectFeatureScope(IN CPU_FEATURES_ENTRY *CpuFeature, IN BOOLEAN Before, IN UINT8 *NextCpuFeatureMask)
#define CPU_REGISTER_TABLE_WRITE32(ProcessorNumber, RegisterType, Index, Value)
UINT32 EFIAPI InterlockedIncrement(IN volatile UINT32 *Value)
SPIN_LOCK *EFIAPI AcquireSpinLock(IN OUT SPIN_LOCK *SpinLock)
UINT32 EFIAPI InterlockedCompareExchange32(IN OUT volatile UINT32 *Value, IN UINT32 CompareValue, IN UINT32 ExchangeValue)
SPIN_LOCK *EFIAPI ReleaseSpinLock(IN OUT SPIN_LOCK *SpinLock)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINT64 EFIAPI AsmMsrBitFieldWrite64(IN UINT32 Index, IN UINTN StartBit, IN UINTN EndBit, IN UINT64 Value)
Definition: X86Msr.c:505
EFI_CPU_PHYSICAL_LOCATION Location
Definition: MpService.h:178
EFI_PROCESSOR_INFORMATION ProcessorInfo
REGISTER_CPU_FEATURE_FIRST_PROCESSOR First