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