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