4 Copyright (c) 2019 - 2021, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
8 - ACPI 6.4 Specification - January 2021
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 (
43 NumberOfSets
= *(UINT32
*)Ptr
;
45 if (NumberOfSets
== 0) {
46 IncrementErrorCount ();
47 Print (L
"\nERROR: Cache number of sets must be greater than 0");
51 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
52 if (NumberOfSets
> PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX
) {
53 IncrementErrorCount ();
55 L
"\nERROR: When ARMv8.3-CCIDX is implemented the maximum cache number of "
56 L
"sets must be less than or equal to %d",
57 PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX
62 if (NumberOfSets
> PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX
) {
63 IncrementWarningCount ();
65 L
"\nWARNING: Without ARMv8.3-CCIDX, the maximum cache number of sets "
66 L
"must be less than or equal to %d. Ignore this message if "
67 L
"ARMv8.3-CCIDX is implemented",
68 PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX
77 This function validates the Cache Type Structure (Type 1) 'Associativity'
80 @param [in] Ptr Pointer to the start of the field data.
81 @param [in] Context Pointer to context specific information e.g. this
82 could be a pointer to the ACPI table header.
87 ValidateCacheAssociativity (
94 Associativity
= *(UINT8
*)Ptr
;
96 if (Associativity
== 0) {
97 IncrementErrorCount ();
98 Print (L
"\nERROR: Cache associativity must be greater than 0");
104 This function validates the Cache Type Structure (Type 1) Line size field.
106 @param [in] Ptr Pointer to the start of the field data.
107 @param [in] Context Pointer to context specific information e.g. this
108 could be a pointer to the ACPI table header.
113 ValidateCacheLineSize (
118 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
119 // Reference: ARM Architecture Reference Manual ARMv8 (D.a)
120 // Section D12.2.25: CCSIDR_EL1, Current Cache Size ID Register
121 // LineSize, bits [2:0]
122 // (Log2(Number of bytes in cache line)) - 4.
125 LineSize
= *(UINT16
*)Ptr
;
127 if ((LineSize
< PPTT_ARM_CACHE_LINE_SIZE_MIN
) ||
128 (LineSize
> PPTT_ARM_CACHE_LINE_SIZE_MAX
))
130 IncrementErrorCount ();
132 L
"\nERROR: The cache line size must be between %d and %d bytes"
133 L
" on ARM Platforms.",
134 PPTT_ARM_CACHE_LINE_SIZE_MIN
,
135 PPTT_ARM_CACHE_LINE_SIZE_MAX
140 if ((LineSize
& (LineSize
- 1)) != 0) {
141 IncrementErrorCount ();
142 Print (L
"\nERROR: The cache line size is not a power of 2.");
149 This function validates the Cache Type Structure (Type 1) Attributes field.
151 @param [in] Ptr Pointer to the start of the field data.
152 @param [in] Context Pointer to context specific information e.g. this
153 could be a pointer to the ACPI table header.
158 ValidateCacheAttributes (
163 // Reference: Advanced Configuration and Power Interface (ACPI) Specification
164 // Version 6.4, January 2021
165 // Table 5-140: Cache Type Structure
168 Attributes
= *(UINT8
*)Ptr
;
170 if ((Attributes
& 0xE0) != 0) {
171 IncrementErrorCount ();
173 L
"\nERROR: Attributes bits [7:5] are reserved and must be zero.",
181 An ACPI_PARSER array describing the ACPI PPTT Table.
183 STATIC CONST ACPI_PARSER PpttParser
[] = {
184 PARSE_ACPI_HEADER (&AcpiHdrInfo
)
188 An ACPI_PARSER array describing the processor topology structure header.
190 STATIC CONST ACPI_PARSER ProcessorTopologyStructureHeaderParser
[] = {
191 { L
"Type", 1, 0, NULL
, NULL
, (VOID
**)&ProcessorTopologyStructureType
,
193 { L
"Length", 1, 1, NULL
, NULL
, (VOID
**)&ProcessorTopologyStructureLength
,
195 { L
"Reserved", 2, 2, NULL
, NULL
, NULL
, NULL
,NULL
}
199 An ACPI_PARSER array describing the Processor Hierarchy Node Structure - Type 0.
201 STATIC CONST ACPI_PARSER ProcessorHierarchyNodeStructureParser
[] = {
202 { L
"Type", 1, 0, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
203 { L
"Length", 1, 1, L
"%d", NULL
, NULL
, NULL
, NULL
},
204 { L
"Reserved", 2, 2, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
206 { L
"Flags", 4, 4, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
207 { L
"Parent", 4, 8, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
208 { L
"ACPI Processor ID", 4, 12, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
209 { L
"Number of private resources", 4, 16, L
"%d", NULL
,
210 (VOID
**)&NumberOfPrivateResources
, NULL
, NULL
}
214 An ACPI_PARSER array describing the Cache Type Structure - Type 1.
216 STATIC CONST ACPI_PARSER CacheTypeStructureParser
[] = {
217 { L
"Type", 1, 0, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
218 { L
"Length", 1, 1, L
"%d", NULL
, NULL
, NULL
, NULL
},
219 { L
"Reserved", 2, 2, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
221 { L
"Flags", 4, 4, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
222 { L
"Next Level of Cache", 4, 8, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
223 { L
"Size", 4, 12, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
224 { L
"Number of sets", 4, 16, L
"%d", NULL
, NULL
, ValidateCacheNumberOfSets
, NULL
},
225 { L
"Associativity", 1, 20, L
"%d", NULL
, NULL
, ValidateCacheAssociativity
, NULL
},
226 { L
"Attributes", 1, 21, L
"0x%x", NULL
, NULL
, ValidateCacheAttributes
, NULL
},
227 { L
"Line size", 2, 22, L
"%d", NULL
, NULL
, ValidateCacheLineSize
, NULL
}
231 This function parses the Processor Hierarchy Node Structure (Type 0).
233 @param [in] Ptr Pointer to the start of the Processor Hierarchy Node
235 @param [in] Length Length of the Processor Hierarchy Node Structure.
239 DumpProcessorHierarchyNodeStructure (
246 CHAR16 Buffer
[OUTPUT_FIELD_COLUMN_WIDTH
];
251 "Processor Hierarchy Node Structure",
254 PARSER_PARAMS (ProcessorHierarchyNodeStructureParser
)
257 // Check if the values used to control the parsing logic have been
258 // successfully read.
259 if (NumberOfPrivateResources
== NULL
) {
260 IncrementErrorCount ();
262 L
"ERROR: Insufficient Processor Hierarchy Node length. Length = %d.\n",
268 // Make sure the Private Resource array lies inside this structure
269 if (Offset
+ (*NumberOfPrivateResources
* sizeof (UINT32
)) > Length
) {
270 IncrementErrorCount ();
272 L
"ERROR: Invalid Number of Private Resources. " \
273 L
"PrivateResourceCount = %d. RemainingBufferLength = %d. " \
274 L
"Parsing of this structure aborted.\n",
275 *NumberOfPrivateResources
,
283 // Parse the specified number of private resource references or the Processor
284 // Hierarchy Node length. Whichever is minimum.
285 while (Index
< *NumberOfPrivateResources
) {
289 L
"Private resources [%d]",
293 PrintFieldName (4, Buffer
);
296 *((UINT32
*)(Ptr
+ Offset
))
299 Offset
+= sizeof (UINT32
);
305 This function parses the Cache Type Structure (Type 1).
307 @param [in] Ptr Pointer to the start of the Cache Type Structure data.
308 @param [in] Length Length of the Cache Type Structure.
312 DumpCacheTypeStructure (
320 "Cache Type Structure",
323 PARSER_PARAMS (CacheTypeStructureParser
)
328 This function parses the ACPI PPTT table.
329 When trace is enabled this function parses the PPTT table and
330 traces the ACPI table fields.
332 This function parses the following processor topology structures:
333 - Processor hierarchy node structure (Type 0)
334 - Cache Type Structure (Type 1)
336 This function also performs validation of the ACPI table fields.
338 @param [in] Trace If TRUE, trace the ACPI fields.
339 @param [in] Ptr Pointer to the start of the buffer.
340 @param [in] AcpiTableLength Length of the ACPI table.
341 @param [in] AcpiTableRevision Revision of the ACPI table.
348 IN UINT32 AcpiTableLength
,
349 IN UINT8 AcpiTableRevision
353 UINT8
*ProcessorTopologyStructurePtr
;
365 PARSER_PARAMS (PpttParser
)
368 ProcessorTopologyStructurePtr
= Ptr
+ Offset
;
370 while (Offset
< AcpiTableLength
) {
371 // Parse Processor Hierarchy Node Structure to obtain Type and Length.
376 ProcessorTopologyStructurePtr
,
377 AcpiTableLength
- Offset
,
378 PARSER_PARAMS (ProcessorTopologyStructureHeaderParser
)
381 // Check if the values used to control the parsing logic have been
382 // successfully read.
383 if ((ProcessorTopologyStructureType
== NULL
) ||
384 (ProcessorTopologyStructureLength
== NULL
))
386 IncrementErrorCount ();
388 L
"ERROR: Insufficient remaining table buffer length to read the " \
389 L
"processor topology structure header. Length = %d.\n",
390 AcpiTableLength
- Offset
395 // Validate Processor Topology Structure length
396 if ((*ProcessorTopologyStructureLength
== 0) ||
397 ((Offset
+ (*ProcessorTopologyStructureLength
)) > AcpiTableLength
))
399 IncrementErrorCount ();
401 L
"ERROR: Invalid Processor Topology Structure length. " \
402 L
"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
403 *ProcessorTopologyStructureLength
,
410 PrintFieldName (2, L
"* Structure Offset *");
411 Print (L
"0x%x\n", Offset
);
413 switch (*ProcessorTopologyStructureType
) {
414 case EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR
:
415 DumpProcessorHierarchyNodeStructure (
416 ProcessorTopologyStructurePtr
,
417 *ProcessorTopologyStructureLength
420 case EFI_ACPI_6_4_PPTT_TYPE_CACHE
:
421 DumpCacheTypeStructure (
422 ProcessorTopologyStructurePtr
,
423 *ProcessorTopologyStructureLength
426 case EFI_ACPI_6_3_PPTT_TYPE_ID
:
427 IncrementErrorCount ();
429 L
"ERROR: PPTT Type 2 - Processor ID has been removed and must not be"
434 IncrementErrorCount ();
436 L
"ERROR: Unknown processor topology structure:"
437 L
" Type = %d, Length = %d\n",
438 *ProcessorTopologyStructureType
,
439 *ProcessorTopologyStructureLength
443 ProcessorTopologyStructurePtr
+= *ProcessorTopologyStructureLength
;
444 Offset
+= *ProcessorTopologyStructureLength
;