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