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