TianoCore EDK2 master
Loading...
Searching...
No Matches
SsdtCpuTopologyGenerator.c
Go to the documentation of this file.
1
17#include <Library/AcpiLib.h>
18#include <Library/BaseLib.h>
20#include <Library/DebugLib.h>
22#include <Protocol/AcpiTable.h>
23
24// Module specific include files.
25#include <AcpiTableGenerator.h>
32
34
54 );
55
64 );
65
74 );
75
84 );
85
94 );
95
112STATIC
114EFIAPI
117 IN UINT32 Count
118 )
119{
120 CM_OBJECT_TOKEN *Table;
121
122 if ((Generator == NULL) ||
123 (Count == 0) ||
124 (Count >= MAX_NODE_COUNT))
125 {
126 ASSERT (0);
127 return EFI_INVALID_PARAMETER;
128 }
129
130 Table = AllocateZeroPool (sizeof (CM_OBJECT_TOKEN) * Count);
131 if (Table == NULL) {
132 ASSERT (0);
133 return EFI_OUT_OF_RESOURCES;
134 }
135
136 Generator->TokenTable.Table = Table;
137
138 return EFI_SUCCESS;
139}
140
145STATIC
146VOID
147EFIAPI
150 )
151{
152 ASSERT (Generator != NULL);
153 ASSERT (Generator->TokenTable.Table != NULL);
154
155 if (Generator->TokenTable.Table != NULL) {
156 FreePool (Generator->TokenTable.Table);
157 }
158}
159
170STATIC
171UINT32
172EFIAPI
175 IN CM_OBJECT_TOKEN Token
176 )
177{
178 CM_OBJECT_TOKEN *Table;
179 UINT32 Index;
180 UINT32 LastIndex;
181
182 ASSERT (Generator != NULL);
183 ASSERT (Generator->TokenTable.Table != NULL);
184
185 Table = Generator->TokenTable.Table;
186 LastIndex = Generator->TokenTable.LastIndex;
187
188 // Search if there is already an entry with this Token.
189 for (Index = 0; Index < LastIndex; Index++) {
190 if (Table[Index] == Token) {
191 return Index;
192 }
193 }
194
195 ASSERT (LastIndex < MAX_NODE_COUNT);
196 ASSERT (LastIndex < Generator->ProcNodeCount);
197
198 // If no, create a new entry.
199 Table[LastIndex] = Token;
200
201 return Generator->TokenTable.LastIndex++;
202}
203
221EFIAPI
223 IN CHAR8 LeadChar,
224 IN UINT32 Value,
225 IN OUT CHAR8 *AslName
226 )
227{
228 UINT8 Index;
229
230 if ((Value >= MAX_NODE_COUNT) ||
231 (AslName == NULL))
232 {
233 ASSERT (0);
234 return EFI_INVALID_PARAMETER;
235 }
236
237 AslName[0] = LeadChar;
238 AslName[AML_NAME_SEG_SIZE] = '\0';
239
240 for (Index = 0; Index < AML_NAME_SEG_SIZE - 1; Index++) {
241 AslName[AML_NAME_SEG_SIZE - Index - 1] =
242 AsciiFromHex (((Value >> (4 * Index)) & 0xF));
243 }
244
245 return EFI_SUCCESS;
246}
247
283STATIC
285EFIAPI
289 IN CM_OBJECT_TOKEN PsdToken,
291 )
292{
293 EFI_STATUS Status;
295
296 Status = GetEArchCommonObjPsdInfo (
297 CfgMgrProtocol,
298 PsdToken,
299 &PsdInfo,
300 NULL
301 );
302 if (EFI_ERROR (Status)) {
303 ASSERT_EFI_ERROR (Status);
304 return Status;
305 }
306
307 Status = AmlCreatePsdNode (
308 PsdInfo,
309 Node,
310 NULL
311 );
312 ASSERT_EFI_ERROR (Status);
313 return Status;
314}
315
371EFIAPI
375 IN CM_OBJECT_TOKEN CpcToken,
377 )
378{
379 EFI_STATUS Status;
381
382 Status = GetEArchCommonObjCpcInfo (
383 CfgMgrProtocol,
384 CpcToken,
385 &CpcInfo,
386 NULL
387 );
388 if (EFI_ERROR (Status)) {
389 ASSERT (0);
390 return Status;
391 }
392
393 Status = AmlCreateCpcNode (
394 CpcInfo,
395 Node,
396 NULL
397 );
398 ASSERT_EFI_ERROR (Status);
399 return Status;
400}
401
433STATIC
435EFIAPI
438 IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo,
440 )
441{
442 EFI_STATUS Status;
443 UINT32 TokenIndex;
444 CHAR8 AslName[SB_SCOPE_PREFIX_SIZE + AML_NAME_SEG_SIZE];
445
446 ASSERT (Generator != NULL);
447 ASSERT (ProcHierarchyNodeInfo != NULL);
448 ASSERT (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN);
449 ASSERT (Node != NULL);
450
451 TokenIndex = TokenTableAdd (Generator, ProcHierarchyNodeInfo->LpiToken);
452
453 CopyMem (AslName, SB_SCOPE_PREFIX, SB_SCOPE_PREFIX_SIZE);
454
455 Status = WriteAslName (
456 'L',
457 TokenIndex,
458 AslName + SB_SCOPE_PREFIX_SIZE - 1
459 );
460 if (EFI_ERROR (Status)) {
461 ASSERT (0);
462 return Status;
463 }
464
465 // ASL:
466 // Method (_LPI, 0) {
467 // Return ([AslName])
468 // }
470 "_LPI",
471 AslName,
472 0,
473 FALSE,
474 0,
475 Node,
476 NULL
477 );
478 if (EFI_ERROR (Status)) {
479 ASSERT (0);
480 }
481
482 return Status;
483}
484
520STATIC
522EFIAPI
526 IN AML_OBJECT_NODE_HANDLE ScopeNode
527 )
528{
529 EFI_STATUS Status;
530
531 UINT32 Index;
532 UINT32 LastIndex;
533
535 CM_ARCH_COMMON_OBJ_REF *LpiRefInfo;
536 UINT32 LpiRefInfoCount;
537 UINT32 LpiRefIndex;
539 CHAR8 AslName[AML_NAME_SEG_SIZE + 1];
540
541 ASSERT (Generator != NULL);
542 ASSERT (Generator->TokenTable.Table != NULL);
543 ASSERT (CfgMgrProtocol != NULL);
544 ASSERT (ScopeNode != NULL);
545
546 LastIndex = Generator->TokenTable.LastIndex;
547
548 // For each entry in the TokenTable, create a name in the AML namespace
549 // under SB_SCOPE, to store the Lpi states associated with the LpiToken.
550 for (Index = 0; Index < LastIndex; Index++) {
551 Status = WriteAslName ('L', Index, AslName);
552 if (EFI_ERROR (Status)) {
553 ASSERT (0);
554 return Status;
555 }
556
557 // We do not support the LevelId field for now, let it to 0.
558 Status = AmlCreateLpiNode (AslName, 0, 0, ScopeNode, &LpiNode);
559 if (EFI_ERROR (Status)) {
560 ASSERT (0);
561 return Status;
562 }
563
564 // Fetch the LPI objects referenced by the token.
565 Status = GetEArchCommonObjCmRef (
566 CfgMgrProtocol,
567 Generator->TokenTable.Table[Index],
568 &LpiRefInfo,
569 &LpiRefInfoCount
570 );
571 if (EFI_ERROR (Status)) {
572 ASSERT (0);
573 return Status;
574 }
575
576 for (LpiRefIndex = 0; LpiRefIndex < LpiRefInfoCount; LpiRefIndex++) {
577 // For each CM_ARCH_COMMON_LPI_INFO referenced by the token,
578 // add an Lpi state.
579 Status = GetEArchCommonObjLpiInfo (
580 CfgMgrProtocol,
581 LpiRefInfo[LpiRefIndex].ReferenceToken,
582 &LpiInfo,
583 NULL
584 );
585 if (EFI_ERROR (Status)) {
586 ASSERT (0);
587 return Status;
588 }
589
590 Status = AmlAddLpiState (
591 LpiInfo->MinResidency,
592 LpiInfo->WorstCaseWakeLatency,
593 LpiInfo->Flags,
594 LpiInfo->ArchFlags,
595 LpiInfo->ResCntFreq,
596 LpiInfo->EnableParentState,
597 LpiInfo->IsInteger ?
598 NULL :
599 &LpiInfo->RegisterEntryMethod,
600 LpiInfo->IsInteger ?
601 LpiInfo->IntegerEntryMethod :
602 0,
603 &LpiInfo->ResidencyCounterRegister,
604 &LpiInfo->UsageCounterRegister,
605 LpiInfo->StateName,
606 LpiNode
607 );
608 if (EFI_ERROR (Status)) {
609 ASSERT (0);
610 return Status;
611 }
612 } // for LpiRefIndex
613 } // for Index
614
615 return EFI_SUCCESS;
616}
617
638EFIAPI
641 IN AML_NODE_HANDLE ParentNode,
642 IN UINT32 AcpiProcessorUid,
643 IN UINT32 CpuName,
644 OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL
645 )
646{
647 EFI_STATUS Status;
649 CHAR8 AslName[AML_NAME_SEG_SIZE + 1];
650
651 ASSERT (Generator != NULL);
652 ASSERT (ParentNode != NULL);
653
654 Status = WriteAslName ('C', CpuName, AslName);
655 if (EFI_ERROR (Status)) {
656 ASSERT (0);
657 return Status;
658 }
659
660 Status = AmlCodeGenDevice (AslName, ParentNode, &CpuNode);
661 if (EFI_ERROR (Status)) {
662 ASSERT (0);
663 return Status;
664 }
665
666 Status = AmlCodeGenNameInteger (
667 "_UID",
668 AcpiProcessorUid,
669 CpuNode,
670 NULL
671 );
672 if (EFI_ERROR (Status)) {
673 ASSERT (0);
674 return Status;
675 }
676
677 Status = AmlCodeGenNameString (
678 "_HID",
680 CpuNode,
681 NULL
682 );
683 if (EFI_ERROR (Status)) {
684 ASSERT (0);
685 return Status;
686 }
687
688 // If requested, return the handle to the CpuNode.
689 if (CpuNodePtr != NULL) {
690 *CpuNodePtr = CpuNode;
691 }
692
693 return Status;
694}
695
711STATIC
713EFIAPI
717 IN AML_NODE_HANDLE ParentNode,
718 IN UINT32 CpuName,
719 IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo
720 )
721{
722 EFI_STATUS Status;
724 UINT32 AcpiProcessorUid;
725 CM_OBJECT_TOKEN CpcToken;
726 CM_OBJECT_TOKEN PsdToken;
727
728 ASSERT (Generator != NULL);
729 ASSERT (CfgMgrProtocol != NULL);
730 ASSERT (ParentNode != NULL);
731 ASSERT (ProcHierarchyNodeInfo != NULL);
732 ASSERT (ProcHierarchyNodeInfo->AcpiIdObjectToken != CM_NULL_TOKEN);
733
734 Status = GetIntCInfo (
735 CfgMgrProtocol,
736 ProcHierarchyNodeInfo->AcpiIdObjectToken,
737 &AcpiProcessorUid,
738 &CpcToken,
739 &PsdToken
740 );
741 if (EFI_ERROR (Status)) {
742 ASSERT (0);
743 return Status;
744 }
745
746 Status = CreateAmlCpu (Generator, ParentNode, AcpiProcessorUid, CpuName, &CpuNode);
747 if (EFI_ERROR (Status)) {
748 ASSERT (0);
749 return Status;
750 }
751
752 // If a set of Lpi states is associated with the
753 // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them.
754 if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) {
755 Status = CreateAmlLpiMethod (Generator, ProcHierarchyNodeInfo, CpuNode);
756 if (EFI_ERROR (Status)) {
757 ASSERT_EFI_ERROR (Status);
758 return Status;
759 }
760 }
761
762 if (PsdToken != CM_NULL_TOKEN) {
763 Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, PsdToken, CpuNode);
764 if (EFI_ERROR (Status)) {
765 ASSERT_EFI_ERROR (Status);
766 return Status;
767 }
768 }
769
770 // If a CPC info is associated with the
771 // IntcInfo, create an _CPC method returning them.
772 if (CpcToken != CM_NULL_TOKEN) {
773 Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, CpcToken, CpuNode);
774 if (EFI_ERROR (Status)) {
775 ASSERT_EFI_ERROR (Status);
776 return Status;
777 }
778 }
779
780 // Add arch specific information if necessary.
781 Status = AddArchAmlCpuInfo (
782 Generator,
783 CfgMgrProtocol,
784 ProcHierarchyNodeInfo->AcpiIdObjectToken,
785 CpuName,
786 CpuNode
787 );
788 if (EFI_ERROR (Status)) {
789 ASSERT_EFI_ERROR (Status);
790 return Status;
791 }
792
793 return Status;
794}
795
827STATIC
829EFIAPI
833 IN AML_NODE_HANDLE ParentNode,
834 IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo,
835 IN UINT16 ProcContainerName,
836 IN UINT32 ProcContainerUid,
837 OUT AML_OBJECT_NODE_HANDLE *ProcContainerNodePtr
838 )
839{
840 EFI_STATUS Status;
841 AML_OBJECT_NODE_HANDLE ProcContainerNode;
842 CHAR8 AslNameProcContainer[AML_NAME_SEG_SIZE + 1];
843
844 ASSERT (Generator != NULL);
845 ASSERT (CfgMgrProtocol != NULL);
846 ASSERT (ParentNode != NULL);
847 ASSERT (ProcHierarchyNodeInfo != NULL);
848 ASSERT (ProcContainerNodePtr != NULL);
849
850 Status = WriteAslName ('C', ProcContainerName, AslNameProcContainer);
851 if (EFI_ERROR (Status)) {
852 ASSERT (0);
853 return Status;
854 }
855
856 Status = AmlCodeGenDevice (AslNameProcContainer, ParentNode, &ProcContainerNode);
857 if (EFI_ERROR (Status)) {
858 ASSERT (0);
859 return Status;
860 }
861
862 // Use the ProcContainerIndex for the _UID value as there is no AcpiProcessorUid
863 // and EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID is set for non-Cpus.
864 Status = AmlCodeGenNameInteger (
865 "_UID",
866 ProcContainerUid,
867 ProcContainerNode,
868 NULL
869 );
870 if (EFI_ERROR (Status)) {
871 ASSERT (0);
872 return Status;
873 }
874
875 Status = AmlCodeGenNameString (
876 "_HID",
878 ProcContainerNode,
879 NULL
880 );
881 if (EFI_ERROR (Status)) {
882 ASSERT (0);
883 return Status;
884 }
885
886 // If a set of Lpi states are associated with the
887 // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them.
888 if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) {
889 Status = CreateAmlLpiMethod (
890 Generator,
891 ProcHierarchyNodeInfo,
892 ProcContainerNode
893 );
894 if (EFI_ERROR (Status)) {
895 ASSERT (0);
896 return Status;
897 }
898 }
899
900 *ProcContainerNodePtr = ProcContainerNode;
901
902 return Status;
903}
904
916STATIC
918EFIAPI
920 UINT32 NodeFlags,
921 BOOLEAN IsLeaf,
922 CM_OBJECT_TOKEN NodeToken,
923 CM_OBJECT_TOKEN ParentNodeToken,
924 BOOLEAN PackageNodeSeen
925 )
926{
927 BOOLEAN InvalidFlags;
928 BOOLEAN HasPhysicalPackageBit;
929
930 HasPhysicalPackageBit = (NodeFlags & EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) ==
931 EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL;
932
933 // Only one Physical Package flag is allowed in the hierarchy
934 InvalidFlags = HasPhysicalPackageBit && PackageNodeSeen;
935
936 // Check Leaf specific flags.
937 if (IsLeaf) {
938 InvalidFlags |= ((NodeFlags & PPTT_LEAF_MASK) != PPTT_LEAF_MASK);
939 // Must have Physical Package flag somewhere in the hierarchy
940 InvalidFlags |= !(HasPhysicalPackageBit || PackageNodeSeen);
941 } else {
942 InvalidFlags |= ((NodeFlags & PPTT_LEAF_MASK) != 0);
943 }
944
945 if (InvalidFlags) {
946 DEBUG ((
947 DEBUG_ERROR,
948 "ERROR: SSDT-CPU-TOPOLOGY: Invalid flags for ProcNode: 0x%p.\n",
949 (VOID *)NodeToken
950 ));
951 ASSERT (0);
952 return EFI_INVALID_PARAMETER;
953 }
954
955 return EFI_SUCCESS;
956}
957
976STATIC
978EFIAPI
982 IN CM_OBJECT_TOKEN NodeToken,
983 IN AML_NODE_HANDLE ParentNode,
984 IN OUT UINT32 *ProcContainerIndex,
985 IN BOOLEAN PackageNodeSeen
986 )
987{
988 EFI_STATUS Status;
989 UINT32 Index;
990 UINT32 CpuIndex;
991 UINT32 ProcContainerName;
992 AML_OBJECT_NODE_HANDLE ProcContainerNode;
993 UINT32 Uid;
994 UINT16 Name;
995 BOOLEAN HasPhysicalPackageBit;
996
997 ASSERT (Generator != NULL);
998 ASSERT (Generator->ProcNodeList != NULL);
999 ASSERT (Generator->ProcNodeCount != 0);
1000 ASSERT (CfgMgrProtocol != NULL);
1001 ASSERT (ParentNode != NULL);
1002 ASSERT (ProcContainerIndex != NULL);
1003
1004 CpuIndex = 0;
1005 ProcContainerName = 0;
1006
1007 for (Index = 0; Index < Generator->ProcNodeCount; Index++) {
1008 // Find the children of the CM_ARCH_COMMON_PROC_HIERARCHY_INFO
1009 // currently being handled (i.e. ParentToken == NodeToken).
1010 if (Generator->ProcNodeList[Index].ParentToken == NodeToken) {
1011 // Only Cpus (leaf nodes in this tree) have a AcpiIdObjectToken.
1012 // Create a Cpu node.
1013 if (Generator->ProcNodeList[Index].AcpiIdObjectToken != CM_NULL_TOKEN) {
1014 Status = CheckProcNode (
1015 Generator->ProcNodeList[Index].Flags,
1016 TRUE,
1017 Generator->ProcNodeList[Index].Token,
1018 NodeToken,
1019 PackageNodeSeen
1020 );
1021 if (EFI_ERROR (Status)) {
1022 ASSERT (0);
1023 return Status;
1024 }
1025
1026 if (Generator->ProcNodeList[Index].OverrideNameUidEnabled) {
1027 Name = Generator->ProcNodeList[Index].OverrideName;
1028 } else {
1029 ASSERT ((CpuIndex & ~MAX_UINT16) == 0);
1030 Name = (UINT16)CpuIndex;
1031 }
1032
1034 Generator,
1035 CfgMgrProtocol,
1036 ParentNode,
1037 Name,
1038 &Generator->ProcNodeList[Index]
1039 );
1040 if (EFI_ERROR (Status)) {
1041 ASSERT (0);
1042 return Status;
1043 }
1044
1045 CpuIndex++;
1046 } else {
1047 // If this is not a Cpu, then this is a processor container.
1048
1049 Status = CheckProcNode (
1050 Generator->ProcNodeList[Index].Flags,
1051 FALSE,
1052 Generator->ProcNodeList[Index].Token,
1053 NodeToken,
1054 PackageNodeSeen
1055 );
1056 if (EFI_ERROR (Status)) {
1057 ASSERT (0);
1058 return Status;
1059 }
1060
1061 if (Generator->ProcNodeList[Index].OverrideNameUidEnabled) {
1062 Name = Generator->ProcNodeList[Index].OverrideName;
1063 Uid = Generator->ProcNodeList[Index].OverrideUid;
1064 } else {
1065 ASSERT ((ProcContainerName & ~MAX_UINT16) == 0);
1066 Name = (UINT16)ProcContainerName;
1067 Uid = *ProcContainerIndex;
1068 }
1069
1071 Generator,
1072 CfgMgrProtocol,
1073 ParentNode,
1074 &Generator->ProcNodeList[Index],
1075 Name,
1076 Uid,
1077 &ProcContainerNode
1078 );
1079 if (EFI_ERROR (Status)) {
1080 ASSERT (0);
1081 return Status;
1082 }
1083
1084 // Nodes must have a unique name in the ASL namespace.
1085 // Reset the Cpu index whenever we create a new processor container.
1086 (*ProcContainerIndex)++;
1087 CpuIndex = 0;
1088
1089 // And reset the cluster name whenever there is a package.
1090 if (NodeToken == CM_NULL_TOKEN) {
1091 ProcContainerName = 0;
1092 } else {
1093 ProcContainerName++;
1094 }
1095
1096 HasPhysicalPackageBit = (Generator->ProcNodeList[Index].Flags & EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) ==
1097 EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL;
1098
1099 // Recursively continue creating an AML tree.
1100 Status = CreateAmlCpuTopologyTree (
1101 Generator,
1102 CfgMgrProtocol,
1103 Generator->ProcNodeList[Index].Token,
1104 ProcContainerNode,
1105 ProcContainerIndex,
1106 (PackageNodeSeen || HasPhysicalPackageBit)
1107 );
1108 if (EFI_ERROR (Status)) {
1109 ASSERT (0);
1110 return Status;
1111 }
1112 }
1113 } // if ParentToken == NodeToken
1114 } // for
1115
1116 return EFI_SUCCESS;
1117}
1118
1131STATIC
1133EFIAPI
1137 IN AML_OBJECT_NODE_HANDLE ScopeNode
1138 )
1139{
1140 EFI_STATUS Status;
1141 UINT32 ProcContainerIndex;
1142
1143 ASSERT (Generator != NULL);
1144 ASSERT (Generator->ProcNodeCount != 0);
1145 ASSERT (Generator->ProcNodeList != NULL);
1146 ASSERT (CfgMgrProtocol != NULL);
1147 ASSERT (ScopeNode != NULL);
1148
1149 ProcContainerIndex = 0;
1150
1151 Status = TokenTableInitialize (Generator, Generator->ProcNodeCount);
1152 if (EFI_ERROR (Status)) {
1153 ASSERT (0);
1154 return Status;
1155 }
1156
1157 Status = CreateAmlCpuTopologyTree (
1158 Generator,
1159 CfgMgrProtocol,
1161 ScopeNode,
1162 &ProcContainerIndex,
1163 FALSE
1164 );
1165 if (EFI_ERROR (Status)) {
1166 ASSERT (0);
1167 goto exit_handler;
1168 }
1169
1170 Status = GenerateLpiStates (Generator, CfgMgrProtocol, ScopeNode);
1171 if (EFI_ERROR (Status)) {
1172 ASSERT (0);
1173 goto exit_handler;
1174 }
1175
1176exit_handler:
1178 return Status;
1179}
1180
1203STATIC
1205EFIAPI
1211 )
1212{
1213 EFI_STATUS Status;
1214 AML_ROOT_NODE_HANDLE RootNode;
1215 AML_OBJECT_NODE_HANDLE ScopeNode;
1216 CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList;
1217 UINT32 ProcHierarchyNodeCount;
1219
1220 ASSERT (This != NULL);
1221 ASSERT (AcpiTableInfo != NULL);
1222 ASSERT (CfgMgrProtocol != NULL);
1223 ASSERT (Table != NULL);
1224 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
1225 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
1226
1228
1229 Status = AddSsdtAcpiHeader (
1230 CfgMgrProtocol,
1231 This,
1232 AcpiTableInfo,
1233 &RootNode
1234 );
1235 if (EFI_ERROR (Status)) {
1236 return Status;
1237 }
1238
1239 Status = AmlCodeGenScope (SB_SCOPE, RootNode, &ScopeNode);
1240 if (EFI_ERROR (Status)) {
1241 goto exit_handler;
1242 }
1243
1244 // Get the processor hierarchy info and update the processor topology
1245 // structure count with Processor Hierarchy Nodes (Type 0)
1246 Status = GetEArchCommonObjProcHierarchyInfo (
1247 CfgMgrProtocol,
1249 &ProcHierarchyNodeList,
1250 &ProcHierarchyNodeCount
1251 );
1252 if (EFI_ERROR (Status) &&
1253 (Status != EFI_NOT_FOUND))
1254 {
1255 goto exit_handler;
1256 }
1257
1258 if (Status == EFI_NOT_FOUND) {
1259 // If hierarchy information is not found generate a flat topology.
1260 Status = CreateTopologyFromIntC (
1261 Generator,
1262 CfgMgrProtocol,
1263 ScopeNode
1264 );
1265 if (EFI_ERROR (Status)) {
1266 goto exit_handler;
1267 }
1268 } else {
1269 // Generate the topology from CM_ARCH_COMMON_PROC_HIERARCHY_INFO objects.
1270 Generator->ProcNodeList = ProcHierarchyNodeList;
1271 Generator->ProcNodeCount = ProcHierarchyNodeCount;
1272
1274 Generator,
1275 CfgMgrProtocol,
1276 ScopeNode
1277 );
1278 if (EFI_ERROR (Status)) {
1279 goto exit_handler;
1280 }
1281 }
1282
1284 RootNode,
1285 Table
1286 );
1287 if (EFI_ERROR (Status)) {
1288 DEBUG ((
1289 DEBUG_ERROR,
1290 "ERROR: SSDT-CPU-TOPOLOGY: Failed to Serialize SSDT Table Data."
1291 " Status = %r\n",
1292 Status
1293 ));
1294 goto exit_handler;
1295 }
1296
1297exit_handler:
1298 // Delete the RootNode and its attached children.
1299 return AmlDeleteTree (RootNode);
1300}
1301
1314STATIC
1316EFIAPI
1322 )
1323{
1324 ASSERT (This != NULL);
1325 ASSERT (AcpiTableInfo != NULL);
1326 ASSERT (CfgMgrProtocol != NULL);
1327 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
1328 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
1329
1330 if ((Table == NULL) || (*Table == NULL)) {
1331 DEBUG ((DEBUG_ERROR, "ERROR: SSDT-CPU-TOPOLOGY: Invalid Table Pointer\n"));
1332 ASSERT ((Table != NULL) && (*Table != NULL));
1333 return EFI_INVALID_PARAMETER;
1334 }
1335
1336 FreePool (*Table);
1337 *Table = NULL;
1338 return EFI_SUCCESS;
1339}
1340
1343#define SSDT_CPU_TOPOLOGY_GENERATOR_REVISION CREATE_REVISION (1, 0)
1344
1347STATIC
1349 // ACPI table generator header
1350 {
1351 // Generator ID
1353 // Generator Description
1354 L"ACPI.STD.SSDT.CPU.TOPOLOGY.GENERATOR",
1355 // ACPI Table Signature
1357 // ACPI Table Revision - Unused
1358 0,
1359 // Minimum ACPI Table Revision - Unused
1360 0,
1361 // Creator ID
1363 // Creator Revision
1365 // Build Table function
1367 // Free Resource function
1369 // Extended build function not needed
1370 NULL,
1371 // Extended build function not implemented by the generator.
1372 // Hence extended free resource function is not required.
1373 NULL
1374 },
1375
1376 // Private fields are defined from here.
1377
1378 // TokenTable
1379 {
1380 // Table
1381 NULL,
1382 // LastIndex
1383 0
1384 },
1385 // ProcNodeList
1386 NULL,
1387 // ProcNodeCount
1388 0
1389};
1390
1402EFIAPI
1404 IN EFI_HANDLE ImageHandle,
1405 IN EFI_SYSTEM_TABLE *SystemTable
1406 )
1407{
1408 EFI_STATUS Status;
1409
1411 DEBUG ((
1412 DEBUG_INFO,
1413 "SSDT-CPU-TOPOLOGY: Register Generator. Status = %r\n",
1414 Status
1415 ));
1416 ASSERT_EFI_ERROR (Status);
1417
1418 return Status;
1419}
1420
1431EFIAPI
1433 IN EFI_HANDLE ImageHandle,
1434 IN EFI_SYSTEM_TABLE *SystemTable
1435 )
1436{
1437 EFI_STATUS Status;
1438
1440 DEBUG ((
1441 DEBUG_INFO,
1442 "SSDT-CPU-TOPOLOGY: Deregister Generator. Status = %r\n",
1443 Status
1444 ));
1445 ASSERT_EFI_ERROR (Status);
1446 return Status;
1447}
#define EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi63.h:2831
UINT8 EFIAPI AsciiFromHex(IN UINT8 Hex)
Definition: AcpiHelper.c:25
EFI_STATUS EFIAPI RegisterAcpiTableGenerator(IN CONST ACPI_TABLE_GENERATOR *CONST Generator)
EFI_STATUS EFIAPI DeregisterAcpiTableGenerator(IN CONST ACPI_TABLE_GENERATOR *CONST Generator)
#define CREATE_STD_ACPI_TABLE_GEN_ID(TableId)
#define TABLE_GENERATOR_CREATOR_ID
@ EStdAcpiTableIdSsdtCpuTopology
SSDT Cpu Topology.
void * AML_ROOT_NODE_HANDLE
Definition: AmlLib.h:51
EFI_STATUS EFIAPI AmlCreateCpcNode(IN AML_CPC_INFO *CpcInfo, IN AML_NODE_HANDLE ParentNode OPTIONAL, OUT AML_OBJECT_NODE_HANDLE *NewCpcNode OPTIONAL)
Definition: AmlCodeGen.c:3508
EFI_STATUS EFIAPI AmlAddLpiState(IN UINT32 MinResidency, IN UINT32 WorstCaseWakeLatency, IN UINT32 Flags, IN UINT32 ArchFlags, IN UINT32 ResCntFreq, IN UINT32 EnableParentState, IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE *GenericRegisterDescriptor OPTIONAL, IN UINT64 Integer OPTIONAL, IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE *ResidencyCounterRegister OPTIONAL, IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE *UsageCounterRegister OPTIONAL, IN CONST CHAR8 *StateName OPTIONAL, IN AML_OBJECT_NODE_HANDLE LpiNode)
Definition: AmlCodeGen.c:2607
EFI_STATUS EFIAPI AmlCreatePsdNode(IN AML_PSD_INFO *PsdInfo, IN AML_NODE_HANDLE ParentNode OPTIONAL, OUT AML_OBJECT_NODE_HANDLE *NewPsdNode OPTIONAL)
Definition: AmlCodeGen.c:4210
EFI_STATUS EFIAPI AmlCodeGenDevice(IN CONST CHAR8 *NameString, IN AML_NODE_HANDLE ParentNode OPTIONAL, OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL)
EFI_STATUS EFIAPI AmlCodeGenScope(IN CONST CHAR8 *NameString, IN AML_NODE_HANDLE ParentNode OPTIONAL, OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL)
EFI_STATUS EFIAPI AmlCodeGenNameString(IN CONST CHAR8 *NameString, IN CONST CHAR8 *String, IN AML_NODE_HANDLE ParentNode OPTIONAL, OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL)
EFI_STATUS EFIAPI AmlCreateLpiNode(IN CONST CHAR8 *LpiNameString, IN UINT16 Revision, IN UINT64 LevelId, IN AML_NODE_HANDLE ParentNode OPTIONAL, OUT AML_OBJECT_NODE_HANDLE *NewLpiNode OPTIONAL)
Definition: AmlCodeGen.c:2452
EFI_STATUS EFIAPI AmlCodeGenNameInteger(IN CONST CHAR8 *NameString, IN UINT64 Integer, IN AML_NODE_HANDLE ParentNode OPTIONAL, OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL)
void * AML_OBJECT_NODE_HANDLE
Definition: AmlLib.h:55
void * AML_NODE_HANDLE
Definition: AmlLib.h:47
EFI_STATUS EFIAPI AmlCodeGenMethodRetNameString(IN CONST CHAR8 *MethodNameString, IN CONST CHAR8 *ReturnedNameString OPTIONAL, IN UINT8 NumArgs, IN BOOLEAN IsSerialized, IN UINT8 SyncLevel, IN AML_NODE_HANDLE ParentNode OPTIONAL, OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL)
Definition: AmlCodeGen.c:2138
@ EArchCommonObjLpiInfo
15 - Lpi Info
@ EArchCommonObjCpcInfo
18 - Continuous Performance Control Info
@ EArchCommonObjPsdInfo
25 - P-State Dependency (PSD) Info
@ EArchCommonObjCmRef
7 - CM Object Reference
@ EArchCommonObjProcHierarchyInfo
16 - Processor Hierarchy Info
EFI_STATUS EFIAPI CreateTopologyFromIntC(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN AML_OBJECT_NODE_HANDLE ScopeNode)
EFI_STATUS EFIAPI GetIntCInfo(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CM_OBJECT_TOKEN AcpiIdObjectToken, OUT UINT32 *AcpiProcessorUid, OUT CM_OBJECT_TOKEN *CpcToken, OUT CM_OBJECT_TOKEN *PsdToken)
EFI_STATUS EFIAPI AddArchAmlCpuInfo(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CM_OBJECT_TOKEN AcpiIdObjectToken, IN UINT32 CpuName, OUT AML_OBJECT_NODE_HANDLE *CpuNode)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define GET_OBJECT_LIST(CmObjectNameSpace, CmObjectId, Type)
@ EObjNameSpaceArchCommon
Arch Common Objects Namespace.
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#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 ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
STATIC EFI_STATUS EFIAPI CreateAmlLpiMethod(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, IN AML_OBJECT_NODE_HANDLE *Node)
EFI_STATUS EFIAPI AcpiSsdtCpuTopologyLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC EFI_STATUS EFIAPI CreateAmlPsdNode(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CM_OBJECT_TOKEN PsdToken, IN AML_OBJECT_NODE_HANDLE *Node)
STATIC EFI_STATUS EFIAPI TokenTableInitialize(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN UINT32 Count)
STATIC UINT32 EFIAPI TokenTableAdd(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CM_OBJECT_TOKEN Token)
STATIC ACPI_CPU_TOPOLOGY_GENERATOR SsdtCpuTopologyGenerator
#define SSDT_CPU_TOPOLOGY_GENERATOR_REVISION
STATIC EFI_STATUS EFIAPI CreateAmlCpuFromProcHierarchy(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN AML_NODE_HANDLE ParentNode, IN UINT32 CpuName, IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo)
STATIC EFI_STATUS EFIAPI BuildSsdtCpuTopologyTable(IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table)
STATIC EFI_STATUS EFIAPI FreeSsdtCpuTopologyTableResources(IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table)
STATIC EFI_STATUS EFIAPI GenerateLpiStates(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN AML_OBJECT_NODE_HANDLE ScopeNode)
EFI_STATUS EFIAPI AcpiSsdtCpuTopologyLibDestructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI CreateAmlCpu(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN AML_NODE_HANDLE ParentNode, IN UINT32 AcpiProcessorUid, IN UINT32 CpuName, OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL)
EFI_STATUS EFIAPI WriteAslName(IN CHAR8 LeadChar, IN UINT32 Value, IN OUT CHAR8 *AslName)
STATIC EFI_STATUS EFIAPI CreateAmlProcessorContainer(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN AML_NODE_HANDLE ParentNode, IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, IN UINT16 ProcContainerName, IN UINT32 ProcContainerUid, OUT AML_OBJECT_NODE_HANDLE *ProcContainerNodePtr)
STATIC VOID EFIAPI TokenTableFree(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator)
STATIC EFI_STATUS EFIAPI CheckProcNode(UINT32 NodeFlags, BOOLEAN IsLeaf, CM_OBJECT_TOKEN NodeToken, CM_OBJECT_TOKEN ParentNodeToken, BOOLEAN PackageNodeSeen)
EFI_STATUS EFIAPI CreateAmlCpcNode(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CM_OBJECT_TOKEN CpcToken, IN AML_OBJECT_NODE_HANDLE *Node)
STATIC EFI_STATUS EFIAPI CreateAmlCpuTopologyTree(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CM_OBJECT_TOKEN NodeToken, IN AML_NODE_HANDLE ParentNode, IN OUT UINT32 *ProcContainerIndex, IN BOOLEAN PackageNodeSeen)
STATIC EFI_STATUS EFIAPI CreateTopologyFromProcHierarchy(IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN AML_OBJECT_NODE_HANDLE ScopeNode)
#define SB_SCOPE
#define SB_SCOPE_PREFIX_SIZE
Size of the SB_SCOPE_PREFIX string.
#define ACPI_HID_PROCESSOR_CONTAINER_DEVICE
HID for a processor container device.
#define ACPI_HID_PROCESSOR_DEVICE
HID for a processor device.
#define MAX_NODE_COUNT
UINTN CM_OBJECT_TOKEN
#define CM_NULL_TOKEN
EFI_STATUS EFIAPI AddSsdtAcpiHeader(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CONST ACPI_TABLE_GENERATOR *CONST Generator, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, OUT AML_ROOT_NODE_HANDLE *RootNode)
Definition: TableHelper.c:221
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS EFIAPI AmlDeleteTree(IN AML_NODE_HANDLE Node)
EFI_STATUS EFIAPI AmlSerializeDefinitionBlock(IN AML_ROOT_NODE_HANDLE RootNode, OUT EFI_ACPI_DESCRIPTION_HEADER **Table)
ACPI_TABLE_GENERATOR Header
ACPI Table generator header.
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE UsageCounterRegister
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE RegisterEntryMethod
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ResidencyCounterRegister