TianoCore EDK2 master
Loading...
Searching...
No Matches
RegisterCpuFeaturesLib.c
Go to the documentation of this file.
1
10
18VOID
20 IN UINT8 *FeatureMask,
21 IN UINT32 BitMaskSize
22 )
23{
24 UINTN Index;
25 UINT8 *Data8;
26
27 Data8 = (UINT8 *)FeatureMask;
28 for (Index = 0; Index < BitMaskSize; Index++) {
29 DEBUG ((DEBUG_INFO, " %02x ", *Data8++));
30 }
31
32 DEBUG ((DEBUG_INFO, "\n"));
33}
34
42VOID
44 IN CPU_FEATURES_ENTRY *CpuFeature,
45 IN UINT32 BitMaskSize
46 )
47{
48 if (CpuFeature->FeatureName != NULL) {
49 DEBUG ((DEBUG_INFO, "FeatureName: %a\n", CpuFeature->FeatureName));
50 } else {
51 DEBUG ((DEBUG_INFO, "FeatureMask = "));
52 DumpCpuFeatureMask (CpuFeature->FeatureMask, BitMaskSize);
53 }
54}
55
65BOOLEAN
67 IN UINT8 *FeatureMask,
68 IN UINT8 *DependentBitMask
69 )
70{
71 UINTN Index;
72 UINT8 *Data1;
73 UINT8 *Data2;
74 CPU_FEATURES_DATA *CpuFeaturesData;
75
76 CpuFeaturesData = GetCpuFeaturesData ();
77
78 Data1 = FeatureMask;
79 Data2 = DependentBitMask;
80 for (Index = 0; Index < CpuFeaturesData->BitMaskSize; Index++) {
81 if (((*(Data1++)) & (*(Data2++))) != 0) {
82 return TRUE;
83 }
84 }
85
86 return FALSE;
87}
88
100BOOLEAN
102 IN LIST_ENTRY *FeatureList,
103 IN LIST_ENTRY *CurrentEntry,
104 IN BOOLEAN SearchFormer,
105 IN UINT8 *FeatureMask
106 )
107{
108 CPU_FEATURES_ENTRY *CpuFeature;
109 LIST_ENTRY *NextEntry;
110
111 //
112 // Check whether exist the not neighborhood entry first.
113 // If not exist, return FALSE means not found status.
114 //
115 if (SearchFormer) {
116 NextEntry = CurrentEntry->BackLink;
117 if (IsNull (FeatureList, NextEntry)) {
118 return FALSE;
119 }
120
121 NextEntry = NextEntry->BackLink;
122 if (IsNull (FeatureList, NextEntry)) {
123 return FALSE;
124 }
125
126 NextEntry = CurrentEntry->BackLink->BackLink;
127 } else {
128 NextEntry = CurrentEntry->ForwardLink;
129 if (IsNull (FeatureList, NextEntry)) {
130 return FALSE;
131 }
132
133 NextEntry = NextEntry->ForwardLink;
134 if (IsNull (FeatureList, NextEntry)) {
135 return FALSE;
136 }
137
138 NextEntry = CurrentEntry->ForwardLink->ForwardLink;
139 }
140
141 while (!IsNull (FeatureList, NextEntry)) {
142 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry);
143
144 if (IsBitMaskMatchCheck (FeatureMask, CpuFeature->FeatureMask)) {
145 return TRUE;
146 }
147
148 if (SearchFormer) {
149 NextEntry = NextEntry->BackLink;
150 } else {
151 NextEntry = NextEntry->ForwardLink;
152 }
153 }
154
155 return FALSE;
156}
157
167CPU_FEATURE_DEPENDENCE_TYPE
169 IN CPU_FEATURES_ENTRY *CpuFeature,
170 IN BOOLEAN Before,
171 IN UINT8 *NextCpuFeatureMask
172 )
173{
174 //
175 // if need to check before type dependence but the feature after current feature is not
176 // exist, means this before type dependence not valid, just return NoneDepType.
177 // Just like Feature A has a dependence of feature B, but Feature B not installed, so
178 // Feature A maybe insert to the last entry of the list. In this case, for below code,
179 // Featrure A has depend of feature B, but it is the last entry of the list, so the
180 // NextCpuFeatureMask is NULL, so the dependence for feature A here is useless and code
181 // just return NoneDepType.
182 //
183 if (NextCpuFeatureMask == NULL) {
184 return NoneDepType;
185 }
186
187 if (Before) {
188 if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) &&
189 IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageBeforeFeatureBitMask))
190 {
191 return PackageDepType;
192 }
193
194 if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&
195 IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreBeforeFeatureBitMask))
196 {
197 return CoreDepType;
198 }
199
200 if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&
201 IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadBeforeFeatureBitMask))
202 {
203 return ThreadDepType;
204 }
205
206 return NoneDepType;
207 }
208
209 if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&
210 IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageAfterFeatureBitMask))
211 {
212 return PackageDepType;
213 }
214
215 if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&
216 IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreAfterFeatureBitMask))
217 {
218 return CoreDepType;
219 }
220
221 if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&
222 IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadAfterFeatureBitMask))
223 {
224 return ThreadDepType;
225 }
226
227 return NoneDepType;
228}
229
239CPU_FEATURE_DEPENDENCE_TYPE
241 IN CPU_FEATURES_ENTRY *CpuFeature,
242 IN BOOLEAN Before,
243 IN LIST_ENTRY *FeatureList
244 )
245{
246 if (Before) {
247 if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) &&
248 FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->PackageBeforeFeatureBitMask))
249 {
250 return PackageDepType;
251 }
252
253 if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&
254 FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->CoreBeforeFeatureBitMask))
255 {
256 return CoreDepType;
257 }
258
259 if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&
260 FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->ThreadBeforeFeatureBitMask))
261 {
262 return ThreadDepType;
263 }
264
265 return NoneDepType;
266 }
267
268 if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&
269 FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->PackageAfterFeatureBitMask))
270 {
271 return PackageDepType;
272 }
273
274 if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&
275 FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->CoreAfterFeatureBitMask))
276 {
277 return CoreDepType;
278 }
279
280 if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&
281 FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->ThreadAfterFeatureBitMask))
282 {
283 return ThreadDepType;
284 }
285
286 return NoneDepType;
287}
288
308BOOLEAN
310 IN OUT CPU_FEATURES_ENTRY *PreviousFeature,
311 IN OUT CPU_FEATURES_ENTRY *CurrentFeature,
312 IN CPU_FEATURES_ENTRY *FindFeature,
313 IN BOOLEAN Before
314 )
315{
316 CPU_FEATURE_DEPENDENCE_TYPE PreDependType;
317 CPU_FEATURE_DEPENDENCE_TYPE CurrentDependType;
318
319 PreDependType = DetectFeatureScope (PreviousFeature, Before, FindFeature->FeatureMask);
320 CurrentDependType = DetectFeatureScope (CurrentFeature, Before, FindFeature->FeatureMask);
321
322 //
323 // If previous feature has no dependence with the find featue.
324 // return FALSE.
325 //
326 if (PreDependType == NoneDepType) {
327 return FALSE;
328 }
329
330 //
331 // If both feature have dependence, keep the one which needs use more
332 // processors and clear the dependence for the other one.
333 //
334 if (PreDependType >= CurrentDependType) {
335 return TRUE;
336 } else {
337 return FALSE;
338 }
339}
340
350VOID
352 IN LIST_ENTRY *FeatureList,
353 IN OUT LIST_ENTRY *FindEntry,
354 IN OUT LIST_ENTRY *CurrentEntry,
355 IN BOOLEAN Before
356 )
357{
358 LIST_ENTRY *PreviousEntry;
359 CPU_FEATURES_ENTRY *PreviousFeature;
360 CPU_FEATURES_ENTRY *CurrentFeature;
361 CPU_FEATURES_ENTRY *FindFeature;
362
363 //
364 // For CPU feature which has core or package type dependence, later code need to insert
365 // AcquireSpinLock/ReleaseSpinLock logic to sequency the execute order.
366 // So if driver finds both feature A and B need to execute before feature C, driver will
367 // base on dependence type of feature A and B to update the logic here.
368 // For example, feature A has package type dependence and feature B has core type dependence,
369 // because package type dependence need to wait for more processors which has strong dependence
370 // than core type dependence. So driver will adjust the feature order to B -> A -> C. and driver
371 // will remove the feature dependence in feature B.
372 // Driver just needs to make sure before feature C been executed, feature A has finished its task
373 // in all all thread. Feature A finished in all threads also means feature B have finshed in all
374 // threads.
375 //
376 if (Before) {
377 PreviousEntry = GetPreviousNode (FeatureList, FindEntry);
378 } else {
379 PreviousEntry = GetNextNode (FeatureList, FindEntry);
380 }
381
382 CurrentFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);
383 RemoveEntryList (CurrentEntry);
384
385 if (IsNull (FeatureList, PreviousEntry)) {
386 //
387 // If not exist the previous or next entry, just insert the current entry.
388 //
389 if (Before) {
390 InsertTailList (FindEntry, CurrentEntry);
391 } else {
392 InsertHeadList (FindEntry, CurrentEntry);
393 }
394 } else {
395 //
396 // If exist the previous or next entry, need to check it before insert curent entry.
397 //
398 PreviousFeature = CPU_FEATURE_ENTRY_FROM_LINK (PreviousEntry);
399 FindFeature = CPU_FEATURE_ENTRY_FROM_LINK (FindEntry);
400
401 if (AdjustFeaturesDependence (PreviousFeature, CurrentFeature, FindFeature, Before)) {
402 //
403 // Return TRUE means current feature dependence has been cleared and the previous
404 // feature dependence has been kept and used. So insert current feature before (or after)
405 // the previous feature.
406 //
407 if (Before) {
408 InsertTailList (PreviousEntry, CurrentEntry);
409 } else {
410 InsertHeadList (PreviousEntry, CurrentEntry);
411 }
412 } else {
413 if (Before) {
414 InsertTailList (FindEntry, CurrentEntry);
415 } else {
416 InsertHeadList (FindEntry, CurrentEntry);
417 }
418 }
419 }
420}
421
431BOOLEAN
433 IN LIST_ENTRY *FeatureList,
434 IN LIST_ENTRY *CurrentEntry,
435 IN UINT8 *FeatureMask
436 )
437{
438 LIST_ENTRY *CheckEntry;
439 CPU_FEATURES_ENTRY *CheckFeature;
440 BOOLEAN Swapped;
441
442 Swapped = FALSE;
443
444 //
445 // Check all features dispatched before this entry
446 //
447 CheckEntry = GetFirstNode (FeatureList);
448 while (CheckEntry != CurrentEntry) {
449 CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);
450 if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, FeatureMask)) {
451 AdjustEntry (FeatureList, CheckEntry, CurrentEntry, TRUE);
452 Swapped = TRUE;
453 break;
454 }
455
456 CheckEntry = CheckEntry->ForwardLink;
457 }
458
459 return Swapped;
460}
461
471BOOLEAN
473 IN LIST_ENTRY *FeatureList,
474 IN LIST_ENTRY *CurrentEntry,
475 IN UINT8 *FeatureMask
476 )
477{
478 LIST_ENTRY *CheckEntry;
479 CPU_FEATURES_ENTRY *CheckFeature;
480 BOOLEAN Swapped;
481
482 Swapped = FALSE;
483
484 //
485 // Check all features dispatched after this entry
486 //
487 CheckEntry = GetNextNode (FeatureList, CurrentEntry);
488 while (!IsNull (FeatureList, CheckEntry)) {
489 CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);
490 if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, FeatureMask)) {
491 AdjustEntry (FeatureList, CheckEntry, CurrentEntry, FALSE);
492 Swapped = TRUE;
493 break;
494 }
495
496 CheckEntry = CheckEntry->ForwardLink;
497 }
498
499 return Swapped;
500}
501
507VOID
509 IN LIST_ENTRY *FeatureList
510 )
511{
512 LIST_ENTRY *CurrentEntry;
513 CPU_FEATURES_ENTRY *CpuFeature;
514 LIST_ENTRY *CheckEntry;
515 CPU_FEATURES_ENTRY *CheckFeature;
516 BOOLEAN Swapped;
517 LIST_ENTRY *TempEntry;
518 LIST_ENTRY *NextEntry;
519
520 CurrentEntry = GetFirstNode (FeatureList);
521 while (!IsNull (FeatureList, CurrentEntry)) {
522 Swapped = FALSE;
523 CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);
524 NextEntry = CurrentEntry->ForwardLink;
525 if (CpuFeature->BeforeAll) {
526 //
527 // Check all features dispatched before this entry
528 //
529 CheckEntry = GetFirstNode (FeatureList);
530 while (CheckEntry != CurrentEntry) {
531 CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);
532 if (!CheckFeature->BeforeAll) {
533 //
534 // If this feature has no BeforeAll flag and is dispatched before CpuFeature,
535 // insert currentEntry before Checked feature
536 //
537 RemoveEntryList (CurrentEntry);
538 InsertTailList (CheckEntry, CurrentEntry);
539 Swapped = TRUE;
540 break;
541 }
542
543 CheckEntry = CheckEntry->ForwardLink;
544 }
545
546 if (Swapped) {
547 CurrentEntry = NextEntry;
548 continue;
549 }
550 }
551
552 if (CpuFeature->AfterAll) {
553 //
554 // Check all features dispatched after this entry
555 //
556 CheckEntry = GetNextNode (FeatureList, CurrentEntry);
557 while (!IsNull (FeatureList, CheckEntry)) {
558 CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);
559 if (!CheckFeature->AfterAll) {
560 //
561 // If this feature has no AfterAll flag and is dispatched after CpuFeature,
562 // insert currentEntry after Checked feature
563 //
564 TempEntry = GetNextNode (FeatureList, CurrentEntry);
565 RemoveEntryList (CurrentEntry);
566 InsertHeadList (CheckEntry, CurrentEntry);
567 CurrentEntry = TempEntry;
568 Swapped = TRUE;
569 break;
570 }
571
572 CheckEntry = CheckEntry->ForwardLink;
573 }
574
575 if (Swapped) {
576 CurrentEntry = NextEntry;
577 continue;
578 }
579 }
580
581 if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) {
582 Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->ThreadBeforeFeatureBitMask);
583 if (Swapped) {
584 continue;
585 }
586 }
587
588 if (CpuFeature->ThreadAfterFeatureBitMask != NULL) {
589 Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->ThreadAfterFeatureBitMask);
590 if (Swapped) {
591 continue;
592 }
593 }
594
595 if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {
596 Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->CoreBeforeFeatureBitMask);
597 if (Swapped) {
598 continue;
599 }
600 }
601
602 if (CpuFeature->CoreAfterFeatureBitMask != NULL) {
603 Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->CoreAfterFeatureBitMask);
604 if (Swapped) {
605 continue;
606 }
607 }
608
609 if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {
610 Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->PackageBeforeFeatureBitMask);
611 if (Swapped) {
612 continue;
613 }
614 }
615
616 if (CpuFeature->PackageAfterFeatureBitMask != NULL) {
617 Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->PackageAfterFeatureBitMask);
618 if (Swapped) {
619 continue;
620 }
621 }
622
623 CurrentEntry = CurrentEntry->ForwardLink;
624 }
625}
626
640RETURN_STATUS
642 IN CPU_FEATURES_DATA *CpuFeaturesData,
643 IN CPU_FEATURES_ENTRY *CpuFeature
644 )
645{
646 EFI_STATUS Status;
647 CPU_FEATURES_ENTRY *CpuFeatureEntry;
648 LIST_ENTRY *Entry;
649 BOOLEAN FeatureExist;
650
651 FeatureExist = FALSE;
652 CpuFeatureEntry = NULL;
653 Entry = GetFirstNode (&CpuFeaturesData->FeatureList);
654 while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
655 CpuFeatureEntry = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
656 if (CompareMem (CpuFeature->FeatureMask, CpuFeatureEntry->FeatureMask, CpuFeaturesData->BitMaskSize) == 0) {
657 //
658 // If this feature already registered
659 //
660 FeatureExist = TRUE;
661 break;
662 }
663
664 Entry = Entry->ForwardLink;
665 }
666
667 if (!FeatureExist) {
668 DEBUG ((DEBUG_INFO, "[NEW] "));
669 DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);
670 InsertTailList (&CpuFeaturesData->FeatureList, &CpuFeature->Link);
671 CpuFeaturesData->FeaturesCount++;
672 } else {
673 DEBUG ((DEBUG_INFO, "[OVERRIDE] "));
674 DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);
675 ASSERT (CpuFeatureEntry != NULL);
676 //
677 // Overwrite original parameters of CPU feature
678 //
679 if (CpuFeature->GetConfigDataFunc != NULL) {
680 CpuFeatureEntry->GetConfigDataFunc = CpuFeature->GetConfigDataFunc;
681 }
682
683 if (CpuFeature->SupportFunc != NULL) {
684 CpuFeatureEntry->SupportFunc = CpuFeature->SupportFunc;
685 }
686
687 if (CpuFeature->InitializeFunc != NULL) {
688 CpuFeatureEntry->InitializeFunc = CpuFeature->InitializeFunc;
689 }
690
691 if (CpuFeature->FeatureName != NULL) {
692 if (CpuFeatureEntry->FeatureName == NULL) {
693 CpuFeatureEntry->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);
694 ASSERT (CpuFeatureEntry->FeatureName != NULL);
695 }
696
697 Status = AsciiStrCpyS (CpuFeatureEntry->FeatureName, CPU_FEATURE_NAME_SIZE, CpuFeature->FeatureName);
698 ASSERT_EFI_ERROR (Status);
699 FreePool (CpuFeature->FeatureName);
700 }
701
702 if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) {
703 if (CpuFeatureEntry->ThreadBeforeFeatureBitMask != NULL) {
704 FreePool (CpuFeatureEntry->ThreadBeforeFeatureBitMask);
705 }
706
707 CpuFeatureEntry->ThreadBeforeFeatureBitMask = CpuFeature->ThreadBeforeFeatureBitMask;
708 }
709
710 if (CpuFeature->ThreadAfterFeatureBitMask != NULL) {
711 if (CpuFeatureEntry->ThreadAfterFeatureBitMask != NULL) {
712 FreePool (CpuFeatureEntry->ThreadAfterFeatureBitMask);
713 }
714
715 CpuFeatureEntry->ThreadAfterFeatureBitMask = CpuFeature->ThreadAfterFeatureBitMask;
716 }
717
718 if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {
719 if (CpuFeatureEntry->CoreBeforeFeatureBitMask != NULL) {
720 FreePool (CpuFeatureEntry->CoreBeforeFeatureBitMask);
721 }
722
723 CpuFeatureEntry->CoreBeforeFeatureBitMask = CpuFeature->CoreBeforeFeatureBitMask;
724 }
725
726 if (CpuFeature->CoreAfterFeatureBitMask != NULL) {
727 if (CpuFeatureEntry->CoreAfterFeatureBitMask != NULL) {
728 FreePool (CpuFeatureEntry->CoreAfterFeatureBitMask);
729 }
730
731 CpuFeatureEntry->CoreAfterFeatureBitMask = CpuFeature->CoreAfterFeatureBitMask;
732 }
733
734 if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {
735 if (CpuFeatureEntry->PackageBeforeFeatureBitMask != NULL) {
736 FreePool (CpuFeatureEntry->PackageBeforeFeatureBitMask);
737 }
738
739 CpuFeatureEntry->PackageBeforeFeatureBitMask = CpuFeature->PackageBeforeFeatureBitMask;
740 }
741
742 if (CpuFeature->PackageAfterFeatureBitMask != NULL) {
743 if (CpuFeatureEntry->PackageAfterFeatureBitMask != NULL) {
744 FreePool (CpuFeatureEntry->PackageAfterFeatureBitMask);
745 }
746
747 CpuFeatureEntry->PackageAfterFeatureBitMask = CpuFeature->PackageAfterFeatureBitMask;
748 }
749
750 CpuFeatureEntry->BeforeAll = CpuFeature->BeforeAll;
751 CpuFeatureEntry->AfterAll = CpuFeature->AfterAll;
752
753 FreePool (CpuFeature->FeatureMask);
754 FreePool (CpuFeature);
755 }
756
757 //
758 // Verify CPU features dependency can change CPU feature order
759 //
760 CheckCpuFeaturesDependency (&CpuFeaturesData->FeatureList);
761 return RETURN_SUCCESS;
762}
763
771VOID
773 IN UINT8 **FeaturesBitMask,
774 IN UINT32 Feature,
775 IN UINTN BitMaskSize
776 )
777{
778 UINT8 *CpuFeaturesBitMask;
779
780 ASSERT (FeaturesBitMask != NULL);
781 CpuFeaturesBitMask = *FeaturesBitMask;
782 if (CpuFeaturesBitMask == NULL) {
783 CpuFeaturesBitMask = AllocateZeroPool (BitMaskSize);
784 ASSERT (CpuFeaturesBitMask != NULL);
785 *FeaturesBitMask = CpuFeaturesBitMask;
786 }
787
788 CpuFeaturesBitMask += (Feature / 8);
789 *CpuFeaturesBitMask |= (UINT8)(1 << (Feature % 8));
790}
791
838RETURN_STATUS
839EFIAPI
841 IN CHAR8 *FeatureName OPTIONAL,
842 IN CPU_FEATURE_GET_CONFIG_DATA GetConfigDataFunc OPTIONAL,
843 IN CPU_FEATURE_SUPPORT SupportFunc OPTIONAL,
844 IN CPU_FEATURE_INITIALIZE InitializeFunc OPTIONAL,
845 ...
846 )
847{
848 EFI_STATUS Status;
849 VA_LIST Marker;
850 UINT32 Feature;
851 CPU_FEATURES_ENTRY *CpuFeature;
852 UINT8 *FeatureMask;
853 UINT8 *ThreadBeforeFeatureBitMask;
854 UINT8 *ThreadAfterFeatureBitMask;
855 UINT8 *CoreBeforeFeatureBitMask;
856 UINT8 *CoreAfterFeatureBitMask;
857 UINT8 *PackageBeforeFeatureBitMask;
858 UINT8 *PackageAfterFeatureBitMask;
859 BOOLEAN BeforeAll;
860 BOOLEAN AfterAll;
861 CPU_FEATURES_DATA *CpuFeaturesData;
862
863 FeatureMask = NULL;
864 ThreadBeforeFeatureBitMask = NULL;
865 ThreadAfterFeatureBitMask = NULL;
866 CoreBeforeFeatureBitMask = NULL;
867 CoreAfterFeatureBitMask = NULL;
868 PackageBeforeFeatureBitMask = NULL;
869 PackageAfterFeatureBitMask = NULL;
870 BeforeAll = FALSE;
871 AfterAll = FALSE;
872
873 CpuFeaturesData = GetCpuFeaturesData ();
874 if (CpuFeaturesData->FeaturesCount == 0) {
875 InitializeListHead (&CpuFeaturesData->FeatureList);
876 InitializeSpinLock (&CpuFeaturesData->CpuFlags.MemoryMappedLock);
877 //
878 // Code assumes below three PCDs have PCD same buffer size.
879 //
880 ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesCapability));
881 ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesSupport));
882 CpuFeaturesData->BitMaskSize = (UINT32)PcdGetSize (PcdCpuFeaturesSetting);
883 }
884
885 VA_START (Marker, InitializeFunc);
886 Feature = VA_ARG (Marker, UINT32);
887 while (Feature != CPU_FEATURE_END) {
888 //
889 // It's invalid to require a feature is before AND after all other features.
890 //
891 ASSERT (
892 (Feature & (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL))
893 != (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL)
894 );
895
896 //
897 // It's invalid to require feature A is before AND after before feature B,
898 // either in thread level, core level or package level.
899 //
900 ASSERT (
901 (Feature & (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER))
902 != (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER)
903 );
904 ASSERT (
905 (Feature & (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER))
906 != (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER)
907 );
908 ASSERT (
909 (Feature & (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER))
910 != (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER)
911 );
912 if (Feature < CPU_FEATURE_THREAD_BEFORE) {
913 BeforeAll = ((Feature & CPU_FEATURE_BEFORE_ALL) != 0) ? TRUE : FALSE;
914 AfterAll = ((Feature & CPU_FEATURE_AFTER_ALL) != 0) ? TRUE : FALSE;
915 Feature &= ~(CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL);
916 ASSERT (FeatureMask == NULL);
917 SetCpuFeaturesBitMask (&FeatureMask, Feature, CpuFeaturesData->BitMaskSize);
918 } else if ((Feature & CPU_FEATURE_THREAD_BEFORE) != 0) {
919 SetCpuFeaturesBitMask (&ThreadBeforeFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_BEFORE, CpuFeaturesData->BitMaskSize);
920 } else if ((Feature & CPU_FEATURE_THREAD_AFTER) != 0) {
921 SetCpuFeaturesBitMask (&ThreadAfterFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_AFTER, CpuFeaturesData->BitMaskSize);
922 } else if ((Feature & CPU_FEATURE_CORE_BEFORE) != 0) {
923 SetCpuFeaturesBitMask (&CoreBeforeFeatureBitMask, Feature & ~CPU_FEATURE_CORE_BEFORE, CpuFeaturesData->BitMaskSize);
924 } else if ((Feature & CPU_FEATURE_CORE_AFTER) != 0) {
925 SetCpuFeaturesBitMask (&CoreAfterFeatureBitMask, Feature & ~CPU_FEATURE_CORE_AFTER, CpuFeaturesData->BitMaskSize);
926 } else if ((Feature & CPU_FEATURE_PACKAGE_BEFORE) != 0) {
927 SetCpuFeaturesBitMask (&PackageBeforeFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_BEFORE, CpuFeaturesData->BitMaskSize);
928 } else if ((Feature & CPU_FEATURE_PACKAGE_AFTER) != 0) {
929 SetCpuFeaturesBitMask (&PackageAfterFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_AFTER, CpuFeaturesData->BitMaskSize);
930 }
931
932 Feature = VA_ARG (Marker, UINT32);
933 }
934
935 VA_END (Marker);
936
937 CpuFeature = AllocateZeroPool (sizeof (CPU_FEATURES_ENTRY));
938 ASSERT (CpuFeature != NULL);
939 CpuFeature->Signature = CPU_FEATURE_ENTRY_SIGNATURE;
940 CpuFeature->FeatureMask = FeatureMask;
941 CpuFeature->ThreadBeforeFeatureBitMask = ThreadBeforeFeatureBitMask;
942 CpuFeature->ThreadAfterFeatureBitMask = ThreadAfterFeatureBitMask;
943 CpuFeature->CoreBeforeFeatureBitMask = CoreBeforeFeatureBitMask;
944 CpuFeature->CoreAfterFeatureBitMask = CoreAfterFeatureBitMask;
945 CpuFeature->PackageBeforeFeatureBitMask = PackageBeforeFeatureBitMask;
946 CpuFeature->PackageAfterFeatureBitMask = PackageAfterFeatureBitMask;
947 CpuFeature->BeforeAll = BeforeAll;
948 CpuFeature->AfterAll = AfterAll;
949 CpuFeature->GetConfigDataFunc = GetConfigDataFunc;
950 CpuFeature->SupportFunc = SupportFunc;
951 CpuFeature->InitializeFunc = InitializeFunc;
952 if (FeatureName != NULL) {
953 CpuFeature->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);
954 ASSERT (CpuFeature->FeatureName != NULL);
955 Status = AsciiStrCpyS (CpuFeature->FeatureName, CPU_FEATURE_NAME_SIZE, FeatureName);
956 ASSERT_EFI_ERROR (Status);
957 }
958
959 Status = RegisterCpuFeatureWorker (CpuFeaturesData, CpuFeature);
960 ASSERT_EFI_ERROR (Status);
961
962 return RETURN_SUCCESS;
963}
964
974 VOID
975 )
976{
977 EFI_STATUS Status;
978 UINTN NumberOfCpus;
979 UINTN NumberOfEnabledProcessors;
980 ACPI_CPU_DATA *AcpiCpuData;
981 UINTN TableSize;
982 CPU_REGISTER_TABLE *RegisterTable;
983 UINTN Index;
984 EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;
985
986 AcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress);
987 if (AcpiCpuData == NULL) {
988 AcpiCpuData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)));
989 if (AcpiCpuData == NULL) {
990 ASSERT (AcpiCpuData != NULL);
991 return NULL;
992 }
993
994 ZeroMem (AcpiCpuData, sizeof (ACPI_CPU_DATA));
995
996 //
997 // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure
998 //
999 Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);
1000 ASSERT_EFI_ERROR (Status);
1001
1002 GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);
1003 AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;
1004 }
1005
1006 if ((AcpiCpuData->CpuFeatureInitData.RegisterTable == 0) ||
1007 (AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable == 0))
1008 {
1009 //
1010 // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs
1011 //
1012 NumberOfCpus = AcpiCpuData->NumberOfCpus;
1013 TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);
1014 RegisterTable = AllocatePages (EFI_SIZE_TO_PAGES (TableSize));
1015 if (RegisterTable == NULL) {
1016 // Leave the AcpiCpuData data buffer allocated since it was assigned to a dynamic PCD
1017 // which could have invoked PCD set callbacks that may have cached the buffer.
1018 ASSERT (RegisterTable != NULL);
1019 return NULL;
1020 }
1021
1022 for (Index = 0; Index < NumberOfCpus; Index++) {
1023 Status = GetProcessorInformation (Index, &ProcessorInfoBuffer);
1024 ASSERT_EFI_ERROR (Status);
1025
1026 RegisterTable[Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
1027 RegisterTable[Index].TableLength = 0;
1028 RegisterTable[Index].AllocatedSize = 0;
1029 RegisterTable[Index].RegisterTableEntry = 0;
1030
1031 RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
1032 RegisterTable[NumberOfCpus + Index].TableLength = 0;
1033 RegisterTable[NumberOfCpus + Index].AllocatedSize = 0;
1034 RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;
1035 }
1036
1037 if (AcpiCpuData->CpuFeatureInitData.RegisterTable == 0) {
1038 AcpiCpuData->CpuFeatureInitData.RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;
1039 }
1040
1041 if (AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable == 0) {
1042 AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);
1043 }
1044 }
1045
1046 return AcpiCpuData;
1047}
1048
1054STATIC
1055VOID
1057 IN OUT CPU_REGISTER_TABLE *RegisterTable
1058 )
1059{
1060 EFI_PHYSICAL_ADDRESS Address;
1061 UINTN UsedPages;
1062
1063 UsedPages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;
1064 Address = (UINTN)AllocatePages (UsedPages + 1);
1065 ASSERT (Address != 0);
1066
1067 //
1068 // If there are records existing in the register table, then copy its contents
1069 // to new region and free the old one.
1070 //
1071 if (RegisterTable->AllocatedSize > 0) {
1072 CopyMem (
1073 (VOID *)(UINTN)Address,
1074 (VOID *)(UINTN)RegisterTable->RegisterTableEntry,
1075 RegisterTable->AllocatedSize
1076 );
1077
1078 FreePages ((VOID *)(UINTN)RegisterTable->RegisterTableEntry, UsedPages);
1079 }
1080
1081 //
1082 // Adjust the allocated size and register table base address.
1083 //
1084 RegisterTable->AllocatedSize += EFI_PAGE_SIZE;
1085 RegisterTable->RegisterTableEntry = Address;
1086}
1087
1105VOID
1107 IN BOOLEAN PreSmmFlag,
1108 IN UINTN ProcessorNumber,
1109 IN REGISTER_TYPE RegisterType,
1110 IN UINT64 Index,
1111 IN UINT8 ValidBitStart,
1112 IN UINT8 ValidBitLength,
1113 IN UINT64 Value,
1114 IN BOOLEAN TestThenWrite
1115 )
1116{
1117 CPU_FEATURES_DATA *CpuFeaturesData;
1118 ACPI_CPU_DATA *AcpiCpuData;
1119 CPU_REGISTER_TABLE *RegisterTable;
1120 CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
1121
1122 CpuFeaturesData = GetCpuFeaturesData ();
1123 if (CpuFeaturesData->RegisterTable == NULL) {
1124 AcpiCpuData = GetAcpiCpuData ();
1125 if (AcpiCpuData == NULL) {
1126 ASSERT (AcpiCpuData != NULL);
1127 return;
1128 }
1129
1130 ASSERT (AcpiCpuData->CpuFeatureInitData.RegisterTable != 0);
1131 CpuFeaturesData->RegisterTable = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.RegisterTable;
1132 CpuFeaturesData->PreSmmRegisterTable = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable;
1133 }
1134
1135 if (PreSmmFlag) {
1136 RegisterTable = &CpuFeaturesData->PreSmmRegisterTable[ProcessorNumber];
1137 } else {
1138 RegisterTable = &CpuFeaturesData->RegisterTable[ProcessorNumber];
1139 }
1140
1141 if (RegisterTable->TableLength == RegisterTable->AllocatedSize / sizeof (CPU_REGISTER_TABLE_ENTRY)) {
1142 EnlargeRegisterTable (RegisterTable);
1143 }
1144
1145 //
1146 // Append entry in the register table.
1147 //
1148 RegisterTableEntry = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry;
1149 RegisterTableEntry[RegisterTable->TableLength].RegisterType = RegisterType;
1150 RegisterTableEntry[RegisterTable->TableLength].Index = (UINT32)Index;
1151 RegisterTableEntry[RegisterTable->TableLength].HighIndex = (UINT32)RShiftU64 (Index, 32);
1152 RegisterTableEntry[RegisterTable->TableLength].ValidBitStart = ValidBitStart;
1153 RegisterTableEntry[RegisterTable->TableLength].ValidBitLength = ValidBitLength;
1154 RegisterTableEntry[RegisterTable->TableLength].Value = Value;
1155 RegisterTableEntry[RegisterTable->TableLength].TestThenWrite = TestThenWrite;
1156
1157 RegisterTable->TableLength++;
1158}
1159
1174VOID
1175EFIAPI
1177 IN UINTN ProcessorNumber,
1178 IN REGISTER_TYPE RegisterType,
1179 IN UINT64 Index,
1180 IN UINT64 ValueMask,
1181 IN UINT64 Value
1182 )
1183{
1184 UINT8 Start;
1185 UINT8 End;
1186 UINT8 Length;
1187
1188 Start = (UINT8)LowBitSet64 (ValueMask);
1189 End = (UINT8)HighBitSet64 (ValueMask);
1190 Length = End - Start + 1;
1191 CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE);
1192}
1193
1208VOID
1209EFIAPI
1211 IN UINTN ProcessorNumber,
1212 IN REGISTER_TYPE RegisterType,
1213 IN UINT64 Index,
1214 IN UINT64 ValueMask,
1215 IN UINT64 Value
1216 )
1217{
1218 UINT8 Start;
1219 UINT8 End;
1220 UINT8 Length;
1221
1222 Start = (UINT8)LowBitSet64 (ValueMask);
1223 End = (UINT8)HighBitSet64 (ValueMask);
1224 Length = End - Start + 1;
1225 CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, TRUE);
1226}
1227
1242VOID
1243EFIAPI
1245 IN UINTN ProcessorNumber,
1246 IN REGISTER_TYPE RegisterType,
1247 IN UINT64 Index,
1248 IN UINT64 ValueMask,
1249 IN UINT64 Value
1250 )
1251{
1252 UINT8 Start;
1253 UINT8 End;
1254 UINT8 Length;
1255
1256 Start = (UINT8)LowBitSet64 (ValueMask);
1257 End = (UINT8)HighBitSet64 (ValueMask);
1258 Length = End - Start + 1;
1259 CpuRegisterTableWriteWorker (TRUE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE);
1260}
1261
1273BOOLEAN
1275 IN UINT8 *CpuBitMask,
1276 IN UINTN CpuBitMaskSize,
1277 IN UINT32 Feature
1278 )
1279{
1280 if ((Feature >> 3) >= CpuBitMaskSize) {
1281 return FALSE;
1282 }
1283
1284 return ((*(CpuBitMask + (Feature >> 3)) & (1 << (Feature & 0x07))) != 0);
1285}
1286
1301BOOLEAN
1302EFIAPI
1304 IN UINT32 Feature
1305 )
1306{
1308 (UINT8 *)PcdGetPtr (PcdCpuFeaturesSupport),
1309 PcdGetSize (PcdCpuFeaturesSupport),
1310 Feature
1311 );
1312}
1313
1325BOOLEAN
1326EFIAPI
1328 IN UINT32 Feature
1329 )
1330{
1332 (UINT8 *)PcdGetPtr (PcdCpuFeaturesSetting),
1333 PcdGetSize (PcdCpuFeaturesSetting),
1334 Feature
1335 );
1336}
1337
1345VOID
1346EFIAPI
1348 IN UINTN ProcessorNumber
1349 )
1350{
1351 CPU_FEATURES_DATA *CpuFeaturesData;
1352
1353 CpuFeaturesData = GetCpuFeaturesData ();
1354 CpuFeaturesData->BspNumber = ProcessorNumber;
1355}
UINT64 UINTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
LIST_ENTRY *EFIAPI GetPreviousNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:369
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
INTN EFIAPI LowBitSet64(IN UINT64 Operand)
Definition: LowBitSet64.c:27
INTN EFIAPI HighBitSet64(IN UINT64 Operand)
Definition: HighBitSet64.c:27
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1797
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
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 EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define VA_ARG(Marker, TYPE)
Definition: Base.h:679
#define VA_START(Marker, Parameter)
Definition: Base.h:661
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
CHAR8 * VA_LIST
Definition: Base.h:643
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define VA_END(Marker)
Definition: Base.h:691
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGetSize(TokenName)
Definition: PcdLib.h:440
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdSet64S(TokenName, Value)
Definition: PcdLib.h:511
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
VOID EFIAPI SwitchBspAfterFeaturesInitialize(IN UINTN ProcessorNumber)
BOOLEAN IsBitMaskMatchCheck(IN UINT8 *FeatureMask, IN UINT8 *DependentBitMask)
RETURN_STATUS RegisterCpuFeatureWorker(IN CPU_FEATURES_DATA *CpuFeaturesData, IN CPU_FEATURES_ENTRY *CpuFeature)
BOOLEAN InsertToBeforeEntry(IN LIST_ENTRY *FeatureList, IN LIST_ENTRY *CurrentEntry, IN UINT8 *FeatureMask)
STATIC VOID EnlargeRegisterTable(IN OUT CPU_REGISTER_TABLE *RegisterTable)
VOID EFIAPI CpuRegisterTableWrite(IN UINTN ProcessorNumber, IN REGISTER_TYPE RegisterType, IN UINT64 Index, IN UINT64 ValueMask, IN UINT64 Value)
BOOLEAN EFIAPI IsCpuFeatureInSetting(IN UINT32 Feature)
BOOLEAN InsertToAfterEntry(IN LIST_ENTRY *FeatureList, IN LIST_ENTRY *CurrentEntry, IN UINT8 *FeatureMask)
VOID CpuRegisterTableWriteWorker(IN BOOLEAN PreSmmFlag, IN UINTN ProcessorNumber, IN REGISTER_TYPE RegisterType, IN UINT64 Index, IN UINT8 ValidBitStart, IN UINT8 ValidBitLength, IN UINT64 Value, IN BOOLEAN TestThenWrite)
VOID AdjustEntry(IN LIST_ENTRY *FeatureList, IN OUT LIST_ENTRY *FindEntry, IN OUT LIST_ENTRY *CurrentEntry, IN BOOLEAN Before)
BOOLEAN EFIAPI IsCpuFeatureSupported(IN UINT32 Feature)
VOID DumpCpuFeature(IN CPU_FEATURES_ENTRY *CpuFeature, IN UINT32 BitMaskSize)
VOID DumpCpuFeatureMask(IN UINT8 *FeatureMask, IN UINT32 BitMaskSize)
BOOLEAN AdjustFeaturesDependence(IN OUT CPU_FEATURES_ENTRY *PreviousFeature, IN OUT CPU_FEATURES_ENTRY *CurrentFeature, IN CPU_FEATURES_ENTRY *FindFeature, IN BOOLEAN Before)
VOID EFIAPI PreSmmCpuRegisterTableWrite(IN UINTN ProcessorNumber, IN REGISTER_TYPE RegisterType, IN UINT64 Index, IN UINT64 ValueMask, IN UINT64 Value)
VOID SetCpuFeaturesBitMask(IN UINT8 **FeaturesBitMask, IN UINT32 Feature, IN UINTN BitMaskSize)
CPU_FEATURE_DEPENDENCE_TYPE DetectNoneNeighborhoodFeatureScope(IN CPU_FEATURES_ENTRY *CpuFeature, IN BOOLEAN Before, IN LIST_ENTRY *FeatureList)
VOID CheckCpuFeaturesDependency(IN LIST_ENTRY *FeatureList)
VOID EFIAPI CpuRegisterTableTestThenWrite(IN UINTN ProcessorNumber, IN REGISTER_TYPE RegisterType, IN UINT64 Index, IN UINT64 ValueMask, IN UINT64 Value)
ACPI_CPU_DATA * GetAcpiCpuData(VOID)
BOOLEAN FindSpecifyFeature(IN LIST_ENTRY *FeatureList, IN LIST_ENTRY *CurrentEntry, IN BOOLEAN SearchFormer, IN UINT8 *FeatureMask)
CPU_FEATURE_DEPENDENCE_TYPE DetectFeatureScope(IN CPU_FEATURES_ENTRY *CpuFeature, IN BOOLEAN Before, IN UINT8 *NextCpuFeatureMask)
BOOLEAN IsCpuFeatureSetInCpuPcd(IN UINT8 *CpuBitMask, IN UINTN CpuBitMaskSize, IN UINT32 Feature)
RETURN_STATUS EFIAPI RegisterCpuFeature(IN CHAR8 *FeatureName OPTIONAL, IN CPU_FEATURE_GET_CONFIG_DATA GetConfigDataFunc OPTIONAL, IN CPU_FEATURE_SUPPORT SupportFunc OPTIONAL, IN CPU_FEATURE_INITIALIZE InitializeFunc OPTIONAL,...)
RETURN_STATUS(EFIAPI * CPU_FEATURE_INITIALIZE)(IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData OPTIONAL, IN BOOLEAN State)
BOOLEAN(EFIAPI * CPU_FEATURE_SUPPORT)(IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData OPTIONAL)
VOID *(EFIAPI * CPU_FEATURE_GET_CONFIG_DATA)(IN UINTN NumberOfProcessors)
SPIN_LOCK *EFIAPI InitializeSpinLock(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