TianoCore EDK2 master
Loading...
Searching...
No Matches
AestParser.c
Go to the documentation of this file.
1
13#include <Library/PrintLib.h>
14#include <Library/UefiLib.h>
16#include "AcpiParser.h"
17#include "AcpiView.h"
18#include "AcpiViewConfig.h"
19
20// Local variables
22STATIC UINT8 *AestNodeType;
23STATIC UINT16 *AestNodeLength;
24STATIC UINT32 *NodeDataOffset;
25STATIC UINT32 *NodeInterfaceOffset;
26STATIC UINT32 *NodeInterruptArrayOffset;
27STATIC UINT32 *NodeInterruptCount;
28STATIC UINT32 *ProcessorId;
29STATIC UINT8 *ProcessorFlags;
30STATIC UINT8 *ProcessorResourceType;
31
41VOID
42EFIAPI
44 IN UINT8 *Ptr,
45 IN UINT32 Length,
46 IN VOID *Context
47 )
48{
49 // If the global or shared node flag is set then the ACPI Processor ID
50 // field must be set to 0 and ignored.
51 if (((*Ptr & 0x3) != 0) && (*ProcessorId != 0)) {
53 Print (
54 L"\nERROR: 'ACPI Processor ID' field must be set to 0 for global"
55 L" or shared nodes."
56 );
57 }
58}
59
69VOID
70EFIAPI
72 IN UINT8 *Ptr,
73 IN UINT32 Length,
74 IN VOID *Context
75 )
76{
77 UINT32 GicInterfaceType;
78
79 GicInterfaceType = *(UINT32 *)Ptr;
80 if (GicInterfaceType > 3) {
82 Print (L"\nError: Invalid GIC Interface type %d", GicInterfaceType);
83 }
84}
85
95VOID
96EFIAPI
98 IN UINT8 *Ptr,
99 IN UINT32 Length,
100 IN VOID *Context
101 )
102{
103 if (*Ptr > 1) {
105 Print (L"\nError: Interface type should be 0 or 1");
106 }
107}
108
117STATIC
118VOID
119EFIAPI
121 IN UINT8 *Ptr,
122 IN UINT32 Length,
123 IN VOID *Context
124 )
125{
126 if (*Ptr > 1) {
128 Print (L"\nError: Interrupt type should be 0 or 1");
129 }
130}
131
140STATIC
141VOID
142EFIAPI
144 IN UINT8 *Ptr,
145 IN UINT32 Length,
146 IN VOID *Context
147 )
148{
149 if ((*Ptr & 0xfe) != 0) {
151 Print (L"\nError: Reserved Flag bits not set to 0");
152 }
153}
154
162VOID
163EFIAPI
165 IN CONST CHAR16 *Format OPTIONAL,
166 IN UINT8 *Ptr,
167 IN UINT32 Length
168 )
169{
170 Print (
171 L"%02X %02X %02X %02X %02X %02X %02X %02X\n",
172 Ptr[0],
173 Ptr[1],
174 Ptr[2],
175 Ptr[3],
176 Ptr[4],
177 Ptr[5],
178 Ptr[6],
179 Ptr[7]
180 );
181
182 Print (
183 L"%*a %02X %02X %02X %02X %02X %02X %02X %02X",
184 OUTPUT_FIELD_COLUMN_WIDTH,
185 "",
186 Ptr[8],
187 Ptr[9],
188 Ptr[10],
189 Ptr[11],
190 Ptr[12],
191 Ptr[13],
192 Ptr[14],
193 Ptr[15]
194 );
195}
196
201 PARSE_ACPI_HEADER (&AcpiHdrInfo)
202};
203
208 { L"Type", 1, 0, L"%d", NULL, (VOID **)&AestNodeType, NULL, NULL },
209 { L"Length", 2, 1, L"%d", NULL, (VOID **)&AestNodeLength, NULL, NULL },
210 { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
211 { L"Node Data Offset", 4, 4, L"%d", NULL, (VOID **)&NodeDataOffset, NULL, NULL },
212 { L"Node Interface Offset", 4, 8, L"%d", NULL,
213 (VOID **)&NodeInterfaceOffset, NULL, NULL },
214 { L"Node Interrupt Array Offset", 4, 12, L"%d", NULL,
215 (VOID **)&NodeInterruptArrayOffset, NULL, NULL },
216 { L"Node Interrupt Count", 4, 16, L"%d", NULL,
217 (VOID **)&NodeInterruptCount, NULL, NULL },
218 { L"Timestamp Rate", 8, 20, L"%ld", NULL, NULL, NULL, NULL },
219 { L"Reserved1", 8, 28, L"0x%lx", NULL, NULL, NULL, NULL },
220 { L"Error Injection Countdown Rate", 8, 36, L"%ld", NULL, NULL, NULL, NULL }
221 // Node specific data...
222 // Node interface...
223 // Node interrupt array...
224};
225
230 { L"ACPI Processor ID", 4, 0, L"0x%x", NULL, (VOID **)&ProcessorId, NULL, NULL },
231 { L"Resource Type", 1, 4, L"%d", NULL, (VOID **)&ProcessorResourceType, NULL,
232 NULL },
233 { L"Reserved", 1, 5, L"0x%x", NULL, NULL, NULL, NULL },
234 { L"Flags", 1, 6, L"0x%x", NULL, (VOID **)&ProcessorFlags,
236 { L"Revision", 1, 7, L"%d", NULL, NULL, NULL, NULL },
237 { L"Processor Affinity Level Indicator", 8, 8, L"0x%lx", NULL, NULL, NULL,
238 NULL },
239 // Resource specific data...
240};
241
246 { L"Cache reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
247 { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL }
248};
249
254 { L"TLB reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
255 { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL }
256};
257
262 { L"Vendor-defined data", 4, 0, L"%x", NULL, NULL, NULL, NULL }
263};
264
269 { L"Proximity Domain", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }
270};
271
276 { L"IORT Node reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
277 { L"SubComponent reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }
278};
279
284 { L"Hardware ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
285 { L"Unique ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
286 { L"Vendor-specific data", 16, 8, NULL, DumpVendorSpecificData, NULL, NULL }
287};
288
293 { L"GIC Interface Type", 4, 0, L"0x%x", NULL, NULL, ValidateGicInterfaceType,
294 NULL },
295 { L"GIC Interface reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}
296};
297
302 { L"Interface Type", 1, 0, L"%d", NULL, NULL, ValidateInterfaceType, NULL },
303 { L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL },
304 { L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
305 { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
306 { L"Start Error Record Index", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
307 { L"Number of Error Records", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
308 { L"Error Records Implemented", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
309 { L"Error Records Support", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
310 { L"Addressing mode", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL }
311};
312
317 { L"Interrupt Type", 1, 0, L"%d", NULL, NULL, ValidateInterruptType, NULL },
318 { L"Reserved", 2, 1, L"0x%x", NULL, NULL, NULL, NULL },
319 { L"Interrupt Flags", 1, 3, L"0x%x", NULL, NULL, ValidateInterruptFlags, NULL },
320 { L"Interrupt GSIV", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
321 { L"ID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL },
322 { L"Reserved1", 3, 9, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }
323};
324
332STATIC
333VOID
335 IN UINT8 *Ptr,
336 IN UINT32 Length
337 )
338{
339 UINT32 Offset;
340
341 Offset = ParseAcpi (
342 TRUE,
343 2,
344 "Processor",
345 Ptr,
346 Length,
348 );
349
350 // Check if the values used to control the parsing logic have been
351 // successfully read.
352 if ((ProcessorId == NULL) ||
353 (ProcessorResourceType == NULL) ||
354 (ProcessorFlags == NULL))
355 {
357 Print (
358 L"ERROR: Insufficient Processor Error Node length. Length = %d.\n",
359 Length
360 );
361 return;
362 }
363
364 switch (*ProcessorResourceType) {
365 case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_CACHE:
366 ParseAcpi (
367 TRUE,
368 2,
369 "Cache Resource",
370 Ptr + Offset,
371 Length - Offset,
373 );
374 break;
375 case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_TLB:
376 ParseAcpi (
377 TRUE,
378 2,
379 "TLB Resource",
380 Ptr + Offset,
381 Length - Offset,
383 );
384 break;
385 case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_GENERIC:
386 ParseAcpi (
387 TRUE,
388 2,
389 "Generic Resource",
390 Ptr + Offset,
391 Length - Offset,
393 );
394 break;
395 default:
397 Print (L"ERROR: Invalid Processor Resource Type.");
398 return;
399 } // switch
400}
401
408STATIC
409VOID
411 IN UINT8 *Ptr,
412 IN UINT32 Length
413 )
414{
415 ParseAcpi (
416 TRUE,
417 2,
418 "Memory Controller",
419 Ptr,
420 Length,
422 );
423}
424
431STATIC
432VOID
434 IN UINT8 *Ptr,
435 IN UINT32 Length
436 )
437{
438 ParseAcpi (
439 TRUE,
440 2,
441 "SMMU",
442 Ptr,
443 Length,
445 );
446}
447
454STATIC
455VOID
457 IN UINT8 *Ptr,
458 IN UINT32 Length
459 )
460{
461 ParseAcpi (
462 TRUE,
463 2,
464 "Vendor-defined",
465 Ptr,
466 Length,
468 );
469}
470
477STATIC
478VOID
480 IN UINT8 *Ptr,
481 IN UINT32 Length
482 )
483{
484 ParseAcpi (
485 TRUE,
486 2,
487 "GIC",
488 Ptr,
489 Length,
491 );
492}
493
500STATIC
501VOID
503 IN UINT8 *Ptr,
504 IN UINT32 Length
505 )
506{
507 ParseAcpi (
508 TRUE,
509 2,
510 "Node Interface",
511 Ptr,
512 Length,
514 );
515}
516
524STATIC
525VOID
527 IN UINT8 *Ptr,
528 IN UINT32 Length,
529 IN UINT32 InterruptCount
530 )
531{
532 UINT32 Offset;
533 UINT32 Index;
534 CHAR8 Buffer[64];
535
536 if (Length < (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT))) {
538 Print (
539 L"ERROR: Node not long enough for Interrupt Array.\n" \
540 L" Length left = %d, Required = %d, Interrupt Count = %d\n",
541 Length,
542 (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT)),
543 InterruptCount
544 );
545 return;
546 }
547
548 Offset = 0;
549 for (Index = 0; Index < InterruptCount; Index++) {
551 Buffer,
552 sizeof (Buffer),
553 "Node Interrupt [%d]",
554 Index
555 );
556
557 Offset += ParseAcpi (
558 TRUE,
559 4,
560 Buffer,
561 Ptr + Offset,
562 Length - Offset,
564 );
565 } // for
566}
567
579STATIC
580VOID
582 IN UINT8 *Ptr,
583 IN UINT32 Length,
584 IN UINT8 NodeType,
585 IN UINT32 DataOffset,
586 IN UINT32 InterfaceOffset,
587 IN UINT32 InterruptArrayOffset,
588 IN UINT32 InterruptCount
589 )
590{
591 UINT32 Offset;
592 UINT32 RemainingLength;
593 UINT8 *NodeDataPtr;
594
595 Offset = ParseAcpi (
596 TRUE,
597 2,
598 "Node Structure",
599 Ptr,
600 Length,
602 );
603
604 if ((Offset > DataOffset) || (DataOffset > Length)) {
606 Print (
607 L"ERROR: Invalid Node Data Offset: %d.\n" \
608 L" It should be between %d and %d.\n",
609 DataOffset,
610 Offset,
611 Length
612 );
613 }
614
615 if ((Offset > InterfaceOffset) || (InterfaceOffset > Length)) {
617 Print (
618 L"ERROR: Invalid Node Interface Offset: %d.\n" \
619 L" It should be between %d and %d.\n",
620 InterfaceOffset,
621 Offset,
622 Length
623 );
624 }
625
626 if ((Offset > InterruptArrayOffset) || (InterruptArrayOffset > Length)) {
628 Print (
629 L"ERROR: Invalid Node Interrupt Array Offset: %d.\n" \
630 L" It should be between %d and %d.\n",
631 InterruptArrayOffset,
632 Offset,
633 Length
634 );
635 }
636
637 // Parse Node Data Field.
638 NodeDataPtr = Ptr + DataOffset;
639 RemainingLength = Length - DataOffset;
640 switch (NodeType) {
641 case EFI_ACPI_AEST_NODE_TYPE_PROCESSOR:
642 DumpProcessorNode (NodeDataPtr, RemainingLength);
643 break;
644 case EFI_ACPI_AEST_NODE_TYPE_MEMORY:
645 DumpMemoryControllerNode (NodeDataPtr, RemainingLength);
646 break;
647 case EFI_ACPI_AEST_NODE_TYPE_SMMU:
648 DumpSmmuNode (NodeDataPtr, RemainingLength);
649 break;
650 case EFI_ACPI_AEST_NODE_TYPE_VENDOR_DEFINED:
651 DumpVendorDefinedNode (NodeDataPtr, RemainingLength);
652 break;
653 case EFI_ACPI_AEST_NODE_TYPE_GIC:
654 DumpGicNode (NodeDataPtr, RemainingLength);
655 break;
656 default:
658 Print (L"ERROR: Invalid Error Node Type.\n");
659 return;
660 } // switch
661
662 // Parse the Interface Field.
664 Ptr + InterfaceOffset,
665 Length - InterfaceOffset
666 );
667
668 // Parse the Node Interrupt Array.
670 Ptr + InterruptArrayOffset,
671 Length - InterruptArrayOffset,
672 InterruptCount
673 );
674
675 return;
676}
677
690VOID
691EFIAPI
693 IN BOOLEAN Trace,
694 IN UINT8 *Ptr,
695 IN UINT32 AcpiTableLength,
696 IN UINT8 AcpiTableRevision
697 )
698{
699 UINT32 Offset;
700 UINT8 *NodePtr;
701
702 if (!Trace) {
703 return;
704 }
705
706 Offset = ParseAcpi (
707 TRUE,
708 0,
709 "AEST",
710 Ptr,
711 AcpiTableLength,
713 );
714
715 while (Offset < AcpiTableLength) {
716 NodePtr = Ptr + Offset;
717
718 ParseAcpi (
719 FALSE,
720 0,
721 NULL,
722 NodePtr,
723 AcpiTableLength - Offset,
725 );
726
727 // Check if the values used to control the parsing logic have been
728 // successfully read.
729 if ((AestNodeType == NULL) ||
730 (AestNodeLength == NULL) ||
731 (NodeDataOffset == NULL) ||
732 (NodeInterfaceOffset == NULL) ||
733 (NodeInterruptArrayOffset == NULL) ||
734 (NodeInterruptCount == NULL))
735 {
737 Print (
738 L"ERROR: Insufficient length left for Node Structure.\n" \
739 L" Length left = %d.\n",
740 AcpiTableLength - Offset
741 );
742 return;
743 }
744
745 // Validate AEST Node length
746 if ((*AestNodeLength == 0) ||
747 ((Offset + (*AestNodeLength)) > AcpiTableLength))
748 {
750 Print (
751 L"ERROR: Invalid AEST Node length. " \
752 L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
753 *AestNodeLength,
754 Offset,
755 AcpiTableLength
756 );
757 return;
758 }
759
761 NodePtr,
762 *AestNodeLength,
763 *AestNodeType,
764 *NodeDataOffset,
765 *NodeInterfaceOffset,
766 *NodeInterruptArrayOffset,
767 *NodeInterruptCount
768 );
769
770 Offset += *AestNodeLength;
771 } // while
772}
VOID EFIAPI Dump3Chars(IN CONST CHAR16 *Format OPTIONAL, IN UINT8 *Ptr, IN UINT32 Length)
Definition: AcpiParser.c:326
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
STATIC CONST ACPI_PARSER AestNodeInterface[]
Definition: AestParser.c:301
STATIC CONST ACPI_PARSER AestNodeHeaderParser[]
Definition: AestParser.c:207
STATIC VOID DumpSmmuNode(IN UINT8 *Ptr, IN UINT32 Length)
Definition: AestParser.c:433
STATIC CONST ACPI_PARSER AestParser[]
Definition: AestParser.c:200
STATIC VOID DumpAestNodeStructure(IN UINT8 *Ptr, IN UINT32 Length, IN UINT8 NodeType, IN UINT32 DataOffset, IN UINT32 InterfaceOffset, IN UINT32 InterruptArrayOffset, IN UINT32 InterruptCount)
Definition: AestParser.c:581
STATIC VOID EFIAPI ValidateInterruptFlags(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: AestParser.c:143
STATIC VOID EFIAPI ValidateGicInterfaceType(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: AestParser.c:71
STATIC VOID EFIAPI ValidateInterfaceType(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: AestParser.c:97
STATIC VOID DumpNodeInterrupts(IN UINT8 *Ptr, IN UINT32 Length, IN UINT32 InterruptCount)
Definition: AestParser.c:526
STATIC CONST ACPI_PARSER AestGicStructure[]
Definition: AestParser.c:292
STATIC CONST ACPI_PARSER AestProcessorStructure[]
Definition: AestParser.c:229
STATIC VOID EFIAPI ValidateInterruptType(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: AestParser.c:120
STATIC VOID DumpMemoryControllerNode(IN UINT8 *Ptr, IN UINT32 Length)
Definition: AestParser.c:410
STATIC CONST ACPI_PARSER AestProcessorTlbResourceSubstructure[]
Definition: AestParser.c:253
VOID EFIAPI DumpVendorSpecificData(IN CONST CHAR16 *Format OPTIONAL, IN UINT8 *Ptr, IN UINT32 Length)
Definition: AestParser.c:164
STATIC VOID DumpVendorDefinedNode(IN UINT8 *Ptr, IN UINT32 Length)
Definition: AestParser.c:456
STATIC CONST ACPI_PARSER AestVendorDefinedStructure[]
Definition: AestParser.c:283
STATIC CONST ACPI_PARSER AestNodeInterrupt[]
Definition: AestParser.c:316
STATIC CONST ACPI_PARSER AestSmmuStructure[]
Definition: AestParser.c:275
STATIC CONST ACPI_PARSER AestMemoryControllerStructure[]
Definition: AestParser.c:268
STATIC CONST ACPI_PARSER AestProcessorCacheResourceSubstructure[]
Definition: AestParser.c:245
STATIC VOID DumpNodeInterface(IN UINT8 *Ptr, IN UINT32 Length)
Definition: AestParser.c:502
STATIC VOID EFIAPI ValidateProcessorFlags(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: AestParser.c:43
VOID EFIAPI ParseAcpiAest(IN BOOLEAN Trace, IN UINT8 *Ptr, IN UINT32 AcpiTableLength, IN UINT8 AcpiTableRevision)
Definition: AestParser.c:692
STATIC CONST ACPI_PARSER AestProcessorGenericResourceSubstructure[]
Definition: AestParser.c:261
STATIC VOID DumpProcessorNode(IN UINT8 *Ptr, IN UINT32 Length)
Definition: AestParser.c:334
STATIC VOID DumpGicNode(IN UINT8 *Ptr, IN UINT32 Length)
Definition: AestParser.c:479
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
#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
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
Definition: UefiLibPrint.c:113