TianoCore EDK2 master
Loading...
Searching...
No Matches
PpttGenerator.c
Go to the documentation of this file.
1
15#include <Library/AcpiLib.h>
16#include <Library/BaseLib.h>
17#include <Library/DebugLib.h>
19#include <Protocol/AcpiTable.h>
20
21// Module specific include files.
22#include <AcpiTableGenerator.h>
27
28#include "PpttGenerator.h"
29
49 );
50
59 );
60
69 );
70
79 );
80
91UINT32
94 )
95{
96 ASSERT (Node != NULL);
97
98 // <size of Processor Hierarchy Node> + <size of Private Resources array>
100 (Node->NoOfPrivateResources * sizeof (UINT32));
101}
102
108 ProcHierarchyNodes,
109 GetProcHierarchyNodeSize (NodesToIndex),
111 );
112
118 CacheTypeStructs,
121 );
122
137STATIC
140 IN PPTT_NODE_INDEXER *NodeIndexer,
141 IN UINT32 NodeCount,
142 IN CONST CM_OBJECT_TOKEN SearchToken,
143 OUT PPTT_NODE_INDEXER **IndexedNodeFound
144 )
145{
146 EFI_STATUS Status;
147
148 ASSERT (NodeIndexer != NULL);
149
150 DEBUG ((
151 DEBUG_INFO,
152 "PPTT: Node Indexer: SearchToken = %p\n",
153 SearchToken
154 ));
155
156 while (NodeCount-- != 0) {
157 DEBUG ((
158 DEBUG_INFO,
159 "PPTT: Node Indexer: NodeIndexer->Token = %p. Offset = %d\n",
160 NodeIndexer->Token,
161 NodeIndexer->Offset
162 ));
163
164 if (NodeIndexer->Token == SearchToken) {
165 *IndexedNodeFound = NodeIndexer;
166 Status = EFI_SUCCESS;
167 DEBUG ((
168 DEBUG_INFO,
169 "PPTT: Node Indexer: Token = %p. Found, Status = %r\n",
170 SearchToken,
171 Status
172 ));
173 return Status;
174 }
175
176 NodeIndexer++;
177 }
178
179 Status = EFI_NOT_FOUND;
180 DEBUG ((
181 DEBUG_ERROR,
182 "PPTT: Node Indexer: SearchToken = %p. Status = %r\n",
183 SearchToken,
184 Status
185 ));
186
187 return Status;
188}
189
199STATIC
203 )
204{
205 EFI_STATUS Status;
206 PPTT_NODE_INDEXER *Iterator;
207 PPTT_NODE_INDEXER *CycleDetector;
208 UINT32 NodesRemaining;
209
210 ASSERT (Generator != NULL);
211
212 Iterator = Generator->NodeIndexer;
213 NodesRemaining = Generator->ProcTopologyStructCount;
214
215 while (NodesRemaining != 0) {
216 DEBUG ((
217 DEBUG_INFO,
218 "INFO: PPTT: Cycle detection for element with index %d\n",
219 Generator->ProcTopologyStructCount - NodesRemaining
220 ));
221
222 CycleDetector = Iterator;
223
224 // Walk the topology tree
225 while (CycleDetector->TopologyParent != NULL) {
226 DEBUG ((
227 DEBUG_INFO,
228 "INFO: PPTT: %p -> %p\n",
229 CycleDetector->Token,
230 CycleDetector->TopologyParent->Token
231 ));
232
233 // Check if we have already visited this node
234 if (CycleDetector->CycleDetectionStamp == NodesRemaining) {
235 Status = EFI_INVALID_PARAMETER;
236 DEBUG ((
237 DEBUG_ERROR,
238 "ERROR: PPTT: Cycle in processor and cache topology detected for " \
239 "a chain of references originating from a node with: Token = %p " \
240 "Status = %r\n",
241 Iterator->Token,
242 Status
243 ));
244 return Status;
245 }
246
247 // Stamp the visited node
248 CycleDetector->CycleDetectionStamp = NodesRemaining;
249 CycleDetector = CycleDetector->TopologyParent;
250 } // Continue topology tree walk
251
252 Iterator++;
253 NodesRemaining--;
254 } // Next Node Indexer
255
256 return EFI_SUCCESS;
257}
258
274STATIC
279 IN UINT32 *PrivResArray,
280 IN UINT32 PrivResCount,
281 IN CONST CM_OBJECT_TOKEN PrivResArrayToken
282 )
283{
284 EFI_STATUS Status;
285 CM_ARCH_COMMON_OBJ_REF *CmObjRefs;
286 UINT32 CmObjRefCount;
287 PPTT_NODE_INDEXER *PpttNodeFound;
288
289 ASSERT (
290 (Generator != NULL) &&
291 (CfgMgrProtocol != NULL) &&
292 (PrivResArray != NULL) &&
293 (PrivResCount != 0)
294 );
295
296 // Validate input arguments
297 if (PrivResArrayToken == CM_NULL_TOKEN) {
298 Status = EFI_INVALID_PARAMETER;
299 DEBUG ((
300 DEBUG_ERROR,
301 "ERROR: PPTT: The number of private resources is %d while " \
302 "PrivResToken = CM_NULL_TOKEN. Status = %r\n",
303 PrivResCount,
304 Status
305 ));
306 return Status;
307 }
308
309 CmObjRefCount = 0;
310 // Get the CM Object References
311 Status = GetEArchCommonObjCmRef (
312 CfgMgrProtocol,
313 PrivResArrayToken,
314 &CmObjRefs,
315 &CmObjRefCount
316 );
317 if (EFI_ERROR (Status)) {
318 DEBUG ((
319 DEBUG_ERROR,
320 "ERROR: PPTT: Failed to get CM Object References. " \
321 "PrivResToken = %p. Status = %r\n",
322 PrivResArrayToken,
323 Status
324 ));
325 return Status;
326 }
327
328 if (CmObjRefCount != PrivResCount) {
329 Status = EFI_INVALID_PARAMETER;
330 DEBUG ((
331 DEBUG_ERROR,
332 "ERROR: PPTT: The number of CM Object References retrieved and the " \
333 "number of private resources don't match. CmObjRefCount = %d. " \
334 "PrivResourceCount = %d. PrivResToken = %p. Status = %r\n",
335 CmObjRefCount,
336 PrivResCount,
337 PrivResArrayToken,
338 Status
339 ));
340 return Status;
341 }
342
343 while (PrivResCount-- != 0) {
344 if (CmObjRefs->ReferenceToken == CM_NULL_TOKEN) {
345 Status = EFI_INVALID_PARAMETER;
346 DEBUG ((
347 DEBUG_ERROR,
348 "ERROR: PPTT: CM_NULL_TOKEN provided as reference token for a " \
349 "private resource. Status = %r\n",
350 Status
351 ));
352 return Status;
353 }
354
355 // The Node indexer has the Processor hierarchy nodes at the begining
356 // followed by the cache structs. Therefore we can skip the Processor
357 // hierarchy nodes in the node indexer search.
359 Generator->CacheStructIndexedList,
360 (Generator->ProcTopologyStructCount -
361 Generator->ProcHierarchyNodeCount),
362 CmObjRefs->ReferenceToken,
363 &PpttNodeFound
364 );
365 if (EFI_ERROR (Status)) {
366 DEBUG ((
367 DEBUG_ERROR,
368 "ERROR: PPTT: Failed to get a private resource with Token = %p from " \
369 "Node Indexer. Status = %r\n",
370 CmObjRefs->ReferenceToken,
371 Status
372 ));
373 return Status;
374 }
375
376 // Update the offset of the private resources in the Processor
377 // Hierarchy Node structure
378 *(PrivResArray++) = PpttNodeFound->Offset;
379 CmObjRefs++;
380 }
381
382 return EFI_SUCCESS;
383}
384
405BOOLEAN
406EFIAPI
408 IN CONST VOID *Object1,
409 IN CONST VOID *Object2,
410 IN UINTN Index1,
411 IN UINTN Index2
412 )
413{
414 PPTT_NODE_INDEXER *IndexedObject1;
415 PPTT_NODE_INDEXER *IndexedObject2;
418
419 ASSERT (
420 (Object1 != NULL) &&
421 (Object2 != NULL)
422 );
423
424 IndexedObject1 = (PPTT_NODE_INDEXER *)Object1;
425 IndexedObject2 = (PPTT_NODE_INDEXER *)Object2;
426 ProcNode1 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject1->Object;
427 ProcNode2 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject2->Object;
428
429 if (IS_ACPI_PROC_ID_VALID (ProcNode1) &&
430 IS_ACPI_PROC_ID_VALID (ProcNode2) &&
431 (ProcNode1->AcpiIdObjectToken != CM_NULL_TOKEN) &&
432 (ProcNode2->AcpiIdObjectToken != CM_NULL_TOKEN) &&
433 (ProcNode1->AcpiIdObjectToken == ProcNode2->AcpiIdObjectToken))
434 {
435 DEBUG ((
436 DEBUG_ERROR,
437 "ERROR: PPTT: Two Processor Hierarchy Info objects (%d and %d) map to " \
438 "the same ACPI ID reference object. ACPI Processor IDs are not unique. " \
439 "AcpiIdObjectToken = %p.\n",
440 Index1,
441 Index2,
442 ProcNode1->AcpiIdObjectToken
443 ));
444 return TRUE;
445 }
446
447 return FALSE;
448}
449
467STATIC
473 IN CONST UINT32 NodesStartOffset
474 )
475{
476 EFI_STATUS Status;
478 UINT32 *PrivateResources;
479 BOOLEAN IsAcpiIdObjectTokenDuplicated;
480
481 CM_ARM_GICC_INFO *GicCInfoList;
482 UINT32 GicCInfoCount;
483 UINT32 UniqueGicCRefCount;
484
485 PPTT_NODE_INDEXER *PpttNodeFound;
487
488 PPTT_NODE_INDEXER *ProcNodeIterator;
489 UINT32 NodeCount;
490 UINT32 Length;
491
492 ASSERT (
493 (Generator != NULL) &&
494 (CfgMgrProtocol != NULL) &&
495 (Pptt != NULL)
496 );
497
498 ProcStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)Pptt +
499 NodesStartOffset);
500
501 ProcNodeIterator = Generator->ProcHierarchyNodeIndexedList;
502 NodeCount = Generator->ProcHierarchyNodeCount;
503
504 // Check if every GICC Object is referenced by onlu one Proc Node
505 IsAcpiIdObjectTokenDuplicated = FindDuplicateValue (
506 ProcNodeIterator,
507 NodeCount,
508 sizeof (PPTT_NODE_INDEXER),
510 );
511 // Duplicate GIC CPU Interface Token was found so two PPTT Processor Hierarchy
512 // Nodes map to the same MADT GICC structure
513 if (IsAcpiIdObjectTokenDuplicated) {
514 return EFI_INVALID_PARAMETER;
515 }
516
517 UniqueGicCRefCount = 0;
518
519 while (NodeCount-- != 0) {
520 ProcInfoNode = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)ProcNodeIterator->Object;
521
522 // Check if the private resource count is within the size limit
523 // imposed on the Processor Hierarchy node by the specification.
524 // Note: The length field is 8 bit wide while the number of private
525 // resource field is 32 bit wide.
526 Length = GetProcHierarchyNodeSize (ProcInfoNode);
527 if (Length > MAX_UINT8) {
528 Status = EFI_INVALID_PARAMETER;
529 DEBUG ((
530 DEBUG_ERROR,
531 "ERROR: PPTT: Too many private resources. Count = %d. " \
532 "Maximum supported Processor Node size exceeded. " \
533 "Token = %p. Status = %r\n",
534 ProcInfoNode->NoOfPrivateResources,
535 ProcInfoNode->ParentToken,
536 Status
537 ));
538 return Status;
539 }
540
541 // Populate the node header
542 ProcStruct->Type = EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR;
543 ProcStruct->Length = (UINT8)Length;
544 ProcStruct->Reserved[0] = EFI_ACPI_RESERVED_BYTE;
545 ProcStruct->Reserved[1] = EFI_ACPI_RESERVED_BYTE;
546
547 // Populate the flags
548 ProcStruct->Flags.PhysicalPackage = ProcInfoNode->Flags & BIT0;
549 ProcStruct->Flags.AcpiProcessorIdValid = (ProcInfoNode->Flags & BIT1) >> 1;
550 ProcStruct->Flags.ProcessorIsAThread = (ProcInfoNode->Flags & BIT2) >> 2;
551 ProcStruct->Flags.NodeIsALeaf = (ProcInfoNode->Flags & BIT3) >> 3;
552 ProcStruct->Flags.IdenticalImplementation =
553 (ProcInfoNode->Flags & BIT4) >> 4;
554 ProcStruct->Flags.Reserved = 0;
555
556 // Populate the parent reference
557 if (ProcInfoNode->ParentToken == CM_NULL_TOKEN) {
558 ProcStruct->Parent = 0;
559 } else {
561 Generator->ProcHierarchyNodeIndexedList,
562 Generator->ProcHierarchyNodeCount,
563 ProcInfoNode->ParentToken,
564 &PpttNodeFound
565 );
566 if (EFI_ERROR (Status)) {
567 DEBUG ((
568 DEBUG_ERROR,
569 "ERROR: PPTT: Failed to get parent processor hierarchy node " \
570 "reference. ParentToken = %p. ChildToken = %p. Status = %r\n",
571 ProcInfoNode->ParentToken,
572 ProcInfoNode->Token,
573 Status
574 ));
575 return Status;
576 }
577
578 // Test if the reference is to a 'leaf' node
581 ))
582 {
583 Status = EFI_INVALID_PARAMETER;
584 DEBUG ((
585 DEBUG_ERROR,
586 "ERROR: PPTT: Reference to a leaf Processor Hierarchy Node. " \
587 "ParentToken = %p. ChildToken = %p. Status = %r\n",
588 ProcInfoNode->ParentToken,
589 ProcInfoNode->Token,
590 Status
591 ));
592 return Status;
593 }
594
595 // Update Proc Structure with the offset of the parent node
596 ProcStruct->Parent = PpttNodeFound->Offset;
597
598 // Store the reference for the parent node in the Node Indexer
599 // so that this can be used later for cycle detection
600 ProcNodeIterator->TopologyParent = PpttNodeFound;
601 }
602
603 // Populate ACPI Processor ID
604 if (!IS_ACPI_PROC_ID_VALID (ProcInfoNode)) {
605 // Default invalid ACPI Processor ID to 0
606 ProcStruct->AcpiProcessorId = 0;
607 } else if (ProcInfoNode->AcpiIdObjectToken == CM_NULL_TOKEN) {
608 Status = EFI_INVALID_PARAMETER;
609 DEBUG ((
610 DEBUG_ERROR,
611 "ERROR: PPTT: The 'ACPI Processor ID valid' flag is set but no " \
612 "ACPI ID Reference object token was provided. " \
613 "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n",
614 ProcInfoNode->AcpiIdObjectToken,
615 ProcInfoNode->Token,
616 Status
617 ));
618 return Status;
619 } else {
620 Status = GetEArmObjGicCInfo (
621 CfgMgrProtocol,
622 ProcInfoNode->AcpiIdObjectToken,
623 &GicCInfoList,
624 &GicCInfoCount
625 );
626 if (EFI_ERROR (Status)) {
627 DEBUG ((
628 DEBUG_ERROR,
629 "ERROR: PPTT: Failed to get ACPI ID Reference object token. " \
630 "ACPI Processor ID can't be populated. " \
631 "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n",
632 ProcInfoNode->AcpiIdObjectToken,
633 ProcInfoNode->Token,
634 Status
635 ));
636 return Status;
637 }
638
639 if (GicCInfoCount != 1) {
640 Status = EFI_INVALID_PARAMETER;
641 DEBUG ((
642 DEBUG_ERROR,
643 "ERROR: PPTT: Failed to find a unique GICC structure. " \
644 "ACPI Processor ID can't be populated. " \
645 "GICC Structure Count = %d. AcpiIdObjectToken = %p. RequestorToken = %p " \
646 "Status = %r\n",
647 GicCInfoCount,
648 ProcInfoNode->AcpiIdObjectToken,
649 ProcInfoNode->Token,
650 Status
651 ));
652 return Status;
653 }
654
655 // Update the ACPI Processor Id
656 ProcStruct->AcpiProcessorId = GicCInfoList->AcpiProcessorUid;
657
658 // Increment the reference count for the number of
659 // Unique GICC objects that were retrieved.
660 UniqueGicCRefCount++;
661 }
662
663 ProcStruct->NumberOfPrivateResources = ProcInfoNode->NoOfPrivateResources;
664 PrivateResources = (UINT32 *)((UINT8 *)ProcStruct +
666
667 if (ProcStruct->NumberOfPrivateResources != 0) {
668 // Populate the private resources array
669 Status = AddPrivateResources (
670 Generator,
671 CfgMgrProtocol,
672 PrivateResources,
673 ProcStruct->NumberOfPrivateResources,
674 ProcInfoNode->PrivateResourcesArrayToken
675 );
676 if (EFI_ERROR (Status)) {
677 DEBUG ((
678 DEBUG_ERROR,
679 "ERROR: PPTT: Failed to populate the private resources array. " \
680 "Status = %r\n",
681 Status
682 ));
683 return Status;
684 }
685 }
686
687 // Next Processor Hierarchy Node
688 ProcStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)ProcStruct +
689 ProcStruct->Length);
690 ProcNodeIterator++;
691 } // Processor Hierarchy Node
692
693 // Knowing the total number of GICC references made and that all GICC Token
694 // references are unique, we can test if no GICC instances have been left out.
695 Status = GetEArmObjGicCInfo (
696 CfgMgrProtocol,
698 &GicCInfoList,
699 &GicCInfoCount
700 );
701 if (EFI_ERROR (Status)) {
702 DEBUG ((
703 DEBUG_ERROR,
704 "ERROR: PPTT: Failed to get GICC Info. Status = %r\n",
705 Status
706 ));
707 return Status;
708 }
709
710 // MADT - PPTT cross validation
711 // This checks that one and only one GICC structure is referenced by a
712 // Processor Hierarchy Node in the PPTT.
713 // Since we have already checked that the GICC objects referenced by the
714 // Proc Nodes are unique, the UniqueGicCRefCount cannot be greater than
715 // the total number of GICC objects in the platform.
716 if (GicCInfoCount > UniqueGicCRefCount) {
717 Status = EFI_INVALID_PARAMETER;
718 DEBUG ((
719 DEBUG_ERROR,
720 "ERROR: PPTT: %d GICC structure(s) exposed by MADT don't have " \
721 "a corresponding Processor Hierarchy Node. Status = %r\n",
722 GicCInfoCount - UniqueGicCRefCount,
723 Status
724 ));
725 }
726
727 return Status;
728}
729
740STATIC
741BOOLEAN
743 IN CONST UINT32 CacheId,
744 IN CONST UINT32 *CacheIdList,
745 IN CONST UINT32 CacheIdListSize
746 )
747{
748 UINT32 Index;
749
750 for (Index = 0; Index < CacheIdListSize; Index++) {
751 if (CacheIdList[Index] == CacheId) {
752 return FALSE;
753 }
754 }
755
756 return TRUE;
757}
758
778STATIC
784 IN CONST UINT32 NodesStartOffset,
785 IN CONST UINT32 Revision
786 )
787{
788 EFI_STATUS Status;
790 PPTT_NODE_INDEXER *PpttNodeFound;
791 CM_ARCH_COMMON_CACHE_INFO *CacheInfoNode;
792 PPTT_NODE_INDEXER *CacheNodeIterator;
793 UINT32 NodeCount;
794 BOOLEAN CacheIdUnique;
795 UINT32 NodeIndex;
796 UINT32 *FoundCacheIds;
797
798 ASSERT (
799 (Generator != NULL) &&
800 (CfgMgrProtocol != NULL) &&
801 (Pptt != NULL)
802 );
803
804 CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *)((UINT8 *)Pptt +
805 NodesStartOffset);
806
807 CacheNodeIterator = Generator->CacheStructIndexedList;
808 NodeCount = Generator->CacheStructCount;
809
810 FoundCacheIds = AllocateZeroPool (NodeCount * sizeof (*FoundCacheIds));
811 if (FoundCacheIds == NULL) {
812 DEBUG ((DEBUG_ERROR, "ERROR: PPTT: Failed to allocate resources.\n"));
813 return EFI_OUT_OF_RESOURCES;
814 }
815
816 for (NodeIndex = 0; NodeIndex < NodeCount; NodeIndex++) {
817 CacheInfoNode = (CM_ARCH_COMMON_CACHE_INFO *)CacheNodeIterator->Object;
818
819 // Populate the node header
820 CacheStruct->Type = EFI_ACPI_6_4_PPTT_TYPE_CACHE;
821 CacheStruct->Length = sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE);
822 CacheStruct->Reserved[0] = EFI_ACPI_RESERVED_BYTE;
823 CacheStruct->Reserved[1] = EFI_ACPI_RESERVED_BYTE;
824
825 // "On Arm-based systems, all cache properties must be provided in the
826 // table." (ACPI 6.4, Section 5.2.29.2)
827 CacheStruct->Flags.SizePropertyValid = 1;
828 CacheStruct->Flags.NumberOfSetsValid = 1;
829 CacheStruct->Flags.AssociativityValid = 1;
830 CacheStruct->Flags.AllocationTypeValid = 1;
831 CacheStruct->Flags.CacheTypeValid = 1;
832 CacheStruct->Flags.WritePolicyValid = 1;
833 CacheStruct->Flags.LineSizeValid = 1;
834 CacheStruct->Flags.CacheIdValid = 1;
835 CacheStruct->Flags.Reserved = 0;
836
837 // Populate the reference to the next level of cache
838 if (CacheInfoNode->NextLevelOfCacheToken == CM_NULL_TOKEN) {
839 CacheStruct->NextLevelOfCache = 0;
840 } else {
842 Generator->CacheStructIndexedList,
843 Generator->CacheStructCount,
844 CacheInfoNode->NextLevelOfCacheToken,
845 &PpttNodeFound
846 );
847 if (EFI_ERROR (Status)) {
848 DEBUG ((
849 DEBUG_ERROR,
850 "ERROR: PPTT: Failed to get the reference to the Next Level of " \
851 "Cache. NextLevelOfCacheToken = %p. RequestorToken = %p. " \
852 "Status = %r\n",
853 CacheInfoNode->NextLevelOfCacheToken,
854 CacheInfoNode->Token,
855 Status
856 ));
857 goto cleanup;
858 }
859
860 // Update Cache Structure with the offset for the next level of cache
861 CacheStruct->NextLevelOfCache = PpttNodeFound->Offset;
862
863 // Store the next level of cache information in the Node Indexer
864 // so that this can be used later for cycle detection
865 CacheNodeIterator->TopologyParent = PpttNodeFound;
866 }
867
868 CacheStruct->Size = CacheInfoNode->Size;
869
870 // Validate and populate the 'Number of sets' field
872 Status = EFI_INVALID_PARAMETER;
873 DEBUG ((
874 DEBUG_ERROR,
875 "ERROR: PPTT: When ARMv8.3-CCIDX is implemented the maximum number " \
876 "of sets can be %d. NumberOfSets = %d. Status = %r\n",
878 CacheInfoNode->NumberOfSets,
879 Status
880 ));
881 goto cleanup;
882 }
883
884 if (CacheInfoNode->NumberOfSets > PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX) {
885 DEBUG ((
886 DEBUG_INFO,
887 "INFO: PPTT: When ARMv8.3-CCIDX is not implemented the maximum " \
888 "number of sets can be %d. NumberOfSets = %d\n",
890 CacheInfoNode->NumberOfSets
891 ));
892 }
893
894 CacheStruct->NumberOfSets = CacheInfoNode->NumberOfSets;
895
896 // Validate Associativity field based on maximum associativity
897 // supported by ACPI Cache type structure.
898 if (CacheInfoNode->Associativity > MAX_UINT8) {
899 Status = EFI_INVALID_PARAMETER;
900 DEBUG ((
901 DEBUG_ERROR,
902 "ERROR: PPTT: The maximum associativity supported by ACPI " \
903 "Cache type structure is %d. Associativity = %d, Status = %r\n",
904 MAX_UINT8,
905 CacheInfoNode->Associativity,
906 Status
907 ));
908 goto cleanup;
909 }
910
911 // Validate the Associativity field based on the architecture specification
912 // The architecture supports much larger associativity values than the
913 // current ACPI specification.
914 // These checks will be needed in the future when the ACPI specification
915 // is extended. Disabling this code for now.
916 #if 0
917 if (CacheInfoNode->Associativity > PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX) {
918 Status = EFI_INVALID_PARAMETER;
919 DEBUG ((
920 DEBUG_ERROR,
921 "ERROR: PPTT: When ARMv8.3-CCIDX is implemented the maximum cache " \
922 "associativity can be %d. Associativity = %d. Status = %r\n",
923 PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX,
924 CacheInfoNode->Associativity,
925 Status
926 ));
927 goto cleanup;
928 }
929
930 if (CacheInfoNode->Associativity > PPTT_ARM_CACHE_ASSOCIATIVITY_MAX) {
931 DEBUG ((
932 DEBUG_INFO,
933 "INFO: PPTT: When ARMv8.3-CCIDX is not implemented the maximum " \
934 "cache associativity can be %d. Associativity = %d\n",
935 PPTT_ARM_CACHE_ASSOCIATIVITY_MAX,
936 CacheInfoNode->Associativity
937 ));
938 }
939
940 #endif
941
942 // Note a typecast is needed as the maximum associativity
943 // supported by ACPI Cache type structure is MAX_UINT8.
944 CacheStruct->Associativity = (UINT8)CacheInfoNode->Associativity;
945
946 // Populate cache attributes
947 CacheStruct->Attributes.AllocationType =
948 CacheInfoNode->Attributes & (BIT0 | BIT1);
949 CacheStruct->Attributes.CacheType =
950 (CacheInfoNode->Attributes & (BIT2 | BIT3)) >> 2;
951 CacheStruct->Attributes.WritePolicy =
952 (CacheInfoNode->Attributes & BIT4) >> 4;
953 CacheStruct->Attributes.Reserved = 0;
954
955 // Validate and populate cache line size
956 if ((CacheInfoNode->LineSize < PPTT_ARM_CACHE_LINE_SIZE_MIN) ||
957 (CacheInfoNode->LineSize > PPTT_ARM_CACHE_LINE_SIZE_MAX))
958 {
959 Status = EFI_INVALID_PARAMETER;
960 DEBUG ((
961 DEBUG_ERROR,
962 "ERROR: PPTT: The cache line size must be between %d and %d bytes " \
963 "on ARM Platforms. LineSize = %d. Status = %r\n",
964 PPTT_ARM_CACHE_LINE_SIZE_MIN,
966 CacheInfoNode->LineSize,
967 Status
968 ));
969 goto cleanup;
970 }
971
972 if ((CacheInfoNode->LineSize & (CacheInfoNode->LineSize - 1)) != 0) {
973 Status = EFI_INVALID_PARAMETER;
974 DEBUG ((
975 DEBUG_ERROR,
976 "ERROR: PPTT: The cache line size is not a power of 2. " \
977 "LineSize = %d. Status = %r\n",
978 CacheInfoNode->LineSize,
979 Status
980 ));
981 goto cleanup;
982 }
983
984 CacheStruct->LineSize = CacheInfoNode->LineSize;
985
986 if (Revision >= 3) {
987 // Validate and populate cache id
988 if (CacheInfoNode->CacheId == 0) {
989 Status = EFI_INVALID_PARAMETER;
990 DEBUG ((
991 DEBUG_ERROR,
992 "ERROR: PPTT: The cache id cannot be zero. Status = %r\n",
993 Status
994 ));
995 goto cleanup;
996 }
997
998 CacheIdUnique = IsCacheIdUnique (
999 CacheInfoNode->CacheId,
1000 FoundCacheIds,
1001 NodeIndex
1002 );
1003 if (!CacheIdUnique) {
1004 Status = EFI_INVALID_PARAMETER;
1005 DEBUG ((
1006 DEBUG_ERROR,
1007 "ERROR: PPTT: The cache id is not unique. " \
1008 "CacheId = %d. Status = %r\n",
1009 CacheInfoNode->CacheId,
1010 Status
1011 ));
1012 goto cleanup;
1013 }
1014
1015 // Store the cache id so we can check future cache ids for uniqueness
1016 FoundCacheIds[NodeIndex] = CacheInfoNode->CacheId;
1017
1018 CacheStruct->CacheId = CacheInfoNode->CacheId;
1019 }
1020
1021 // Next Cache Type Structure
1022 CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *)((UINT8 *)CacheStruct +
1023 CacheStruct->Length);
1024 CacheNodeIterator++;
1025 } // for Cache Type Structure
1026
1027 Status = EFI_SUCCESS;
1028
1029cleanup:
1030 FreePool (FoundCacheIds);
1031
1032 return Status;
1033}
1034
1058STATIC
1060EFIAPI
1066 )
1067{
1068 EFI_STATUS Status;
1069 UINT32 TableSize;
1070 UINT32 ProcTopologyStructCount;
1071 UINT32 ProcHierarchyNodeCount;
1072 UINT32 CacheStructCount;
1073
1074 UINT32 ProcHierarchyNodeOffset;
1075 UINT32 CacheStructOffset;
1076
1077 CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList;
1078 CM_ARCH_COMMON_CACHE_INFO *CacheStructList;
1079
1081
1082 // Pointer to the Node Indexer array
1083 PPTT_NODE_INDEXER *NodeIndexer;
1084
1086
1087 ASSERT (
1088 (This != NULL) &&
1089 (AcpiTableInfo != NULL) &&
1090 (CfgMgrProtocol != NULL) &&
1091 (Table != NULL) &&
1092 (AcpiTableInfo->TableGeneratorId == This->GeneratorID) &&
1093 (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature)
1094 );
1095
1096 if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
1097 (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
1098 {
1099 DEBUG ((
1100 DEBUG_ERROR,
1101 "ERROR: PPTT: Requested table revision = %d is not supported. "
1102 "Supported table revisions: Minimum = %d. Maximum = %d\n",
1103 AcpiTableInfo->AcpiTableRevision,
1104 This->MinAcpiTableRevision,
1105 This->AcpiTableRevision
1106 ));
1107 return EFI_INVALID_PARAMETER;
1108 }
1109
1111 *Table = NULL;
1112
1113 // Get the processor hierarchy info and update the processor topology
1114 // structure count with Processor Hierarchy Nodes (Type 0)
1115 Status = GetEArchCommonObjProcHierarchyInfo (
1116 CfgMgrProtocol,
1118 &ProcHierarchyNodeList,
1119 &ProcHierarchyNodeCount
1120 );
1121 if (EFI_ERROR (Status)) {
1122 DEBUG ((
1123 DEBUG_ERROR,
1124 "ERROR: PPTT: Failed to get processor hierarchy info. Status = %r\n",
1125 Status
1126 ));
1127 goto error_handler;
1128 }
1129
1130 ProcTopologyStructCount = ProcHierarchyNodeCount;
1131 Generator->ProcHierarchyNodeCount = ProcHierarchyNodeCount;
1132
1133 // Get the cache info and update the processor topology structure count with
1134 // Cache Type Structures (Type 1)
1135 Status = GetEArchCommonObjCacheInfo (
1136 CfgMgrProtocol,
1138 &CacheStructList,
1139 &CacheStructCount
1140 );
1141 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
1142 DEBUG ((
1143 DEBUG_ERROR,
1144 "ERROR: PPTT: Failed to get cache info. Status = %r\n",
1145 Status
1146 ));
1147 goto error_handler;
1148 }
1149
1150 ProcTopologyStructCount += CacheStructCount;
1151 Generator->CacheStructCount = CacheStructCount;
1152
1153 // Allocate Node Indexer array
1154 NodeIndexer = (PPTT_NODE_INDEXER *)AllocateZeroPool (
1155 sizeof (PPTT_NODE_INDEXER) *
1156 ProcTopologyStructCount
1157 );
1158 if (NodeIndexer == NULL) {
1159 Status = EFI_OUT_OF_RESOURCES;
1160 DEBUG ((
1161 DEBUG_ERROR,
1162 "ERROR: PPTT: Failed to allocate memory for Node Indexer. Status = %r\n ",
1163 Status
1164 ));
1165 goto error_handler;
1166 }
1167
1168 DEBUG ((DEBUG_INFO, "INFO: NodeIndexer = %p\n", NodeIndexer));
1169 Generator->ProcTopologyStructCount = ProcTopologyStructCount;
1170 Generator->NodeIndexer = NodeIndexer;
1171
1172 // Calculate the size of the PPTT table
1174
1175 // Include the size of Processor Hierarchy Nodes and index them
1176 if (Generator->ProcHierarchyNodeCount != 0) {
1177 ProcHierarchyNodeOffset = TableSize;
1178 Generator->ProcHierarchyNodeIndexedList = NodeIndexer;
1179 TableSize += GetSizeofProcHierarchyNodes (
1180 ProcHierarchyNodeOffset,
1181 ProcHierarchyNodeList,
1182 Generator->ProcHierarchyNodeCount,
1183 &NodeIndexer
1184 );
1185
1186 DEBUG ((
1187 DEBUG_INFO,
1188 " ProcHierarchyNodeCount = %d\n" \
1189 " ProcHierarchyNodeOffset = 0x%x\n" \
1190 " ProcHierarchyNodeIndexedList = 0x%p\n",
1191 Generator->ProcHierarchyNodeCount,
1192 ProcHierarchyNodeOffset,
1193 Generator->ProcHierarchyNodeIndexedList
1194 ));
1195 }
1196
1197 // Include the size of Cache Type Structures and index them
1198 if (Generator->CacheStructCount != 0) {
1199 CacheStructOffset = TableSize;
1200 Generator->CacheStructIndexedList = NodeIndexer;
1201 TableSize += GetSizeofCacheTypeStructs (
1202 CacheStructOffset,
1203 CacheStructList,
1204 Generator->CacheStructCount,
1205 &NodeIndexer
1206 );
1207 DEBUG ((
1208 DEBUG_INFO,
1209 " CacheStructCount = %d\n" \
1210 " CacheStructOffset = 0x%x\n" \
1211 " CacheStructIndexedList = 0x%p\n",
1212 Generator->CacheStructCount,
1213 CacheStructOffset,
1214 Generator->CacheStructIndexedList
1215 ));
1216 }
1217
1218 DEBUG ((
1219 DEBUG_INFO,
1220 "INFO: PPTT:\n" \
1221 " ProcTopologyStructCount = %d\n" \
1222 " TableSize = %d\n",
1223 ProcTopologyStructCount,
1224 TableSize
1225 ));
1226
1227 // Allocate the Buffer for the PPTT table
1228 *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
1229 if (*Table == NULL) {
1230 Status = EFI_OUT_OF_RESOURCES;
1231 DEBUG ((
1232 DEBUG_ERROR,
1233 "ERROR: PPTT: Failed to allocate memory for PPTT Table. " \
1234 "Size = %d. Status = %r\n",
1235 TableSize,
1236 Status
1237 ));
1238 goto error_handler;
1239 }
1240
1242
1243 DEBUG ((
1244 DEBUG_INFO,
1245 "PPTT: Pptt = 0x%p. TableSize = 0x%x\n",
1246 Pptt,
1247 TableSize
1248 ));
1249
1250 // Add ACPI header
1251 Status = AddAcpiHeader (
1252 CfgMgrProtocol,
1253 This,
1254 &Pptt->Header,
1255 AcpiTableInfo,
1256 TableSize
1257 );
1258 if (EFI_ERROR (Status)) {
1259 DEBUG ((
1260 DEBUG_ERROR,
1261 "ERROR: PPTT: Failed to add ACPI header. Status = %r\n",
1262 Status
1263 ));
1264 goto error_handler;
1265 }
1266
1267 // Add Processor Hierarchy Nodes (Type 0) to the generated table
1268 if (Generator->ProcHierarchyNodeCount != 0) {
1269 Status = AddProcHierarchyNodes (
1270 Generator,
1271 CfgMgrProtocol,
1272 Pptt,
1273 ProcHierarchyNodeOffset
1274 );
1275 if (EFI_ERROR (Status)) {
1276 DEBUG ((
1277 DEBUG_ERROR,
1278 "ERROR: PPTT: Failed to add Processor Hierarchy Nodes. Status = %r\n",
1279 Status
1280 ));
1281 goto error_handler;
1282 }
1283 }
1284
1285 // Add Cache Type Structures (Type 1) to the generated table
1286 if (Generator->CacheStructCount != 0) {
1287 Status = AddCacheTypeStructures (
1288 Generator,
1289 CfgMgrProtocol,
1290 Pptt,
1291 CacheStructOffset,
1292 AcpiTableInfo->AcpiTableRevision
1293 );
1294 if (EFI_ERROR (Status)) {
1295 DEBUG ((
1296 DEBUG_ERROR,
1297 "ERROR: PPTT: Failed to add Cache Type Structures. Status = %r\n",
1298 Status
1299 ));
1300 goto error_handler;
1301 }
1302 }
1303
1304 // Validate CM object cross-references in PPTT
1306 if (EFI_ERROR (Status)) {
1307 DEBUG ((
1308 DEBUG_ERROR,
1309 "ERROR: PPTT: Invalid processor and cache topology. Status = %r\n",
1310 Status
1311 ));
1312 goto error_handler;
1313 }
1314
1315 return Status;
1316
1317error_handler:
1318 if (Generator->NodeIndexer != NULL) {
1319 FreePool (Generator->NodeIndexer);
1320 Generator->NodeIndexer = NULL;
1321 }
1322
1323 if (*Table != NULL) {
1324 FreePool (*Table);
1325 *Table = NULL;
1326 }
1327
1328 return Status;
1329}
1330
1343STATIC
1345EFIAPI
1351 )
1352{
1354
1355 ASSERT (
1356 (This != NULL) &&
1357 (AcpiTableInfo != NULL) &&
1358 (CfgMgrProtocol != NULL) &&
1359 (AcpiTableInfo->TableGeneratorId == This->GeneratorID) &&
1360 (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature)
1361 );
1362
1364
1365 // Free any memory allocated by the generator
1366 if (Generator->NodeIndexer != NULL) {
1367 FreePool (Generator->NodeIndexer);
1368 Generator->NodeIndexer = NULL;
1369 }
1370
1371 if ((Table == NULL) || (*Table == NULL)) {
1372 DEBUG ((DEBUG_ERROR, "ERROR: PPTT: Invalid Table Pointer\n"));
1373 ASSERT (
1374 (Table != NULL) &&
1375 (*Table != NULL)
1376 );
1377 return EFI_INVALID_PARAMETER;
1378 }
1379
1380 FreePool (*Table);
1381 *Table = NULL;
1382 return EFI_SUCCESS;
1383}
1384
1387#define PPTT_GENERATOR_REVISION CREATE_REVISION (1, 0)
1388
1391STATIC
1393 // ACPI table generator header
1394 {
1395 // Generator ID
1397 // Generator Description
1398 L"ACPI.STD.PPTT.GENERATOR",
1399 // ACPI Table Signature
1401 // ACPI Table Revision supported by this Generator
1403 // Minimum supported ACPI Table Revision
1405 // Creator ID
1407 // Creator Revision
1409 // Build Table function
1411 // Free Resource function
1413 // Extended build function not needed
1414 NULL,
1415 // Extended build function not implemented by the generator.
1416 // Hence extended free resource function is not required.
1417 NULL
1418 },
1419
1420 // PPTT Generator private data
1421
1422 // Processor topology node count
1423 0,
1424 // Count of Processor Hierarchy Nodes
1425 0,
1426 // Count of Cache Structures
1427 0,
1428 // Pointer to PPTT Node Indexer
1429 NULL
1430};
1431
1444EFIAPI
1446 IN EFI_HANDLE ImageHandle,
1447 IN EFI_SYSTEM_TABLE *SystemTable
1448 )
1449{
1450 EFI_STATUS Status;
1451
1453 DEBUG ((DEBUG_INFO, "PPTT: Register Generator. Status = %r\n", Status));
1454 ASSERT_EFI_ERROR (Status);
1455 return Status;
1456}
1457
1469EFIAPI
1471 IN EFI_HANDLE ImageHandle,
1472 IN EFI_SYSTEM_TABLE *SystemTable
1473 )
1474{
1475 EFI_STATUS Status;
1476
1478 DEBUG ((DEBUG_INFO, "PPTT: Deregister Generator. Status = %r\n", Status));
1479 ASSERT_EFI_ERROR (Status);
1480 return Status;
1481}
UINT64 UINTN
#define EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION
Definition: Acpi63.h:2532
#define EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR
Definition: Acpi64.h:2649
#define EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE
Definition: Acpi64.h:2970
#define EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION
Definition: Acpi64.h:2644
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
@ EStdAcpiTableIdPptt
PPTT Generator.
@ EArchCommonObjCacheInfo
17 - Cache Info
@ EArchCommonObjCmRef
7 - CM Object Reference
@ EArchCommonObjProcHierarchyInfo
16 - Processor Hierarchy Info
@ EArmObjGicCInfo
2 - GIC CPU Interface Info
#define GET_OBJECT_LIST(CmObjectNameSpace, CmObjectId, Type)
@ EObjNameSpaceArm
ARM Objects Namespace.
@ 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 ACPI_PPTT_GENERATOR PpttGenerator
STATIC UINT32 GetProcHierarchyNodeSize(IN CONST CM_ARCH_COMMON_PROC_HIERARCHY_INFO *Node)
Definition: PpttGenerator.c:92
STATIC EFI_STATUS DetectCyclesInTopology(IN CONST ACPI_PPTT_GENERATOR *CONST Generator)
STATIC BOOLEAN IsCacheIdUnique(IN CONST UINT32 CacheId, IN CONST UINT32 *CacheIdList, IN CONST UINT32 CacheIdListSize)
EFI_STATUS EFIAPI AcpiPpttLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
#define PPTT_GENERATOR_REVISION
STATIC EFI_STATUS AddPrivateResources(IN CONST ACPI_PPTT_GENERATOR *CONST Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN UINT32 *PrivResArray, IN UINT32 PrivResCount, IN CONST CM_OBJECT_TOKEN PrivResArrayToken)
BOOLEAN EFIAPI IsAcpiIdObjectTokenEqual(IN CONST VOID *Object1, IN CONST VOID *Object2, IN UINTN Index1, IN UINTN Index2)
STATIC EFI_STATUS GetPpttNodeReferencedByToken(IN PPTT_NODE_INDEXER *NodeIndexer, IN UINT32 NodeCount, IN CONST CM_OBJECT_TOKEN SearchToken, OUT PPTT_NODE_INDEXER **IndexedNodeFound)
STATIC EFI_STATUS EFIAPI BuildPpttTable(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 AddProcHierarchyNodes(IN CONST ACPI_PPTT_GENERATOR *CONST Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CONST EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *Pptt, IN CONST UINT32 NodesStartOffset)
EFI_STATUS EFIAPI AcpiPpttLibDestructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC EFI_STATUS EFIAPI FreePpttTableResources(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 AddCacheTypeStructures(IN CONST ACPI_PPTT_GENERATOR *CONST Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CONST EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *Pptt, IN CONST UINT32 NodesStartOffset, IN CONST UINT32 Revision)
#define GET_SIZE_OF_PPTT_STRUCTS( PpttObjName, PpttObjSize, CmObjectType)
Definition: PpttGenerator.h:92
#define PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX
Definition: PpttGenerator.h:24
#define IS_ACPI_PROC_ID_VALID(Node)
Definition: PpttGenerator.h:47
#define IS_PROC_NODE_LEAF(Node)
Definition: PpttGenerator.h:43
#define PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX
Definition: PpttGenerator.h:30
#define PPTT_ARM_CACHE_LINE_SIZE_MAX
Definition: PpttGenerator.h:38
UINTN CM_OBJECT_TOKEN
#define CM_NULL_TOKEN
EFI_STATUS EFIAPI AddAcpiHeader(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CONST ACPI_TABLE_GENERATOR *CONST Generator, IN OUT EFI_ACPI_DESCRIPTION_HEADER *CONST AcpiHeader, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST UINT32 Length)
Definition: TableHelper.c:114
BOOLEAN EFIAPI FindDuplicateValue(IN CONST VOID *Array, IN CONST UINTN Count, IN CONST UINTN ElementSize, IN PFN_IS_EQUAL EqualTestFunction)
Definition: TableHelper.c:299
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
ACPI_TABLE_GENERATOR Header
ACPI Table generator header.
UINT32 CacheId
Unique ID for the cache.
UINT8 Attributes
Cache attributes (ACPI 6.4 - January 2021, PPTT, Table 5.140)
UINT32 Size
Size of the cache in bytes.
UINT32 NumberOfSets
Number of sets in the cache.
UINT16 LineSize
Line size in bytes.
CM_OBJECT_TOKEN Token
A unique token used to identify this object.
CM_OBJECT_TOKEN ReferenceToken
Token of the CM object being referenced.
UINT32 NoOfPrivateResources
Number of resources private to this Node.
CM_OBJECT_TOKEN Token
A unique token used to identify this object.
UINT32 Flags
Processor structure flags (ACPI 6.3 - January 2019, PPTT, Table 5-155)
struct PpttNodeIndexer * TopologyParent
CM_OBJECT_TOKEN Token
Unique identifier for the node.
VOID * Object
Pointer to the CM object being indexed.
UINT32 CycleDetectionStamp