]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
f7447947b2308d35d4d2890373778f0fd2f97f9e
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Iort / IortParser.c
1 /** @file
2 IORT table parser
3
4 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 @par Reference(s):
8 - IO Remapping Table, Platform Design Document, Revision D, March 2018
9 **/
10
11 #include <IndustryStandard/IoRemappingTable.h>
12 #include <Library/PrintLib.h>
13 #include <Library/UefiLib.h>
14 #include "AcpiParser.h"
15 #include "AcpiTableParser.h"
16 #include "AcpiViewConfig.h"
17
18 // Local variables
19 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
20
21 STATIC CONST UINT32* IortNodeCount;
22 STATIC CONST UINT32* IortNodeOffset;
23
24 STATIC CONST UINT8* IortNodeType;
25 STATIC CONST UINT16* IortNodeLength;
26 STATIC CONST UINT32* IortIdMappingCount;
27 STATIC CONST UINT32* IortIdMappingOffset;
28
29 STATIC CONST UINT32* InterruptContextCount;
30 STATIC CONST UINT32* InterruptContextOffset;
31 STATIC CONST UINT32* PmuInterruptCount;
32 STATIC CONST UINT32* PmuInterruptOffset;
33
34 STATIC CONST UINT32* ItsCount;
35
36 /**
37 This function validates the ID Mapping array count for the ITS node.
38
39 @param [in] Ptr Pointer to the start of the field data.
40 @param [in] Context Pointer to context specific information e.g. this
41 could be a pointer to the ACPI table header.
42 **/
43 STATIC
44 VOID
45 EFIAPI
46 ValidateItsIdMappingCount (
47 IN UINT8* Ptr,
48 IN VOID* Context
49 )
50 {
51 if (*(UINT32*)Ptr != 0) {
52 IncrementErrorCount ();
53 Print (L"\nERROR: IORT ID Mapping count must be zero.");
54 }
55 }
56
57 /**
58 This function validates the ID Mapping array count for the Performance
59 Monitoring Counter Group (PMCG) node.
60
61 @param [in] Ptr Pointer to the start of the field data.
62 @param [in] Context Pointer to context specific information e.g. this
63 could be a pointer to the ACPI table header.
64 **/
65 STATIC
66 VOID
67 EFIAPI
68 ValidatePmcgIdMappingCount (
69 IN UINT8* Ptr,
70 IN VOID* Context
71 )
72 {
73 if (*(UINT32*)Ptr > 1) {
74 IncrementErrorCount ();
75 Print (L"\nERROR: IORT ID Mapping count must not be greater than 1.");
76 }
77 }
78
79 /**
80 This function validates the ID Mapping array offset for the ITS node.
81
82 @param [in] Ptr Pointer to the start of the field data.
83 @param [in] Context Pointer to context specific information e.g. this
84 could be a pointer to the ACPI table header.
85 **/
86 STATIC
87 VOID
88 EFIAPI
89 ValidateItsIdArrayReference (
90 IN UINT8* Ptr,
91 IN VOID* Context
92 )
93 {
94 if (*(UINT32*)Ptr != 0) {
95 IncrementErrorCount ();
96 Print (L"\nERROR: IORT ID Mapping offset must be zero.");
97 }
98 }
99
100 /**
101 Helper Macro for populating the IORT Node header in the ACPI_PARSER array.
102
103 @param [out] ValidateIdMappingCount Optional pointer to a function for
104 validating the ID Mapping count.
105 @param [out] ValidateIdArrayReference Optional pointer to a function for
106 validating the ID Array reference.
107 **/
108 #define PARSE_IORT_NODE_HEADER(ValidateIdMappingCount, \
109 ValidateIdArrayReference) \
110 { L"Type", 1, 0, L"%d", NULL, (VOID**)&IortNodeType, NULL, NULL }, \
111 { L"Length", 2, 1, L"%d", NULL, (VOID**)&IortNodeLength, NULL, NULL }, \
112 { L"Revision", 1, 3, L"%d", NULL, NULL, NULL, NULL }, \
113 { L"Reserved", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, \
114 { L"Number of ID mappings", 4, 8, L"%d", NULL, \
115 (VOID**)&IortIdMappingCount, ValidateIdMappingCount, NULL }, \
116 { L"Reference to ID Array", 4, 12, L"0x%x", NULL, \
117 (VOID**)&IortIdMappingOffset, ValidateIdArrayReference, NULL }
118
119 /**
120 An ACPI_PARSER array describing the ACPI IORT Table
121 **/
122 STATIC CONST ACPI_PARSER IortParser[] = {
123 PARSE_ACPI_HEADER (&AcpiHdrInfo),
124 {L"Number of IORT Nodes", 4, 36, L"%d", NULL,
125 (VOID**)&IortNodeCount, NULL, NULL},
126 {L"Offset to Array of IORT Nodes", 4, 40, L"0x%x", NULL,
127 (VOID**)&IortNodeOffset, NULL, NULL},
128 {L"Reserved", 4, 44, L"0x%x", NULL, NULL, NULL, NULL}
129 };
130
131 /**
132 An ACPI_PARSER array describing the IORT node header structure.
133 **/
134 STATIC CONST ACPI_PARSER IortNodeHeaderParser[] = {
135 PARSE_IORT_NODE_HEADER (NULL, NULL)
136 };
137
138 /**
139 An ACPI_PARSER array describing the IORT SMMUv1/2 node.
140 **/
141 STATIC CONST ACPI_PARSER IortNodeSmmuV1V2Parser[] = {
142 PARSE_IORT_NODE_HEADER (NULL, NULL),
143 {L"Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
144 {L"Span", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL},
145 {L"Model", 4, 32, L"%d", NULL, NULL, NULL, NULL},
146 {L"Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL},
147 {L"Reference to Global Interrupt Array", 4, 40, L"0x%x", NULL, NULL, NULL,
148 NULL},
149 {L"Number of context interrupts", 4, 44, L"%d", NULL,
150 (VOID**)&InterruptContextCount, NULL, NULL},
151 {L"Reference to Context Interrupt Array", 4, 48, L"0x%x", NULL,
152 (VOID**)&InterruptContextOffset, NULL, NULL},
153 {L"Number of PMU Interrupts", 4, 52, L"%d", NULL,
154 (VOID**)&PmuInterruptCount, NULL, NULL},
155 {L"Reference to PMU Interrupt Array", 4, 56, L"0x%x", NULL,
156 (VOID**)&PmuInterruptOffset, NULL, NULL},
157
158 // Interrupt Array
159 {L"SMMU_NSgIrpt", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},
160 {L"SMMU_NSgIrpt interrupt flags", 4, 64, L"0x%x", NULL, NULL, NULL, NULL},
161 {L"SMMU_NSgCfgIrpt", 4, 68, L"0x%x", NULL, NULL, NULL, NULL},
162 {L"SMMU_NSgCfgIrpt interrupt flags", 4, 72, L"0x%x", NULL, NULL, NULL, NULL}
163 };
164
165 /**
166 An ACPI_PARSER array describing the SMMUv1/2 Node Interrupt Array.
167 **/
168 STATIC CONST ACPI_PARSER InterruptArrayParser[] = {
169 {L"Interrupt GSIV", 4, 0, L"0x%x", NULL, NULL, NULL, NULL},
170 {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}
171 };
172
173 /**
174 An ACPI_PARSER array describing the IORT ID Mapping.
175 **/
176 STATIC CONST ACPI_PARSER IortNodeIdMappingParser[] = {
177 {L"Input base", 4, 0, L"0x%x", NULL, NULL, NULL, NULL},
178 {L"Number of IDs", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
179 {L"Output base", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
180 {L"Output reference", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
181 {L"Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}
182 };
183
184 /**
185 An ACPI_PARSER array describing the IORT SMMUv3 node.
186 **/
187 STATIC CONST ACPI_PARSER IortNodeSmmuV3Parser[] = {
188 PARSE_IORT_NODE_HEADER (NULL, NULL),
189 {L"Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
190 {L"Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
191 {L"Reserved", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
192 {L"VATOS Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
193 {L"Model", 4, 40, L"%d", NULL, NULL, NULL, NULL},
194 {L"Event", 4, 44, L"0x%x", NULL, NULL, NULL, NULL},
195 {L"PRI", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},
196 {L"GERR", 4, 52, L"0x%x", NULL, NULL, NULL, NULL},
197 {L"Sync", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},
198 {L"Proximity domain", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},
199 {L"Device ID mapping index", 4, 64, L"%d", NULL, NULL, NULL, NULL}
200 };
201
202 /**
203 An ACPI_PARSER array describing the IORT ITS node.
204 **/
205 STATIC CONST ACPI_PARSER IortNodeItsParser[] = {
206 PARSE_IORT_NODE_HEADER (
207 ValidateItsIdMappingCount,
208 ValidateItsIdArrayReference
209 ),
210 {L"Number of ITSs", 4, 16, L"%d", NULL, (VOID**)&ItsCount, NULL}
211 };
212
213 /**
214 An ACPI_PARSER array describing the ITS ID.
215 **/
216 STATIC CONST ACPI_PARSER ItsIdParser[] = {
217 { L"GIC ITS Identifier", 4, 0, L"%d", NULL, NULL, NULL }
218 };
219
220 /**
221 An ACPI_PARSER array describing the IORT Names Component node.
222 **/
223 STATIC CONST ACPI_PARSER IortNodeNamedComponentParser[] = {
224 PARSE_IORT_NODE_HEADER (NULL, NULL),
225 {L"Node Flags", 4, 16, L"%d", NULL, NULL, NULL, NULL},
226 {L"Memory access properties", 8, 20, L"0x%lx", NULL, NULL, NULL, NULL},
227 {L"Device memory address size limit", 1, 28, L"%d", NULL, NULL, NULL, NULL}
228 };
229
230 /**
231 An ACPI_PARSER array describing the IORT Root Complex node.
232 **/
233 STATIC CONST ACPI_PARSER IortNodeRootComplexParser[] = {
234 PARSE_IORT_NODE_HEADER (NULL, NULL),
235 {L"Memory access properties", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
236 {L"ATS Attribute", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
237 {L"PCI Segment number", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
238 {L"Memory access size limit", 1, 32, L"0x%x", NULL, NULL, NULL, NULL},
239 {L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}
240 };
241
242 /**
243 An ACPI_PARSER array describing the IORT PMCG node.
244 **/
245 STATIC CONST ACPI_PARSER IortNodePmcgParser[] = {
246 PARSE_IORT_NODE_HEADER (ValidatePmcgIdMappingCount, NULL),
247 {L"Page 0 Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
248 {L"Overflow interrupt GSIV", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
249 {L"Node reference", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
250 {L"Page 1 Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}
251 };
252
253 /**
254 This function parses the IORT Node Id Mapping array.
255
256 @param [in] Ptr Pointer to the start of the ID mapping array.
257 @param [in] Length Length of the buffer.
258 @param [in] MappingCount The ID Mapping count.
259 **/
260 STATIC
261 VOID
262 DumpIortNodeIdMappings (
263 IN UINT8* Ptr,
264 IN UINT32 Length,
265 IN UINT32 MappingCount
266 )
267 {
268 UINT32 Index;
269 UINT32 Offset;
270 CHAR8 Buffer[40]; // Used for AsciiName param of ParseAcpi
271
272 Index = 0;
273 Offset = 0;
274
275 while ((Index < MappingCount) &&
276 (Offset < Length)) {
277 AsciiSPrint (
278 Buffer,
279 sizeof (Buffer),
280 "ID Mapping [%d]",
281 Index
282 );
283 Offset += ParseAcpi (
284 TRUE,
285 4,
286 Buffer,
287 Ptr + Offset,
288 Length - Offset,
289 PARSER_PARAMS (IortNodeIdMappingParser)
290 );
291 Index++;
292 }
293 }
294
295 /**
296 This function parses the IORT SMMUv1/2 node.
297
298 @param [in] Ptr Pointer to the start of the buffer.
299 @param [in] Length Length of the buffer.
300 @param [in] MappingCount The ID Mapping count.
301 @param [in] MappingOffset The offset of the ID Mapping array
302 from the start of the IORT table.
303 **/
304 STATIC
305 VOID
306 DumpIortNodeSmmuV1V2 (
307 IN UINT8* Ptr,
308 IN UINT16 Length,
309 IN UINT32 MappingCount,
310 IN UINT32 MappingOffset
311 )
312 {
313 UINT32 Index;
314 UINT32 Offset;
315 CHAR8 Buffer[50]; // Used for AsciiName param of ParseAcpi
316
317 ParseAcpi (
318 TRUE,
319 2,
320 "SMMUv1 or SMMUv2 Node",
321 Ptr,
322 Length,
323 PARSER_PARAMS (IortNodeSmmuV1V2Parser)
324 );
325
326 // Check if the values used to control the parsing logic have been
327 // successfully read.
328 if ((InterruptContextCount == NULL) ||
329 (InterruptContextOffset == NULL) ||
330 (PmuInterruptCount == NULL) ||
331 (PmuInterruptOffset == NULL)) {
332 IncrementErrorCount ();
333 Print (
334 L"ERROR: Insufficient SMMUv1/2 node length. Length = %d\n",
335 Length
336 );
337 return;
338 }
339
340 Offset = *InterruptContextOffset;
341 Index = 0;
342
343 while ((Index < *InterruptContextCount) &&
344 (Offset < Length)) {
345 AsciiSPrint (
346 Buffer,
347 sizeof (Buffer),
348 "Context Interrupts Array [%d]",
349 Index
350 );
351 Offset += ParseAcpi (
352 TRUE,
353 4,
354 Buffer,
355 Ptr + Offset,
356 Length - Offset,
357 PARSER_PARAMS (InterruptArrayParser)
358 );
359 Index++;
360 }
361
362 Offset = *PmuInterruptOffset;
363 Index = 0;
364
365 while ((Index < *PmuInterruptCount) &&
366 (Offset < Length)) {
367 AsciiSPrint (
368 Buffer,
369 sizeof (Buffer),
370 "PMU Interrupts Array [%d]",
371 Index
372 );
373 Offset += ParseAcpi (
374 TRUE,
375 4,
376 Buffer,
377 Ptr + Offset,
378 Length - Offset,
379 PARSER_PARAMS (InterruptArrayParser)
380 );
381 Index++;
382 }
383
384 DumpIortNodeIdMappings (
385 Ptr + MappingOffset,
386 Length - MappingOffset,
387 MappingCount
388 );
389 }
390
391 /**
392 This function parses the IORT SMMUv3 node.
393
394 @param [in] Ptr Pointer to the start of the buffer.
395 @param [in] Length Length of the buffer.
396 @param [in] MappingCount The ID Mapping count.
397 @param [in] MappingOffset The offset of the ID Mapping array
398 from the start of the IORT table.
399 **/
400 STATIC
401 VOID
402 DumpIortNodeSmmuV3 (
403 IN UINT8* Ptr,
404 IN UINT16 Length,
405 IN UINT32 MappingCount,
406 IN UINT32 MappingOffset
407 )
408 {
409 ParseAcpi (
410 TRUE,
411 2,
412 "SMMUV3 Node",
413 Ptr,
414 Length,
415 PARSER_PARAMS (IortNodeSmmuV3Parser)
416 );
417
418 DumpIortNodeIdMappings (
419 Ptr + MappingOffset,
420 Length - MappingOffset,
421 MappingCount
422 );
423 }
424
425 /**
426 This function parses the IORT ITS node.
427
428 @param [in] Ptr Pointer to the start of the buffer.
429 @param [in] Length Length of the buffer.
430 **/
431 STATIC
432 VOID
433 DumpIortNodeIts (
434 IN UINT8* Ptr,
435 IN UINT16 Length
436 )
437 {
438 UINT32 Offset;
439 UINT32 Index;
440 CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi
441
442 Offset = ParseAcpi (
443 TRUE,
444 2,
445 "ITS Node",
446 Ptr,
447 Length,
448 PARSER_PARAMS (IortNodeItsParser)
449 );
450
451 // Check if the values used to control the parsing logic have been
452 // successfully read.
453 if (ItsCount == NULL) {
454 IncrementErrorCount ();
455 Print (
456 L"ERROR: Insufficient ITS group length. Length = %d.\n",
457 Length
458 );
459 return;
460 }
461
462 Index = 0;
463
464 while ((Index < *ItsCount) &&
465 (Offset < Length)) {
466 AsciiSPrint (
467 Buffer,
468 sizeof (Buffer),
469 "GIC ITS Identifier Array [%d]",
470 Index
471 );
472 Offset += ParseAcpi (
473 TRUE,
474 4,
475 Buffer,
476 Ptr + Offset,
477 Length - Offset,
478 PARSER_PARAMS (ItsIdParser)
479 );
480 Index++;
481 }
482
483 // Note: ITS does not have the ID Mappings Array
484
485 }
486
487 /**
488 This function parses the IORT Named Component node.
489
490 @param [in] Ptr Pointer to the start of the buffer.
491 @param [in] Length Length of the buffer.
492 @param [in] MappingCount The ID Mapping count.
493 @param [in] MappingOffset The offset of the ID Mapping array
494 from the start of the IORT table.
495 **/
496 STATIC
497 VOID
498 DumpIortNodeNamedComponent (
499 IN UINT8* Ptr,
500 IN UINT16 Length,
501 IN UINT32 MappingCount,
502 IN UINT32 MappingOffset
503 )
504 {
505 UINT32 Offset;
506
507 Offset = ParseAcpi (
508 TRUE,
509 2,
510 "Named Component Node",
511 Ptr,
512 Length,
513 PARSER_PARAMS (IortNodeNamedComponentParser)
514 );
515
516 // Estimate the Device Name length
517 PrintFieldName (2, L"Device Object Name");
518
519 while ((*(Ptr + Offset) != 0) &&
520 (Offset < Length)) {
521 Print (L"%c", *(Ptr + Offset));
522 Offset++;
523 }
524 Print (L"\n");
525
526 DumpIortNodeIdMappings (
527 Ptr + MappingOffset,
528 Length - MappingOffset,
529 MappingCount
530 );
531 }
532
533 /**
534 This function parses the IORT Root Complex node.
535
536 @param [in] Ptr Pointer to the start of the buffer.
537 @param [in] Length Length of the buffer.
538 @param [in] MappingCount The ID Mapping count.
539 @param [in] MappingOffset The offset of the ID Mapping array
540 from the start of the IORT table.
541 **/
542 STATIC
543 VOID
544 DumpIortNodeRootComplex (
545 IN UINT8* Ptr,
546 IN UINT16 Length,
547 IN UINT32 MappingCount,
548 IN UINT32 MappingOffset
549 )
550 {
551 ParseAcpi (
552 TRUE,
553 2,
554 "Root Complex Node",
555 Ptr,
556 Length,
557 PARSER_PARAMS (IortNodeRootComplexParser)
558 );
559
560 DumpIortNodeIdMappings (
561 Ptr + MappingOffset,
562 Length - MappingOffset,
563 MappingCount
564 );
565 }
566
567 /**
568 This function parses the IORT PMCG node.
569
570 @param [in] Ptr Pointer to the start of the buffer.
571 @param [in] Length Length of the buffer.
572 @param [in] MappingCount The ID Mapping count.
573 @param [in] MappingOffset The offset of the ID Mapping array
574 from the start of the IORT table.
575 **/
576 STATIC
577 VOID
578 DumpIortNodePmcg (
579 IN UINT8* Ptr,
580 IN UINT16 Length,
581 IN UINT32 MappingCount,
582 IN UINT32 MappingOffset
583 )
584 {
585 ParseAcpi (
586 TRUE,
587 2,
588 "PMCG Node",
589 Ptr,
590 Length,
591 PARSER_PARAMS (IortNodePmcgParser)
592 );
593
594 DumpIortNodeIdMappings (
595 Ptr + MappingOffset,
596 Length - MappingOffset,
597 MappingCount
598 );
599 }
600
601 /**
602 This function parses the ACPI IORT table.
603 When trace is enabled this function parses the IORT table and traces the ACPI fields.
604
605 This function also parses the following nodes:
606 - ITS Group
607 - Named Component
608 - Root Complex
609 - SMMUv1/2
610 - SMMUv3
611 - PMCG
612
613 This function also performs validation of the ACPI table fields.
614
615 @param [in] Trace If TRUE, trace the ACPI fields.
616 @param [in] Ptr Pointer to the start of the buffer.
617 @param [in] AcpiTableLength Length of the ACPI table.
618 @param [in] AcpiTableRevision Revision of the ACPI table.
619 **/
620 VOID
621 EFIAPI
622 ParseAcpiIort (
623 IN BOOLEAN Trace,
624 IN UINT8* Ptr,
625 IN UINT32 AcpiTableLength,
626 IN UINT8 AcpiTableRevision
627 )
628 {
629 UINT32 Offset;
630 UINT32 Index;
631 UINT8* NodePtr;
632
633 if (!Trace) {
634 return;
635 }
636
637 ParseAcpi (
638 TRUE,
639 0,
640 "IORT",
641 Ptr,
642 AcpiTableLength,
643 PARSER_PARAMS (IortParser)
644 );
645
646 // Check if the values used to control the parsing logic have been
647 // successfully read.
648 if ((IortNodeCount == NULL) ||
649 (IortNodeOffset == NULL)) {
650 IncrementErrorCount ();
651 Print (
652 L"ERROR: Insufficient table length. AcpiTableLength = %d.\n",
653 AcpiTableLength
654 );
655 return;
656 }
657
658 Offset = *IortNodeOffset;
659 NodePtr = Ptr + Offset;
660 Index = 0;
661
662 // Parse the specified number of IORT nodes or the IORT table buffer length.
663 // Whichever is minimum.
664 while ((Index++ < *IortNodeCount) &&
665 (Offset < AcpiTableLength)) {
666 // Parse the IORT Node Header
667 ParseAcpi (
668 FALSE,
669 0,
670 "IORT Node Header",
671 NodePtr,
672 AcpiTableLength - Offset,
673 PARSER_PARAMS (IortNodeHeaderParser)
674 );
675
676 // Check if the values used to control the parsing logic have been
677 // successfully read.
678 if ((IortNodeType == NULL) ||
679 (IortNodeLength == NULL) ||
680 (IortIdMappingCount == NULL) ||
681 (IortIdMappingOffset == NULL)) {
682 IncrementErrorCount ();
683 Print (
684 L"ERROR: Insufficient remaining table buffer length to read the " \
685 L"IORT node header. Length = %d.\n",
686 AcpiTableLength - Offset
687 );
688 return;
689 }
690
691 // Validate IORT Node length
692 if ((*IortNodeLength == 0) ||
693 ((Offset + (*IortNodeLength)) > AcpiTableLength)) {
694 IncrementErrorCount ();
695 Print (
696 L"ERROR: Invalid IORT Node length. " \
697 L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
698 *IortNodeLength,
699 Offset,
700 AcpiTableLength
701 );
702 return;
703 }
704
705 PrintFieldName (2, L"* Node Offset *");
706 Print (L"0x%x\n", Offset);
707
708 switch (*IortNodeType) {
709 case EFI_ACPI_IORT_TYPE_ITS_GROUP:
710 DumpIortNodeIts (
711 NodePtr,
712 *IortNodeLength
713 );
714 break;
715 case EFI_ACPI_IORT_TYPE_NAMED_COMP:
716 DumpIortNodeNamedComponent (
717 NodePtr,
718 *IortNodeLength,
719 *IortIdMappingCount,
720 *IortIdMappingOffset
721 );
722 break;
723 case EFI_ACPI_IORT_TYPE_ROOT_COMPLEX:
724 DumpIortNodeRootComplex (
725 NodePtr,
726 *IortNodeLength,
727 *IortIdMappingCount,
728 *IortIdMappingOffset
729 );
730 break;
731 case EFI_ACPI_IORT_TYPE_SMMUv1v2:
732 DumpIortNodeSmmuV1V2 (
733 NodePtr,
734 *IortNodeLength,
735 *IortIdMappingCount,
736 *IortIdMappingOffset
737 );
738 break;
739 case EFI_ACPI_IORT_TYPE_SMMUv3:
740 DumpIortNodeSmmuV3 (
741 NodePtr,
742 *IortNodeLength,
743 *IortIdMappingCount,
744 *IortIdMappingOffset
745 );
746 break;
747 case EFI_ACPI_IORT_TYPE_PMCG:
748 DumpIortNodePmcg (
749 NodePtr,
750 *IortNodeLength,
751 *IortIdMappingCount,
752 *IortIdMappingOffset
753 );
754 break;
755
756 default:
757 IncrementErrorCount ();
758 Print (L"ERROR: Unsupported IORT Node type = %d\n", *IortNodeType);
759 } // switch
760
761 NodePtr += (*IortNodeLength);
762 Offset += (*IortNodeLength);
763 } // while
764 }