TianoCore EDK2 master
Loading...
Searching...
No Matches
PpttParser.c
Go to the documentation of this file.
1
12#include <Library/PrintLib.h>
13#include <Library/UefiLib.h>
14#include "AcpiParser.h"
15#include "AcpiView.h"
16#include "AcpiViewConfig.h"
17#include "PpttParser.h"
18
19// Local variables
20STATIC CONST UINT8 *ProcessorTopologyStructureType;
21STATIC CONST UINT8 *ProcessorTopologyStructureLength;
22STATIC CONST UINT32 *NumberOfPrivateResources;
25
26#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
27
34VOID
35EFIAPI
36LogCacheFlagError (
37 IN CONST CHAR16 *FlagName
38 )
39{
41 Print (
42 L"\nERROR: On Arm based systems, all cache properties must be"
43 L" provided in the cache type structure."
44 L" Missing '%s' flag.",
45 FlagName
46 );
47}
48
49#endif
50
60VOID
61EFIAPI
63 IN UINT8 *Ptr,
64 IN UINT32 Length,
65 IN VOID *Context
66 )
67{
68 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
70
71 if (CacheFlags == NULL) {
73 Print (L"\nERROR: Cache Structure Flags were not successfully read.");
74 return;
75 }
76
77 if (CacheFlags->SizePropertyValid == EFI_ACPI_6_4_PPTT_CACHE_SIZE_INVALID) {
78 LogCacheFlagError (L"Size Property Valid");
79 }
80
81 if (CacheFlags->NumberOfSetsValid == EFI_ACPI_6_4_PPTT_NUMBER_OF_SETS_INVALID) {
82 LogCacheFlagError (L"Number Of Sets Valid");
83 }
84
85 if (CacheFlags->AssociativityValid == EFI_ACPI_6_4_PPTT_ASSOCIATIVITY_INVALID) {
86 LogCacheFlagError (L"Associativity Valid");
87 }
88
89 if (CacheFlags->AllocationTypeValid == EFI_ACPI_6_4_PPTT_ALLOCATION_TYPE_INVALID) {
90 LogCacheFlagError (L"Allocation Type Valid");
91 }
92
93 if (CacheFlags->CacheTypeValid == EFI_ACPI_6_4_PPTT_CACHE_TYPE_INVALID) {
94 LogCacheFlagError (L"Cache Type Valid");
95 }
96
97 if (CacheFlags->WritePolicyValid == EFI_ACPI_6_4_PPTT_WRITE_POLICY_INVALID) {
98 LogCacheFlagError (L"Write Policy Valid");
99 }
100
101 if (CacheFlags->LineSizeValid == EFI_ACPI_6_4_PPTT_LINE_SIZE_INVALID) {
102 LogCacheFlagError (L"Line Size Valid");
103 }
104
105 // Cache ID was only introduced in revision 3
106 if (*(AcpiHdrInfo.Revision) >= 3) {
107 if (CacheFlags->CacheIdValid == EFI_ACPI_6_4_PPTT_CACHE_ID_INVALID) {
108 LogCacheFlagError (L"Cache Id Valid");
109 }
110 }
111
112 #endif
113}
114
124STATIC
125VOID
126EFIAPI
128 IN UINT8 *Ptr,
129 IN UINT32 Length,
130 IN VOID *Context
131 )
132{
133 UINT32 NumberOfSets;
134
135 NumberOfSets = *(UINT32 *)Ptr;
136
137 if (NumberOfSets == 0) {
139 Print (L"\nERROR: Cache number of sets must be greater than 0");
140 return;
141 }
142
143 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
144 if (NumberOfSets > PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX) {
146 Print (
147 L"\nERROR: When ARMv8.3-CCIDX is implemented the maximum cache number of "
148 L"sets must be less than or equal to %d",
150 );
151 return;
152 }
153
154 if (NumberOfSets > PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX) {
156 Print (
157 L"\nWARNING: Without ARMv8.3-CCIDX, the maximum cache number of sets "
158 L"must be less than or equal to %d. Ignore this message if "
159 L"ARMv8.3-CCIDX is implemented",
161 );
162 return;
163 }
164
165 #endif
166}
167
177STATIC
178VOID
179EFIAPI
181 IN UINT8 *Ptr,
182 IN UINT32 Length,
183 IN VOID *Context
184 )
185{
186 UINT8 Associativity;
187
188 Associativity = *(UINT8 *)Ptr;
189
190 if (Associativity == 0) {
192 Print (L"\nERROR: Cache associativity must be greater than 0");
193 return;
194 }
195}
196
205STATIC
206VOID
207EFIAPI
209 IN UINT8 *Ptr,
210 IN UINT32 Length,
211 IN VOID *Context
212 )
213{
214 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
215 // Reference: ARM Architecture Reference Manual ARMv8 (D.a)
216 // Section D12.2.25: CCSIDR_EL1, Current Cache Size ID Register
217 // LineSize, bits [2:0]
218 // (Log2(Number of bytes in cache line)) - 4.
219
220 UINT16 LineSize;
221 LineSize = *(UINT16 *)Ptr;
222
223 if ((LineSize < PPTT_ARM_CACHE_LINE_SIZE_MIN) ||
224 (LineSize > PPTT_ARM_CACHE_LINE_SIZE_MAX))
225 {
227 Print (
228 L"\nERROR: The cache line size must be between %d and %d bytes"
229 L" on ARM Platforms.",
230 PPTT_ARM_CACHE_LINE_SIZE_MIN,
232 );
233 return;
234 }
235
236 if ((LineSize & (LineSize - 1)) != 0) {
238 Print (L"\nERROR: The cache line size is not a power of 2.");
239 }
240
241 #endif
242}
243
252STATIC
253VOID
254EFIAPI
256 IN UINT8 *Ptr,
257 IN UINT32 Length,
258 IN VOID *Context
259 )
260{
261 UINT32 CacheId;
262
263 CacheId = *(UINT32 *)Ptr;
264
265 // Cache ID was only introduced in revision 3
266 if (*(AcpiHdrInfo.Revision) < 3) {
267 return;
268 }
269
270 if (CacheFlags == NULL) {
272 Print (L"\nERROR: Cache Structure Flags were not successfully read.");
273 return;
274 }
275
276 if (CacheFlags->CacheIdValid == EFI_ACPI_6_4_PPTT_CACHE_ID_VALID) {
277 if (CacheId == 0) {
279 Print (L"\nERROR: 0 is not a valid Cache ID.");
280 return;
281 }
282 }
283}
284
293STATIC
294VOID
295EFIAPI
297 IN UINT8 *Ptr,
298 IN UINT32 Length,
299 IN VOID *Context
300 )
301{
302 // Reference: Advanced Configuration and Power Interface (ACPI) Specification
303 // Version 6.4, January 2021
304 // Table 5-140: Cache Type Structure
305 UINT8 Attributes;
306
307 Attributes = *(UINT8 *)Ptr;
308
309 if ((Attributes & 0xE0) != 0) {
311 Print (
312 L"\nERROR: Attributes bits [7:5] are reserved and must be zero.",
313 Attributes
314 );
315 return;
316 }
317}
318
323 PARSE_ACPI_HEADER (&AcpiHdrInfo)
324};
325
330 { L"Type", 1, 0, NULL, NULL, (VOID **)&ProcessorTopologyStructureType,
331 NULL, NULL },
332 { L"Length", 1, 1, NULL, NULL, (VOID **)&ProcessorTopologyStructureLength,
333 NULL, NULL },
334 { L"Reserved", 2, 2, NULL, NULL, NULL, NULL,NULL }
335};
336
341 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
342 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
343 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
344
345 { L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
346 { L"Parent", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
347 { L"ACPI Processor ID", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
348 { L"Number of private resources", 4, 16, L"%d", NULL,
349 (VOID **)&NumberOfPrivateResources, NULL, NULL }
350};
351
356 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
357 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
358 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
359
360 { L"Flags", 4, 4, L"0x%x", NULL, (VOID **)&CacheFlags, ValidateCacheFlags,
361 NULL },
362 { L"Next Level of Cache", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
363 { L"Size", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
364 { L"Number of sets", 4, 16, L"%d", NULL, NULL, ValidateCacheNumberOfSets, NULL },
365 { L"Associativity", 1, 20, L"%d", NULL, NULL, ValidateCacheAssociativity, NULL },
366 { L"Attributes", 1, 21, L"0x%x", NULL, NULL, ValidateCacheAttributes, NULL },
367 { L"Line size", 2, 22, L"%d", NULL, NULL, ValidateCacheLineSize, NULL },
368 { L"Cache ID", 4, 24, L"%d", NULL, NULL, ValidateCacheId, NULL }
369};
370
378STATIC
379VOID
381 IN UINT8 *Ptr,
382 IN UINT8 Length
383 )
384{
385 UINT32 Offset;
386 UINT32 Index;
387 CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
388
389 Offset = ParseAcpi (
390 TRUE,
391 2,
392 "Processor Hierarchy Node Structure",
393 Ptr,
394 Length,
396 );
397
398 // Check if the values used to control the parsing logic have been
399 // successfully read.
400 if (NumberOfPrivateResources == NULL) {
402 Print (
403 L"ERROR: Insufficient Processor Hierarchy Node length. Length = %d.\n",
404 Length
405 );
406 return;
407 }
408
409 // Make sure the Private Resource array lies inside this structure
410 if (Offset + (*NumberOfPrivateResources * sizeof (UINT32)) > Length) {
412 Print (
413 L"ERROR: Invalid Number of Private Resources. " \
414 L"PrivateResourceCount = %d. RemainingBufferLength = %d. " \
415 L"Parsing of this structure aborted.\n",
416 *NumberOfPrivateResources,
417 Length - Offset
418 );
419 return;
420 }
421
422 Index = 0;
423
424 // Parse the specified number of private resource references or the Processor
425 // Hierarchy Node length. Whichever is minimum.
426 while (Index < *NumberOfPrivateResources) {
428 Buffer,
429 sizeof (Buffer),
430 L"Private resources [%d]",
431 Index
432 );
433
434 PrintFieldName (4, Buffer);
435 Print (
436 L"0x%x\n",
437 *((UINT32 *)(Ptr + Offset))
438 );
439
440 Offset += sizeof (UINT32);
441 Index++;
442 }
443}
444
451STATIC
452VOID
454 IN UINT8 *Ptr,
455 IN UINT8 Length
456 )
457{
458 ParseAcpi (
459 TRUE,
460 2,
461 "Cache Type Structure",
462 Ptr,
463 Length,
465 );
466}
467
484VOID
485EFIAPI
487 IN BOOLEAN Trace,
488 IN UINT8 *Ptr,
489 IN UINT32 AcpiTableLength,
490 IN UINT8 AcpiTableRevision
491 )
492{
493 UINT32 Offset;
494 UINT8 *ProcessorTopologyStructurePtr;
495
496 if (!Trace) {
497 return;
498 }
499
500 Offset = ParseAcpi (
501 TRUE,
502 0,
503 "PPTT",
504 Ptr,
505 AcpiTableLength,
507 );
508
509 ProcessorTopologyStructurePtr = Ptr + Offset;
510
511 while (Offset < AcpiTableLength) {
512 // Parse Processor Hierarchy Node Structure to obtain Type and Length.
513 ParseAcpi (
514 FALSE,
515 0,
516 NULL,
517 ProcessorTopologyStructurePtr,
518 AcpiTableLength - Offset,
520 );
521
522 // Check if the values used to control the parsing logic have been
523 // successfully read.
524 if ((ProcessorTopologyStructureType == NULL) ||
525 (ProcessorTopologyStructureLength == NULL))
526 {
528 Print (
529 L"ERROR: Insufficient remaining table buffer length to read the " \
530 L"processor topology structure header. Length = %d.\n",
531 AcpiTableLength - Offset
532 );
533 return;
534 }
535
536 // Validate Processor Topology Structure length
537 if ((*ProcessorTopologyStructureLength == 0) ||
538 ((Offset + (*ProcessorTopologyStructureLength)) > AcpiTableLength))
539 {
541 Print (
542 L"ERROR: Invalid Processor Topology Structure length. " \
543 L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
544 *ProcessorTopologyStructureLength,
545 Offset,
546 AcpiTableLength
547 );
548 return;
549 }
550
551 PrintFieldName (2, L"* Structure Offset *");
552 Print (L"0x%x\n", Offset);
553
554 switch (*ProcessorTopologyStructureType) {
557 ProcessorTopologyStructurePtr,
558 *ProcessorTopologyStructureLength
559 );
560 break;
561 case EFI_ACPI_6_4_PPTT_TYPE_CACHE:
563 ProcessorTopologyStructurePtr,
564 *ProcessorTopologyStructureLength
565 );
566 break;
567 case EFI_ACPI_6_3_PPTT_TYPE_ID:
569 Print (
570 L"ERROR: PPTT Type 2 - Processor ID has been removed and must not be"
571 L"used.\n"
572 );
573 break;
574 default:
576 Print (
577 L"ERROR: Unknown processor topology structure:"
578 L" Type = %d, Length = %d\n",
579 *ProcessorTopologyStructureType,
580 *ProcessorTopologyStructureLength
581 );
582 }
583
584 ProcessorTopologyStructurePtr += *ProcessorTopologyStructureLength;
585 Offset += *ProcessorTopologyStructureLength;
586 } // while
587}
#define EFI_ACPI_6_4_PPTT_CACHE_SIZE_INVALID
Definition: Acpi64.h:2703
#define EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR
Definition: Acpi64.h:2649
VOID EFIAPI IncrementWarningCount(VOID)
Definition: AcpiParser.c:95
VOID EFIAPI PrintFieldName(IN UINT32 Indent, IN CONST CHAR16 *FieldName)
Definition: AcpiParser.c:641
VOID EFIAPI IncrementErrorCount(VOID)
Definition: AcpiParser.c:83
UINT32 EFIAPI ParseAcpi(IN BOOLEAN Trace, IN UINT32 Indent, IN CONST CHAR8 *AsciiName OPTIONAL, IN UINT8 *Ptr, IN UINT32 Length, IN CONST ACPI_PARSER *Parser, IN UINT32 ParserItems)
Definition: AcpiParser.c:683
#define PARSER_PARAMS(Parser)
Definition: AcpiParser.h:494
#define PARSE_ACPI_HEADER(Info)
Definition: AcpiParser.h:501
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:408
#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 PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX
Definition: PpttGenerator.h:24
#define PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX
Definition: PpttGenerator.h:30
#define PPTT_ARM_CACHE_LINE_SIZE_MAX
Definition: PpttGenerator.h:38
STATIC CONST ACPI_PARSER CacheTypeStructureParser[]
Definition: PpttParser.c:355
STATIC VOID DumpCacheTypeStructure(IN UINT8 *Ptr, IN UINT8 Length)
Definition: PpttParser.c:453
STATIC VOID DumpProcessorHierarchyNodeStructure(IN UINT8 *Ptr, IN UINT8 Length)
Definition: PpttParser.c:380
STATIC VOID EFIAPI ValidateCacheLineSize(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: PpttParser.c:208
STATIC CONST ACPI_PARSER PpttParser[]
Definition: PpttParser.c:322
STATIC VOID EFIAPI ValidateCacheAttributes(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: PpttParser.c:296
STATIC VOID EFIAPI ValidateCacheId(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: PpttParser.c:255
STATIC CONST ACPI_PARSER ProcessorTopologyStructureHeaderParser[]
Definition: PpttParser.c:329
STATIC CONST ACPI_PARSER ProcessorHierarchyNodeStructureParser[]
Definition: PpttParser.c:340
VOID EFIAPI ParseAcpiPptt(IN BOOLEAN Trace, IN UINT8 *Ptr, IN UINT32 AcpiTableLength, IN UINT8 AcpiTableRevision)
Definition: PpttParser.c:486
STATIC VOID EFIAPI ValidateCacheAssociativity(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: PpttParser.c:180
STATIC VOID EFIAPI ValidateCacheFlags(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: PpttParser.c:62
STATIC VOID EFIAPI ValidateCacheNumberOfSets(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: PpttParser.c:127
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
Definition: UefiLibPrint.c:113
UINT8 * Revision
Revision.
Definition: AcpiParser.h:396