4 Copyright (c) 2019 - 2020, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
8 - ACPI 6.3 Specification - January 2019
9 - ARM Architecture Reference Manual ARMv8 (D.a)
12 #include <Library/PrintLib.h>
13 #include <Library/UefiLib.h>
14 #include "AcpiParser.h"
16 #include "AcpiViewConfig.h"
17 #include "PpttParser.h"
20 STATIC CONST UINT8
* ProcessorTopologyStructureType
;
21 STATIC CONST UINT8
* ProcessorTopologyStructureLength
;
22 STATIC CONST UINT32
* NumberOfPrivateResources
;
23 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo
;
26 This function validates the Cache Type Structure (Type 1) 'Number of sets'
29 @param [in] Ptr Pointer to the start of the field data.
30 @param [in] Context Pointer to context specific information e.g. this
31 could be a pointer to the ACPI table header.
36 ValidateCacheNumberOfSets (
42 NumberOfSets
= *(UINT32
*)Ptr
;
44 if (NumberOfSets
== 0) {
45 IncrementErrorCount ();
46 Print (L
"\nERROR: Cache number of sets must be greater than 0");
50 #if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
51 if (NumberOfSets
> PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX
) {
52 IncrementErrorCount ();
54 L
"\nERROR: When ARMv8.3-CCIDX is implemented the maximum cache number of "
55 L
"sets must be less than or equal to %d",
56 PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX
61 if (NumberOfSets
> PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX
) {
62 IncrementWarningCount ();
64 L
"\nWARNING: Without ARMv8.3-CCIDX, the maximum cache number of sets "
65 L
"must be less than or equal to %d. Ignore this message if "
66 L
"ARMv8.3-CCIDX is implemented",
67 PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX
76 This function validates the Cache Type Structure (Type 1) 'Associativity'
79 @param [in] Ptr Pointer to the start of the field data.
80 @param [in] Context Pointer to context specific information e.g. this
81 could be a pointer to the ACPI table header.
86 ValidateCacheAssociativity (
92 Associativity
= *(UINT8
*)Ptr
;
94 if (Associativity
== 0) {
95 IncrementErrorCount ();
96 Print (L
"\nERROR: Cache associativity must be greater than 0");
102 This function validates the Cache Type Structure (Type 1) Line size field.
104 @param [in] Ptr Pointer to the start of the field data.
105 @param [in] Context Pointer to context specific information e.g. this
106 could be a pointer to the ACPI table header.
111 ValidateCacheLineSize (
116 #if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
117 // Reference: ARM Architecture Reference Manual ARMv8 (D.a)
118 // Section D12.2.25: CCSIDR_EL1, Current Cache Size ID Register
119 // LineSize, bits [2:0]
120 // (Log2(Number of bytes in cache line)) - 4.
123 LineSize
= *(UINT16
*)Ptr
;
125 if ((LineSize
< PPTT_ARM_CACHE_LINE_SIZE_MIN
) ||
126 (LineSize
> PPTT_ARM_CACHE_LINE_SIZE_MAX
)) {
127 IncrementErrorCount ();
129 L
"\nERROR: The cache line size must be between %d and %d bytes"
130 L
" on ARM Platforms.",
131 PPTT_ARM_CACHE_LINE_SIZE_MIN
,
132 PPTT_ARM_CACHE_LINE_SIZE_MAX
137 if ((LineSize
& (LineSize
- 1)) != 0) {
138 IncrementErrorCount ();
139 Print (L
"\nERROR: The cache line size is not a power of 2.");
145 This function validates the Cache Type Structure (Type 1) Attributes field.
147 @param [in] Ptr Pointer to the start of the field data.
148 @param [in] Context Pointer to context specific information e.g. this
149 could be a pointer to the ACPI table header.
154 ValidateCacheAttributes (
159 // Reference: Advanced Configuration and Power Interface (ACPI) Specification
160 // Version 6.2 Errata A, September 2017
161 // Table 5-153: Cache Type Structure
163 Attributes
= *(UINT8
*)Ptr
;
165 if ((Attributes
& 0xE0) != 0) {
166 IncrementErrorCount ();
168 L
"\nERROR: Attributes bits [7:5] are reserved and must be zero.",
176 An ACPI_PARSER array describing the ACPI PPTT Table.
178 STATIC CONST ACPI_PARSER PpttParser
[] = {
179 PARSE_ACPI_HEADER (&AcpiHdrInfo
)
183 An ACPI_PARSER array describing the processor topology structure header.
185 STATIC CONST ACPI_PARSER ProcessorTopologyStructureHeaderParser
[] = {
186 {L
"Type", 1, 0, NULL
, NULL
, (VOID
**)&ProcessorTopologyStructureType
,
188 {L
"Length", 1, 1, NULL
, NULL
, (VOID
**)&ProcessorTopologyStructureLength
,
190 {L
"Reserved", 2, 2, NULL
, NULL
, NULL
, NULL
, NULL
}
194 An ACPI_PARSER array describing the Processor Hierarchy Node Structure - Type 0.
196 STATIC CONST ACPI_PARSER ProcessorHierarchyNodeStructureParser
[] = {
197 {L
"Type", 1, 0, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
198 {L
"Length", 1, 1, L
"%d", NULL
, NULL
, NULL
, NULL
},
199 {L
"Reserved", 2, 2, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
201 {L
"Flags", 4, 4, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
202 {L
"Parent", 4, 8, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
203 {L
"ACPI Processor ID", 4, 12, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
204 {L
"Number of private resources", 4, 16, L
"%d", NULL
,
205 (VOID
**)&NumberOfPrivateResources
, NULL
, NULL
}
209 An ACPI_PARSER array describing the Cache Type Structure - Type 1.
211 STATIC CONST ACPI_PARSER CacheTypeStructureParser
[] = {
212 {L
"Type", 1, 0, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
213 {L
"Length", 1, 1, L
"%d", NULL
, NULL
, NULL
, NULL
},
214 {L
"Reserved", 2, 2, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
216 {L
"Flags", 4, 4, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
217 {L
"Next Level of Cache", 4, 8, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
218 {L
"Size", 4, 12, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
219 {L
"Number of sets", 4, 16, L
"%d", NULL
, NULL
, ValidateCacheNumberOfSets
, NULL
},
220 {L
"Associativity", 1, 20, L
"%d", NULL
, NULL
, ValidateCacheAssociativity
, NULL
},
221 {L
"Attributes", 1, 21, L
"0x%x", NULL
, NULL
, ValidateCacheAttributes
, NULL
},
222 {L
"Line size", 2, 22, L
"%d", NULL
, NULL
, ValidateCacheLineSize
, NULL
}
226 An ACPI_PARSER array describing the ID Type Structure - Type 2.
228 STATIC CONST ACPI_PARSER IdStructureParser
[] = {
229 {L
"Type", 1, 0, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
230 {L
"Length", 1, 1, L
"%d", NULL
, NULL
, NULL
, NULL
},
231 {L
"Reserved", 2, 2, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
233 {L
"VENDOR_ID", 4, 4, NULL
, Dump4Chars
, NULL
, NULL
, NULL
},
234 {L
"LEVEL_1_ID", 8, 8, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
235 {L
"LEVEL_2_ID", 8, 16, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
236 {L
"MAJOR_REV", 2, 24, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
237 {L
"MINOR_REV", 2, 26, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
238 {L
"SPIN_REV", 2, 28, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
242 This function parses the Processor Hierarchy Node Structure (Type 0).
244 @param [in] Ptr Pointer to the start of the Processor Hierarchy Node
246 @param [in] Length Length of the Processor Hierarchy Node Structure.
250 DumpProcessorHierarchyNodeStructure (
257 CHAR16 Buffer
[OUTPUT_FIELD_COLUMN_WIDTH
];
262 "Processor Hierarchy Node Structure",
265 PARSER_PARAMS (ProcessorHierarchyNodeStructureParser
)
268 // Check if the values used to control the parsing logic have been
269 // successfully read.
270 if (NumberOfPrivateResources
== NULL
) {
271 IncrementErrorCount ();
273 L
"ERROR: Insufficient Processor Hierarchy Node length. Length = %d.\n",
279 // Make sure the Private Resource array lies inside this structure
280 if (Offset
+ (*NumberOfPrivateResources
* sizeof (UINT32
)) > Length
) {
281 IncrementErrorCount ();
283 L
"ERROR: Invalid Number of Private Resources. " \
284 L
"PrivateResourceCount = %d. RemainingBufferLength = %d. " \
285 L
"Parsing of this structure aborted.\n",
286 *NumberOfPrivateResources
,
294 // Parse the specified number of private resource references or the Processor
295 // Hierarchy Node length. Whichever is minimum.
296 while (Index
< *NumberOfPrivateResources
) {
300 L
"Private resources [%d]",
304 PrintFieldName (4, Buffer
);
307 *((UINT32
*)(Ptr
+ Offset
))
310 Offset
+= sizeof (UINT32
);
316 This function parses the Cache Type Structure (Type 1).
318 @param [in] Ptr Pointer to the start of the Cache Type Structure data.
319 @param [in] Length Length of the Cache Type Structure.
323 DumpCacheTypeStructure (
331 "Cache Type Structure",
334 PARSER_PARAMS (CacheTypeStructureParser
)
339 This function parses the ID Structure (Type 2).
341 @param [in] Ptr Pointer to the start of the ID Structure data.
342 @param [in] Length Length of the ID Structure.
357 PARSER_PARAMS (IdStructureParser
)
362 This function parses the ACPI PPTT table.
363 When trace is enabled this function parses the PPTT table and
364 traces the ACPI table fields.
366 This function parses the following processor topology structures:
367 - Processor hierarchy node structure (Type 0)
368 - Cache Type Structure (Type 1)
369 - ID structure (Type 2)
371 This function also performs validation of the ACPI table fields.
373 @param [in] Trace If TRUE, trace the ACPI fields.
374 @param [in] Ptr Pointer to the start of the buffer.
375 @param [in] AcpiTableLength Length of the ACPI table.
376 @param [in] AcpiTableRevision Revision of the ACPI table.
383 IN UINT32 AcpiTableLength
,
384 IN UINT8 AcpiTableRevision
388 UINT8
* ProcessorTopologyStructurePtr
;
400 PARSER_PARAMS (PpttParser
)
403 ProcessorTopologyStructurePtr
= Ptr
+ Offset
;
405 while (Offset
< AcpiTableLength
) {
406 // Parse Processor Hierarchy Node Structure to obtain Type and Length.
411 ProcessorTopologyStructurePtr
,
412 AcpiTableLength
- Offset
,
413 PARSER_PARAMS (ProcessorTopologyStructureHeaderParser
)
416 // Check if the values used to control the parsing logic have been
417 // successfully read.
418 if ((ProcessorTopologyStructureType
== NULL
) ||
419 (ProcessorTopologyStructureLength
== NULL
)) {
420 IncrementErrorCount ();
422 L
"ERROR: Insufficient remaining table buffer length to read the " \
423 L
"processor topology structure header. Length = %d.\n",
424 AcpiTableLength
- Offset
429 // Validate Processor Topology Structure length
430 if ((*ProcessorTopologyStructureLength
== 0) ||
431 ((Offset
+ (*ProcessorTopologyStructureLength
)) > AcpiTableLength
)) {
432 IncrementErrorCount ();
434 L
"ERROR: Invalid Processor Topology Structure length. " \
435 L
"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
436 *ProcessorTopologyStructureLength
,
443 PrintFieldName (2, L
"* Structure Offset *");
444 Print (L
"0x%x\n", Offset
);
446 switch (*ProcessorTopologyStructureType
) {
447 case EFI_ACPI_6_2_PPTT_TYPE_PROCESSOR
:
448 DumpProcessorHierarchyNodeStructure (
449 ProcessorTopologyStructurePtr
,
450 *ProcessorTopologyStructureLength
453 case EFI_ACPI_6_2_PPTT_TYPE_CACHE
:
454 DumpCacheTypeStructure (
455 ProcessorTopologyStructurePtr
,
456 *ProcessorTopologyStructureLength
459 case EFI_ACPI_6_2_PPTT_TYPE_ID
:
461 ProcessorTopologyStructurePtr
,
462 *ProcessorTopologyStructureLength
466 IncrementErrorCount ();
468 L
"ERROR: Unknown processor topology structure:"
469 L
" Type = %d, Length = %d\n",
470 *ProcessorTopologyStructureType
,
471 *ProcessorTopologyStructureLength
475 ProcessorTopologyStructurePtr
+= *ProcessorTopologyStructureLength
;
476 Offset
+= *ProcessorTopologyStructureLength
;