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_STATUS_INFORMATION CpuStatusBackupBuffer;
99 CPU_FEATURES_ENTRY *CpuFeature;
100 CPU_FEATURES_INIT_ORDER *InitOrder;
101 CPU_FEATURES_DATA *CpuFeaturesData;
102 LIST_ENTRY *Entry;
103 UINT32 Core;
104 UINT32 Package;
105 UINT32 Thread;
107 UINT32 PackageIndex;
108 UINT32 CoreIndex;
109 UINTN Pages;
110 UINT32 FirstPackage;
111 UINT32 *FirstCore;
112 UINT32 *FirstThread;
113 ACPI_CPU_DATA *AcpiCpuData;
114 CPU_STATUS_INFORMATION *CpuStatus;
115 UINT32 *ThreadCountPerPackage;
116 UINT8 *ThreadCountPerCore;
117 UINTN NumberOfCpus;
118 UINTN NumberOfEnabledProcessors;
119
120 Core = 0;
121 Package = 0;
122 Thread = 0;
123
124 CpuFeaturesData = NULL;
125 CpuStatus = NULL;
126 FirstCore = NULL;
127 InitOrder = NULL;
128 Location = NULL;
129 ThreadCountPerCore = NULL;
130 ThreadCountPerPackage = NULL;
131
132 CpuFeaturesData = GetCpuFeaturesData ();
133 if (CpuFeaturesData == NULL) {
134 ASSERT (CpuFeaturesData != NULL);
135 return;
136 }
137
138 //
139 // Initialize CpuFeaturesData->MpService as early as possile, so later function can use it.
140 //
141 CpuFeaturesData->MpService = GetMpService ();
142
143 GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);
144
145 CpuFeaturesData->InitOrder = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus));
146 if (CpuFeaturesData->InitOrder == NULL) {
147 ASSERT (CpuFeaturesData->InitOrder != NULL);
148 return;
149 }
150
151 ZeroMem (CpuFeaturesData->InitOrder, sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus);
152
153 //
154 // Collect CPU Features information
155 //
156 Entry = GetFirstNode (&CpuFeaturesData->FeatureList);
157 while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
158 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
159 ASSERT (CpuFeature->InitializeFunc != NULL);
160 if (CpuFeature->GetConfigDataFunc != NULL) {
161 CpuFeature->ConfigData = CpuFeature->GetConfigDataFunc (NumberOfCpus);
162 }
163
164 Entry = Entry->ForwardLink;
165 }
166
167 CpuFeaturesData->NumberOfCpus = (UINT32)NumberOfCpus;
168
169 AcpiCpuData = GetAcpiCpuData ();
170 if (AcpiCpuData == NULL) {
171 ASSERT (AcpiCpuData != NULL);
172 goto ExitOnError;
173 }
174
175 CpuFeaturesData->AcpiCpuData = AcpiCpuData;
176
177 CpuStatus = &AcpiCpuData->CpuFeatureInitData.CpuStatus;
178 CopyMem (&CpuStatusBackupBuffer, CpuStatus, sizeof (CpuStatusBackupBuffer));
179 Location = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EFI_CPU_PHYSICAL_LOCATION) * NumberOfCpus));
180 if (Location == NULL) {
181 ASSERT (Location != NULL);
182 goto ExitOnError;
183 }
184
185 ZeroMem (Location, sizeof (EFI_CPU_PHYSICAL_LOCATION) * NumberOfCpus);
186 AcpiCpuData->CpuFeatureInitData.ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)Location;
187
188 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
189 InitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber];
190 InitOrder->FeaturesSupportedMask = AllocateZeroPool (CpuFeaturesData->BitMaskSize);
191 if (InitOrder->FeaturesSupportedMask == NULL) {
192 ASSERT (InitOrder->FeaturesSupportedMask != NULL);
193 goto ExitOnError;
194 }
195
196 InitializeListHead (&InitOrder->OrderList);
197 Status = GetProcessorInformation (ProcessorNumber, &ProcessorInfoBuffer);
198 ASSERT_EFI_ERROR (Status);
199 CopyMem (
200 &InitOrder->CpuInfo.ProcessorInfo,
201 &ProcessorInfoBuffer,
203 );
204 CopyMem (
205 &Location[ProcessorNumber],
206 &ProcessorInfoBuffer.Location,
208 );
209
210 //
211 // Collect CPU package count info.
212 //
213 if (Package < ProcessorInfoBuffer.Location.Package) {
214 Package = ProcessorInfoBuffer.Location.Package;
215 }
216
217 //
218 // Collect CPU max core count info.
219 //
220 if (Core < ProcessorInfoBuffer.Location.Core) {
221 Core = ProcessorInfoBuffer.Location.Core;
222 }
223
224 //
225 // Collect CPU max thread count info.
226 //
227 if (Thread < ProcessorInfoBuffer.Location.Thread) {
228 Thread = ProcessorInfoBuffer.Location.Thread;
229 }
230 }
231
232 CpuStatus->PackageCount = Package + 1;
233 CpuStatus->MaxCoreCount = Core + 1;
234 CpuStatus->MaxThreadCount = Thread + 1;
235 DEBUG ((
236 DEBUG_INFO,
237 "Processor Info: Package: %d, MaxCore : %d, MaxThread: %d\n",
238 CpuStatus->PackageCount,
239 CpuStatus->MaxCoreCount,
240 CpuStatus->MaxThreadCount
241 ));
242
243 //
244 // Collect valid core count in each package because not all cores are valid.
245 //
246 ThreadCountPerPackage = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (UINT32) * CpuStatus->PackageCount));
247 if (ThreadCountPerPackage == NULL) {
248 ASSERT (ThreadCountPerPackage != NULL);
249 goto ExitOnError;
250 }
251
252 ZeroMem (ThreadCountPerPackage, sizeof (UINT32) * CpuStatus->PackageCount);
253 CpuStatus->ThreadCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)ThreadCountPerPackage;
254
255 ThreadCountPerCore = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (UINT8) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount));
256 if (ThreadCountPerCore == NULL) {
257 ASSERT (ThreadCountPerCore != NULL);
258 goto ExitOnError;
259 }
260
261 ZeroMem (ThreadCountPerCore, sizeof (UINT8) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount);
262 CpuStatus->ThreadCountPerCore = (EFI_PHYSICAL_ADDRESS)(UINTN)ThreadCountPerCore;
263
264 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
265 Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;
266 ThreadCountPerPackage[Location->Package]++;
267 ThreadCountPerCore[Location->Package * CpuStatus->MaxCoreCount + Location->Core]++;
268 }
269
270 for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) {
271 if (ThreadCountPerPackage[PackageIndex] != 0) {
272 DEBUG ((DEBUG_INFO, "P%02d: Thread Count = %d\n", PackageIndex, ThreadCountPerPackage[PackageIndex]));
273 for (CoreIndex = 0; CoreIndex < CpuStatus->MaxCoreCount; CoreIndex++) {
274 if (ThreadCountPerCore[PackageIndex * CpuStatus->MaxCoreCount + CoreIndex] != 0) {
275 DEBUG ((
276 DEBUG_INFO,
277 " P%02d C%04d, Thread Count = %d\n",
278 PackageIndex,
279 CoreIndex,
280 ThreadCountPerCore[PackageIndex * CpuStatus->MaxCoreCount + CoreIndex]
281 ));
282 }
283 }
284 }
285 }
286
287 CpuFeaturesData->CpuFlags.CoreSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount);
288 if (CpuFeaturesData->CpuFlags.CoreSemaphoreCount == NULL) {
289 ASSERT (CpuFeaturesData->CpuFlags.CoreSemaphoreCount != NULL);
290 goto ExitOnError;
291 }
292
293 CpuFeaturesData->CpuFlags.PackageSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount);
294 if (CpuFeaturesData->CpuFlags.PackageSemaphoreCount == NULL) {
295 ASSERT (CpuFeaturesData->CpuFlags.PackageSemaphoreCount != NULL);
296 goto ExitOnError;
297 }
298
299 //
300 // Initialize CpuFeaturesData->InitOrder[].CpuInfo.First
301 // Use AllocatePages () instead of AllocatePool () because pool cannot be freed in PEI phase but page can.
302 //
303 Pages = EFI_SIZE_TO_PAGES (CpuStatus->PackageCount * sizeof (UINT32) + CpuStatus->PackageCount * CpuStatus->MaxCoreCount * sizeof (UINT32));
304 FirstCore = AllocatePages (Pages);
305 if (FirstCore == NULL) {
306 ASSERT (FirstCore != NULL);
307 goto ExitOnError;
308 }
309
310 FirstThread = FirstCore + CpuStatus->PackageCount;
311
312 //
313 // Set FirstPackage, FirstCore[], FirstThread[] to maximum package ID, core ID, thread ID.
314 //
315 FirstPackage = MAX_UINT32;
316 SetMem32 (FirstCore, CpuStatus->PackageCount * sizeof (UINT32), MAX_UINT32);
317 SetMem32 (FirstThread, CpuStatus->PackageCount * CpuStatus->MaxCoreCount * sizeof (UINT32), MAX_UINT32);
318
319 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
320 Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;
321
322 //
323 // Save the minimum package ID in the platform.
324 //
325 FirstPackage = MIN (Location->Package, FirstPackage);
326
327 //
328 // Save the minimum core ID per package.
329 //
330 FirstCore[Location->Package] = MIN (Location->Core, FirstCore[Location->Package]);
331
332 //
333 // Save the minimum thread ID per core.
334 //
335 FirstThread[Location->Package * CpuStatus->MaxCoreCount + Location->Core] = MIN (
336 Location->Thread,
337 FirstThread[Location->Package * CpuStatus->MaxCoreCount + Location->Core]
338 );
339 }
340
341 //
342 // Update the First field.
343 //
344 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
345 Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;
346
347 if (Location->Package == FirstPackage) {
348 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Package = 1;
349 }
350
351 //
352 // Set First.Die/Tile/Module for each thread assuming:
353 // single Die under each package, single Tile under each Die, single Module under each Tile
354 //
355 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Die = 1;
356 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Tile = 1;
357 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Module = 1;
358
359 if (Location->Core == FirstCore[Location->Package]) {
360 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Core = 1;
361 }
362
363 if (Location->Thread == FirstThread[Location->Package * CpuStatus->MaxCoreCount + Location->Core]) {
364 CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Thread = 1;
365 }
366 }
367
368 FreePages (FirstCore, Pages);
369
370 return;
371
372ExitOnError:
373 if (FirstCore != NULL) {
374 FreePages (FirstCore, Pages);
375 }
376
377 if ((CpuFeaturesData != NULL) && (CpuFeaturesData->CpuFlags.PackageSemaphoreCount != NULL)) {
378 FreePool ((VOID *)CpuFeaturesData->CpuFlags.PackageSemaphoreCount);
379 CpuFeaturesData->CpuFlags.PackageSemaphoreCount = NULL;
380 }
381
382 if ((CpuFeaturesData != NULL) && (CpuFeaturesData->CpuFlags.CoreSemaphoreCount != NULL)) {
383 FreePool ((VOID *)CpuFeaturesData->CpuFlags.CoreSemaphoreCount);
384 CpuFeaturesData->CpuFlags.CoreSemaphoreCount = NULL;
385 }
386
387 if ((ThreadCountPerCore != NULL) && (CpuStatus != NULL)) {
388 FreePages (
389 ThreadCountPerCore,
390 EFI_SIZE_TO_PAGES (sizeof (UINT8) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount)
391 );
392 }
393
394 if ((ThreadCountPerPackage != NULL) && (CpuStatus != NULL)) {
395 FreePages (
396 ThreadCountPerPackage,
397 EFI_SIZE_TO_PAGES (sizeof (UINT32) * CpuStatus->PackageCount)
398 );
399 }
400
401 if (InitOrder != NULL) {
402 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
403 InitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber];
404 if (InitOrder->FeaturesSupportedMask != NULL) {
405 FreePool (InitOrder->FeaturesSupportedMask);
406 InitOrder->FeaturesSupportedMask = NULL;
407 }
408 }
409 }
410
411 if (Location != NULL) {
412 FreePages (Location, EFI_SIZE_TO_PAGES (sizeof (EFI_CPU_PHYSICAL_LOCATION) * NumberOfCpus));
413 }
414
415 if (CpuFeaturesData->InitOrder != NULL) {
416 FreePages (CpuFeaturesData->InitOrder, EFI_SIZE_TO_PAGES (sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus));
417 CpuFeaturesData->InitOrder = NULL;
418 }
419
420 if (CpuStatus != NULL) {
421 CopyMem (CpuStatus, &CpuStatusBackupBuffer, sizeof (*CpuStatus));
422 }
423}
424
433VOID
435 IN UINT8 *SupportedFeatureMask,
436 IN UINT8 *OrFeatureBitMask,
437 IN UINT32 BitMaskSize
438 )
439{
440 UINTN Index;
441 UINT8 *Data1;
442 UINT8 *Data2;
443
444 Data1 = SupportedFeatureMask;
445 Data2 = OrFeatureBitMask;
446 for (Index = 0; Index < BitMaskSize; Index++) {
447 *(Data1++) |= *(Data2++);
448 }
449}
450
459VOID
461 IN UINT8 *SupportedFeatureMask,
462 IN CONST UINT8 *AndFeatureBitMask,
463 IN UINT32 BitMaskSize
464 )
465{
466 UINTN Index;
467 UINT8 *Data1;
468 CONST UINT8 *Data2;
469
470 Data1 = SupportedFeatureMask;
471 Data2 = AndFeatureBitMask;
472 for (Index = 0; Index < BitMaskSize; Index++) {
473 *(Data1++) &= *(Data2++);
474 }
475}
476
484VOID
486 IN UINT8 *SupportedFeatureMask,
487 IN UINT8 *AndFeatureBitMask,
488 IN UINT32 BitMaskSize
489 )
490{
491 UINTN Index;
492 UINT8 *Data1;
493 UINT8 *Data2;
494
495 Data1 = SupportedFeatureMask;
496 Data2 = AndFeatureBitMask;
497 for (Index = 0; Index < BitMaskSize; Index++) {
498 *(Data1++) &= ~(*(Data2++));
499 }
500}
501
515BOOLEAN
517 IN UINT8 *SupportedFeatureMask,
518 IN UINT8 *ComparedFeatureBitMask,
519 IN UINT32 BitMaskSize
520 )
521{
522 UINTN Index;
523 UINT8 *Data1;
524 UINT8 *Data2;
525
526 Data1 = SupportedFeatureMask;
527 Data2 = ComparedFeatureBitMask;
528 for (Index = 0; Index < BitMaskSize; Index++) {
529 if (((*(Data1++)) & (*(Data2++))) != 0) {
530 return TRUE;
531 }
532 }
533
534 return FALSE;
535}
536
542VOID
543EFIAPI
545 IN OUT VOID *Buffer
546 )
547{
548 UINTN ProcessorNumber;
549 CPU_FEATURES_ENTRY *CpuFeature;
551 LIST_ENTRY *Entry;
552 CPU_FEATURES_DATA *CpuFeaturesData;
553
554 CpuFeaturesData = (CPU_FEATURES_DATA *)Buffer;
555 ProcessorNumber = GetProcessorIndex (CpuFeaturesData);
556 CpuInfo = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo;
557 //
558 // collect processor information
559 //
560 FillProcessorInfo (CpuInfo);
561 Entry = GetFirstNode (&CpuFeaturesData->FeatureList);
562 while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
563 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
564 if (CpuFeature->SupportFunc == NULL) {
565 //
566 // If SupportFunc is NULL, then the feature is supported.
567 //
569 CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask,
570 CpuFeature->FeatureMask,
571 CpuFeaturesData->BitMaskSize
572 );
573 } else if (CpuFeature->SupportFunc (ProcessorNumber, CpuInfo, CpuFeature->ConfigData)) {
575 CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask,
576 CpuFeature->FeatureMask,
577 CpuFeaturesData->BitMaskSize
578 );
579 }
580
581 Entry = Entry->ForwardLink;
582 }
583}
584
592VOID
594 IN UINTN ProcessorNumber
595 )
596{
597 CPU_FEATURES_DATA *CpuFeaturesData;
598 UINTN FeatureIndex;
599 CPU_REGISTER_TABLE *RegisterTable;
600 CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
601 CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead;
602 UINT32 DebugPrintErrorLevel;
603
604 DebugPrintErrorLevel = (ProcessorNumber == 0) ? DEBUG_INFO : DEBUG_VERBOSE;
605 CpuFeaturesData = GetCpuFeaturesData ();
606 //
607 // Debug information
608 //
609 RegisterTable = &CpuFeaturesData->RegisterTable[ProcessorNumber];
610 DEBUG ((DebugPrintErrorLevel, "RegisterTable->TableLength = %d\n", RegisterTable->TableLength));
611
612 RegisterTableEntryHead = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry;
613
614 for (FeatureIndex = 0; FeatureIndex < RegisterTable->TableLength; FeatureIndex++) {
615 RegisterTableEntry = &RegisterTableEntryHead[FeatureIndex];
616 switch (RegisterTableEntry->RegisterType) {
617 case Msr:
618 DEBUG ((
619 DebugPrintErrorLevel,
620 "Processor: %04d: Index %04d, MSR : %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",
621 (UINT32)ProcessorNumber,
622 (UINT32)FeatureIndex,
623 RegisterTableEntry->Index,
624 RegisterTableEntry->ValidBitStart,
625 RegisterTableEntry->ValidBitLength,
626 RegisterTableEntry->Value
627 ));
628 break;
629 case ControlRegister:
630 DEBUG ((
631 DebugPrintErrorLevel,
632 "Processor: %04d: Index %04d, CR : %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",
633 (UINT32)ProcessorNumber,
634 (UINT32)FeatureIndex,
635 RegisterTableEntry->Index,
636 RegisterTableEntry->ValidBitStart,
637 RegisterTableEntry->ValidBitLength,
638 RegisterTableEntry->Value
639 ));
640 break;
641 case MemoryMapped:
642 DEBUG ((
643 DebugPrintErrorLevel,
644 "Processor: %04d: Index %04d, MMIO : %016lx, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",
645 (UINT32)ProcessorNumber,
646 (UINT32)FeatureIndex,
647 RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32),
648 RegisterTableEntry->ValidBitStart,
649 RegisterTableEntry->ValidBitLength,
650 RegisterTableEntry->Value
651 ));
652 break;
653 case CacheControl:
654 DEBUG ((
655 DebugPrintErrorLevel,
656 "Processor: %04d: Index %04d, CACHE: %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",
657 (UINT32)ProcessorNumber,
658 (UINT32)FeatureIndex,
659 RegisterTableEntry->Index,
660 RegisterTableEntry->ValidBitStart,
661 RegisterTableEntry->ValidBitLength,
662 RegisterTableEntry->Value
663 ));
664 break;
665 case Semaphore:
666 DEBUG ((
667 DebugPrintErrorLevel,
668 "Processor: %04d: Index %04d, SEMAP: %s\r\n",
669 (UINT32)ProcessorNumber,
670 (UINT32)FeatureIndex,
671 mDependTypeStr[MIN ((UINT32)RegisterTableEntry->Value, InvalidDepType)]
672 ));
673 break;
674
675 default:
676 break;
677 }
678 }
679}
680
692CPU_FEATURE_DEPENDENCE_TYPE
694 IN CPU_FEATURE_DEPENDENCE_TYPE BeforeDep,
695 IN CPU_FEATURE_DEPENDENCE_TYPE AfterDep,
696 IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep,
697 IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep
698 )
699{
700 CPU_FEATURE_DEPENDENCE_TYPE Bigger;
701
702 Bigger = MAX (BeforeDep, AfterDep);
703 Bigger = MAX (Bigger, NoneNeibBeforeDep);
704 return MAX (Bigger, NoneNeibAfterDep);
705}
706
713VOID
715 IN UINTN NumberOfCpus
716 )
717{
718 EFI_STATUS Status;
719 UINTN ProcessorNumber;
720 CPU_FEATURES_ENTRY *CpuFeature;
721 CPU_FEATURES_ENTRY *CpuFeatureInOrder;
722 CPU_FEATURES_INIT_ORDER *CpuInitOrder;
724 LIST_ENTRY *Entry;
725 CPU_FEATURES_DATA *CpuFeaturesData;
726 LIST_ENTRY *NextEntry;
727 CPU_FEATURES_ENTRY *NextCpuFeatureInOrder;
728 BOOLEAN Success;
729 CPU_FEATURE_DEPENDENCE_TYPE BeforeDep;
730 CPU_FEATURE_DEPENDENCE_TYPE AfterDep;
731 CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep;
732 CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep;
733
734 CpuFeaturesData = GetCpuFeaturesData ();
735 CpuFeaturesData->CapabilityPcd = AllocatePool (CpuFeaturesData->BitMaskSize);
736 ASSERT (CpuFeaturesData->CapabilityPcd != NULL);
737 SetMem (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize, 0xFF);
738 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
739 CpuInitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber];
740 //
741 // Calculate the last capability on all processors
742 //
743 SupportedMaskAnd (CpuFeaturesData->CapabilityPcd, CpuInitOrder->FeaturesSupportedMask, CpuFeaturesData->BitMaskSize);
744 }
745
746 //
747 // Calculate the last setting
748 //
749 CpuFeaturesData->SettingPcd = AllocateCopyPool (CpuFeaturesData->BitMaskSize, CpuFeaturesData->CapabilityPcd);
750 ASSERT (CpuFeaturesData->SettingPcd != NULL);
751 SupportedMaskAnd (CpuFeaturesData->SettingPcd, PcdGetPtr (PcdCpuFeaturesSetting), CpuFeaturesData->BitMaskSize);
752
753 //
754 // Dump the last CPU feature list
755 //
757 DEBUG ((DEBUG_INFO, "Last CPU features list...\n"));
758 Entry = GetFirstNode (&CpuFeaturesData->FeatureList);
759 while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
760 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
761 if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize)) {
762 if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize)) {
763 DEBUG ((DEBUG_INFO, "[Enable ] "));
764 } else {
765 DEBUG ((DEBUG_INFO, "[Disable ] "));
766 }
767 } else {
768 DEBUG ((DEBUG_INFO, "[Unsupport] "));
769 }
770
771 DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);
772 Entry = Entry->ForwardLink;
773 }
774
775 DEBUG ((DEBUG_INFO, "PcdCpuFeaturesCapability:\n"));
776 DumpCpuFeatureMask (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize);
777 DEBUG ((DEBUG_INFO, "Origin PcdCpuFeaturesSetting:\n"));
778 DumpCpuFeatureMask (PcdGetPtr (PcdCpuFeaturesSetting), CpuFeaturesData->BitMaskSize);
779 DEBUG ((DEBUG_INFO, "Final PcdCpuFeaturesSetting:\n"));
780 DumpCpuFeatureMask (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize);
782
783 //
784 // Save PCDs and display CPU PCDs
785 //
786 SetCapabilityPcd (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize);
787 SetSettingPcd (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize);
788
789 for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
790 CpuInitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber];
791 Entry = GetFirstNode (&CpuFeaturesData->FeatureList);
792 while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
793 //
794 // Insert each feature into processor's order list
795 //
796 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
797 if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize)) {
798 CpuFeatureInOrder = AllocateCopyPool (sizeof (CPU_FEATURES_ENTRY), CpuFeature);
799 ASSERT (CpuFeatureInOrder != NULL);
800 InsertTailList (&CpuInitOrder->OrderList, &CpuFeatureInOrder->Link);
801 }
802
803 Entry = Entry->ForwardLink;
804 }
805
806 //
807 // Go through ordered feature list to initialize CPU features
808 //
809 CpuInfo = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo;
810 Entry = GetFirstNode (&CpuInitOrder->OrderList);
811 while (!IsNull (&CpuInitOrder->OrderList, Entry)) {
812 CpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
813
814 Success = FALSE;
815 if (IsBitMaskMatch (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize)) {
816 Status = CpuFeatureInOrder->InitializeFunc (ProcessorNumber, CpuInfo, CpuFeatureInOrder->ConfigData, TRUE);
817 if (EFI_ERROR (Status)) {
818 //
819 // Clean the CpuFeatureInOrder->FeatureMask in setting PCD.
820 //
821 SupportedMaskCleanBit (CpuFeaturesData->SettingPcd, CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize);
822 if (CpuFeatureInOrder->FeatureName != NULL) {
823 DEBUG ((DEBUG_WARN, "Warning :: Failed to enable Feature: Name = %a.\n", CpuFeatureInOrder->FeatureName));
824 } else {
825 DEBUG ((DEBUG_WARN, "Warning :: Failed to enable Feature: Mask = "));
826 DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize);
827 }
828 } else {
829 Success = TRUE;
830 }
831 } else {
832 Status = CpuFeatureInOrder->InitializeFunc (ProcessorNumber, CpuInfo, CpuFeatureInOrder->ConfigData, FALSE);
833 if (EFI_ERROR (Status)) {
834 if (CpuFeatureInOrder->FeatureName != NULL) {
835 DEBUG ((DEBUG_WARN, "Warning :: Failed to disable Feature: Name = %a.\n", CpuFeatureInOrder->FeatureName));
836 } else {
837 DEBUG ((DEBUG_WARN, "Warning :: Failed to disable Feature: Mask = "));
838 DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize);
839 }
840 } else {
841 Success = TRUE;
842 }
843 }
844
845 if (Success) {
846 NextEntry = Entry->ForwardLink;
847 if (!IsNull (&CpuInitOrder->OrderList, NextEntry)) {
848 NextCpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry);
849
850 //
851 // If feature has dependence with the next feature (ONLY care core/package dependency).
852 // and feature initialize succeed, add sync semaphere here.
853 //
854 BeforeDep = DetectFeatureScope (CpuFeatureInOrder, TRUE, NextCpuFeatureInOrder->FeatureMask);
855 AfterDep = DetectFeatureScope (NextCpuFeatureInOrder, FALSE, CpuFeatureInOrder->FeatureMask);
856 //
857 // Check whether next feature has After type dependence with not neighborhood CPU
858 // Features in former CPU features.
859 //
860 NoneNeibAfterDep = DetectNoneNeighborhoodFeatureScope (NextCpuFeatureInOrder, FALSE, &CpuInitOrder->OrderList);
861 } else {
862 BeforeDep = NoneDepType;
863 AfterDep = NoneDepType;
864 NoneNeibAfterDep = NoneDepType;
865 }
866
867 //
868 // Check whether current feature has Before type dependence with none neighborhood
869 // CPU features in after Cpu features.
870 //
871 NoneNeibBeforeDep = DetectNoneNeighborhoodFeatureScope (CpuFeatureInOrder, TRUE, &CpuInitOrder->OrderList);
872
873 //
874 // Get the biggest dependence and add semaphore for it.
875 // PackageDepType > CoreDepType > ThreadDepType > NoneDepType.
876 //
877 BeforeDep = BiggestDep (BeforeDep, AfterDep, NoneNeibBeforeDep, NoneNeibAfterDep);
878 if (BeforeDep > ThreadDepType) {
879 CPU_REGISTER_TABLE_WRITE32 (ProcessorNumber, Semaphore, 0, BeforeDep);
880 }
881 }
882
883 Entry = Entry->ForwardLink;
884 }
885
886 //
887 // Dump PcdCpuFeaturesSetting again because this value maybe updated
888 // again during initialize the features.
889 //
890 DEBUG ((DEBUG_INFO, "Dump final value for PcdCpuFeaturesSetting:\n"));
891 DumpCpuFeatureMask (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize);
892
893 //
894 // Dump the RegisterTable
895 //
896 DumpRegisterTableOnProcessor (ProcessorNumber);
897 }
898}
899
906VOID
908 IN OUT volatile UINT32 *Sem
909 )
910{
912}
913
924VOID
926 IN OUT volatile UINT32 *Sem
927 )
928{
929 UINT32 Value;
930
931 do {
932 Value = *Sem;
933 } while (Value == 0 ||
935 Sem,
936 Value,
937 Value - 1
938 ) != Value);
939}
940
950UINTN
952 IN UINT32 CrIndex,
953 IN BOOLEAN Read,
954 IN OUT UINTN *CrValue
955 )
956{
957 switch (CrIndex) {
958 case 0:
959 if (Read) {
960 *CrValue = AsmReadCr0 ();
961 } else {
962 AsmWriteCr0 (*CrValue);
963 }
964
965 break;
966 case 2:
967 if (Read) {
968 *CrValue = AsmReadCr2 ();
969 } else {
970 AsmWriteCr2 (*CrValue);
971 }
972
973 break;
974 case 3:
975 if (Read) {
976 *CrValue = AsmReadCr3 ();
977 } else {
978 AsmWriteCr3 (*CrValue);
979 }
980
981 break;
982 case 4:
983 if (Read) {
984 *CrValue = AsmReadCr4 ();
985 } else {
986 AsmWriteCr4 (*CrValue);
987 }
988
989 break;
990 default:
991 return EFI_UNSUPPORTED;
992 }
993
994 return EFI_SUCCESS;
995}
996
1007VOID
1009 IN CPU_REGISTER_TABLE *RegisterTable,
1010 IN EFI_CPU_PHYSICAL_LOCATION *ApLocation,
1011 IN CPU_STATUS_INFORMATION *CpuStatus,
1013 )
1014{
1015 CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
1016 UINTN Index;
1017 UINTN Value;
1018 CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead;
1019 volatile UINT32 *SemaphorePtr;
1020 UINT32 FirstThread;
1021 UINT32 CurrentThread;
1022 UINT32 CurrentCore;
1023 UINTN ProcessorIndex;
1024 UINT32 *ThreadCountPerPackage;
1025 UINT8 *ThreadCountPerCore;
1026 EFI_STATUS Status;
1027 UINT64 CurrentValue;
1028
1029 //
1030 // Traverse Register Table of this logical processor
1031 //
1032 RegisterTableEntryHead = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry;
1033
1034 for (Index = 0; Index < RegisterTable->TableLength; Index++) {
1035 RegisterTableEntry = &RegisterTableEntryHead[Index];
1036
1037 //
1038 // Check the type of specified register
1039 //
1040 switch (RegisterTableEntry->RegisterType) {
1041 //
1042 // The specified register is Control Register
1043 //
1044 case ControlRegister:
1045 Status = ReadWriteCr (RegisterTableEntry->Index, TRUE, &Value);
1046 if (EFI_ERROR (Status)) {
1047 break;
1048 }
1049
1050 if (RegisterTableEntry->TestThenWrite) {
1051 CurrentValue = BitFieldRead64 (
1052 Value,
1053 RegisterTableEntry->ValidBitStart,
1054 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1
1055 );
1056 if (CurrentValue == RegisterTableEntry->Value) {
1057 break;
1058 }
1059 }
1060
1061 Value = (UINTN)BitFieldWrite64 (
1062 Value,
1063 RegisterTableEntry->ValidBitStart,
1064 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
1065 RegisterTableEntry->Value
1066 );
1067 ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value);
1068 break;
1069
1070 //
1071 // The specified register is Model Specific Register
1072 //
1073 case Msr:
1074 if (RegisterTableEntry->TestThenWrite) {
1075 Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index);
1076 if (RegisterTableEntry->ValidBitLength >= 64) {
1077 if (Value == RegisterTableEntry->Value) {
1078 break;
1079 }
1080 } else {
1081 CurrentValue = BitFieldRead64 (
1082 Value,
1083 RegisterTableEntry->ValidBitStart,
1084 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1
1085 );
1086 if (CurrentValue == RegisterTableEntry->Value) {
1087 break;
1088 }
1089 }
1090 }
1091
1092 if (RegisterTableEntry->ValidBitLength >= 64) {
1093 //
1094 // If length is not less than 64 bits, then directly write without reading
1095 //
1097 RegisterTableEntry->Index,
1098 RegisterTableEntry->Value
1099 );
1100 } else {
1101 //
1102 // Set the bit section according to bit start and length
1103 //
1105 RegisterTableEntry->Index,
1106 RegisterTableEntry->ValidBitStart,
1107 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
1108 RegisterTableEntry->Value
1109 );
1110 }
1111
1112 break;
1113 //
1114 // MemoryMapped operations
1115 //
1116 case MemoryMapped:
1117 AcquireSpinLock (&CpuFlags->MemoryMappedLock);
1119 (UINTN)(RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32)),
1120 RegisterTableEntry->ValidBitStart,
1121 RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
1122 (UINT32)RegisterTableEntry->Value
1123 );
1124 ReleaseSpinLock (&CpuFlags->MemoryMappedLock);
1125 break;
1126 //
1127 // Enable or disable cache
1128 //
1129 case CacheControl:
1130 //
1131 // If value of the entry is 0, then disable cache. Otherwise, enable cache.
1132 //
1133 if (RegisterTableEntry->Value == 0) {
1134 AsmDisableCache ();
1135 } else {
1136 AsmEnableCache ();
1137 }
1138
1139 break;
1140
1141 case Semaphore:
1142 // Semaphore works logic like below:
1143 //
1144 // V(x) = LibReleaseSemaphore (Semaphore[FirstThread + x]);
1145 // P(x) = LibWaitForSemaphore (Semaphore[FirstThread + x]);
1146 //
1147 // All threads (T0...Tn) waits in P() line and continues running
1148 // together.
1149 //
1150 //
1151 // T0 T1 ... Tn
1152 //
1153 // V(0...n) V(0...n) ... V(0...n)
1154 // n * P(0) n * P(1) ... n * P(n)
1155 //
1156 switch (RegisterTableEntry->Value) {
1157 case CoreDepType:
1158 SemaphorePtr = CpuFlags->CoreSemaphoreCount;
1159 ThreadCountPerCore = (UINT8 *)(UINTN)CpuStatus->ThreadCountPerCore;
1160
1161 CurrentCore = ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core;
1162 //
1163 // Get Offset info for the first thread in the core which current thread belongs to.
1164 //
1165 FirstThread = CurrentCore * CpuStatus->MaxThreadCount;
1166 CurrentThread = FirstThread + ApLocation->Thread;
1167
1168 //
1169 // Different cores may have different valid threads in them. If driver maintail clearly
1170 // thread index in different cores, the logic will be much complicated.
1171 // Here driver just simply records the max thread number in all cores and use it as expect
1172 // thread number for all cores.
1173 // In below two steps logic, first current thread will Release semaphore for each thread
1174 // in current core. Maybe some threads are not valid in this core, but driver don't
1175 // care. Second, driver will let current thread wait semaphore for all valid threads in
1176 // current core. Because only the valid threads will do release semaphore for this
1177 // thread, driver here only need to wait the valid thread count.
1178 //
1179
1180 //
1181 // First Notify ALL THREADs in current Core that this thread is ready.
1182 //
1183 for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex++) {
1184 LibReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
1185 }
1186
1187 //
1188 // Second, check whether all VALID THREADs (not all threads) in current core are ready.
1189 //
1190 for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerCore[CurrentCore]; ProcessorIndex++) {
1191 LibWaitForSemaphore (&SemaphorePtr[CurrentThread]);
1192 }
1193
1194 break;
1195
1196 case PackageDepType:
1197 SemaphorePtr = CpuFlags->PackageSemaphoreCount;
1198 ThreadCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ThreadCountPerPackage;
1199 //
1200 // Get Offset info for the first thread in the package which current thread belongs to.
1201 //
1202 FirstThread = ApLocation->Package * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount;
1203 //
1204 // Get the possible threads count for current package.
1205 //
1206 CurrentThread = FirstThread + CpuStatus->MaxThreadCount * ApLocation->Core + ApLocation->Thread;
1207
1208 //
1209 // Different packages may have different valid threads in them. If driver maintail clearly
1210 // thread index in different packages, the logic will be much complicated.
1211 // Here driver just simply records the max thread number in all packages and use it as expect
1212 // thread number for all packages.
1213 // In below two steps logic, first current thread will Release semaphore for each thread
1214 // in current package. Maybe some threads are not valid in this package, but driver don't
1215 // care. Second, driver will let current thread wait semaphore for all valid threads in
1216 // current package. Because only the valid threads will do release semaphore for this
1217 // thread, driver here only need to wait the valid thread count.
1218 //
1219
1220 //
1221 // First Notify ALL THREADS in current package that this thread is ready.
1222 //
1223 for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount; ProcessorIndex++) {
1224 LibReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
1225 }
1226
1227 //
1228 // Second, check whether VALID THREADS (not all threads) in current package are ready.
1229 //
1230 for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerPackage[ApLocation->Package]; ProcessorIndex++) {
1231 LibWaitForSemaphore (&SemaphorePtr[CurrentThread]);
1232 }
1233
1234 break;
1235
1236 default:
1237 break;
1238 }
1239
1240 break;
1241
1242 default:
1243 break;
1244 }
1245 }
1246}
1247
1254VOID
1255EFIAPI
1257 IN OUT VOID *Buffer
1258 )
1259{
1260 CPU_FEATURES_DATA *CpuFeaturesData;
1261 CPU_REGISTER_TABLE *RegisterTable;
1262 CPU_REGISTER_TABLE *RegisterTables;
1263 UINT32 InitApicId;
1264 UINTN ProcIndex;
1265 UINTN Index;
1266 ACPI_CPU_DATA *AcpiCpuData;
1267
1268 CpuFeaturesData = (CPU_FEATURES_DATA *)Buffer;
1269 AcpiCpuData = CpuFeaturesData->AcpiCpuData;
1270
1271 RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.RegisterTable;
1272
1273 InitApicId = GetInitialApicId ();
1274 RegisterTable = NULL;
1275 ProcIndex = (UINTN)-1;
1276 for (Index = 0; Index < AcpiCpuData->NumberOfCpus; Index++) {
1277 if (RegisterTables[Index].InitialApicId == InitApicId) {
1278 RegisterTable = &RegisterTables[Index];
1279 ProcIndex = Index;
1280 break;
1281 }
1282 }
1283
1284 ASSERT (RegisterTable != NULL);
1285
1287 RegisterTable,
1288 (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)AcpiCpuData->CpuFeatureInitData.ApLocation + ProcIndex,
1289 &AcpiCpuData->CpuFeatureInitData.CpuStatus,
1290 &CpuFeaturesData->CpuFlags
1291 );
1292}
1293
1302VOID
1303EFIAPI
1305 VOID
1306 )
1307{
1308 CPU_FEATURES_DATA *CpuFeaturesData;
1309
1310 CpuFeaturesData = GetCpuFeaturesData ();
1311
1313
1314 if (CpuFeaturesData->NumberOfCpus > 1) {
1315 //
1316 // Wakeup all APs for data collection.
1317 //
1319 }
1320
1321 //
1322 // Collect data on BSP
1323 //
1324 CollectProcessorData (CpuFeaturesData);
1325
1326 AnalysisProcessorFeatures (CpuFeaturesData->NumberOfCpus);
1327}
UINT64 UINTN
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)
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 FreePool(IN VOID *Buffer)
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 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
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#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