1 /******************************************************************************
2  *
3  * Module Name: dmtbdump2 - Dump ACPI data tables that contain no AML code
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <wchar.h>
153 #include <contrib/dev/acpica/include/acpi.h>
154 #include <contrib/dev/acpica/include/accommon.h>
155 #include <contrib/dev/acpica/include/acdisasm.h>
156 #include <contrib/dev/acpica/include/actables.h>
157 #include <contrib/dev/acpica/compiler/aslcompiler.h>
158 
159 /* This module used for application-level code only */
160 
161 #define _COMPONENT          ACPI_CA_DISASSEMBLER
162         ACPI_MODULE_NAME    ("dmtbdump2")
163 
164 
165 /*******************************************************************************
166  *
167  * FUNCTION:    AcpiDmDumpIort
168  *
169  * PARAMETERS:  Table               - A IORT table
170  *
171  * RETURN:      None
172  *
173  * DESCRIPTION: Format the contents of a IORT
174  *
175  ******************************************************************************/
176 
177 void
178 AcpiDmDumpIort (
179     ACPI_TABLE_HEADER       *Table)
180 {
181     ACPI_STATUS             Status;
182     ACPI_TABLE_IORT         *Iort;
183     ACPI_IORT_NODE          *IortNode;
184     ACPI_IORT_ITS_GROUP     *IortItsGroup = NULL;
185     ACPI_IORT_SMMU          *IortSmmu = NULL;
186     ACPI_IORT_RMR           *IortRmr = NULL;
187     UINT32                  Offset;
188     UINT32                  NodeOffset;
189     UINT32                  Length;
190     ACPI_DMTABLE_INFO       *InfoTable;
191     char                    *String;
192     UINT32                  i;
193     UINT32                  MappingByteLength;
194     UINT8                   Revision;
195 
196 
197     /* Main table */
198 
199     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIort);
200     if (ACPI_FAILURE (Status))
201     {
202         return;
203     }
204 
205     Revision = Table->Revision;
206 
207     /* IORT Revisions E, E.a and E.c have known issues and are not supported */
208 
209     if (Revision == 1 || Revision == 2 || Revision == 4)
210     {
211         AcpiOsPrintf ("\n**** Unsupported IORT revision 0x%X\n",
212                       Revision);
213         return;
214     }
215 
216     Iort = ACPI_CAST_PTR (ACPI_TABLE_IORT, Table);
217     Offset = sizeof (ACPI_TABLE_IORT);
218 
219     /* Dump the OptionalPadding (optional) */
220 
221     if (Iort->NodeOffset > Offset)
222     {
223         Status = AcpiDmDumpTable (Table->Length, Offset, Table,
224             Iort->NodeOffset - Offset, AcpiDmTableInfoIortPad);
225         if (ACPI_FAILURE (Status))
226         {
227             return;
228         }
229     }
230 
231     Offset = Iort->NodeOffset;
232     while (Offset < Table->Length)
233     {
234         /* Common subtable header */
235 
236         IortNode = ACPI_ADD_PTR (ACPI_IORT_NODE, Table, Offset);
237         AcpiOsPrintf ("\n");
238         Length = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
239 
240         if (Revision == 0)
241         {
242             Status = AcpiDmDumpTable (Table->Length, Offset,
243                 IortNode, Length, AcpiDmTableInfoIortHdr);
244         }
245         else if (Revision >= 3)
246         {
247             Status = AcpiDmDumpTable (Table->Length, Offset,
248                 IortNode, Length, AcpiDmTableInfoIortHdr3);
249         }
250 
251         if (ACPI_FAILURE (Status))
252         {
253             return;
254         }
255 
256         NodeOffset = Length;
257 
258         switch (IortNode->Type)
259         {
260         case ACPI_IORT_NODE_ITS_GROUP:
261 
262             InfoTable = AcpiDmTableInfoIort0;
263             Length = ACPI_OFFSET (ACPI_IORT_ITS_GROUP, Identifiers);
264             IortItsGroup = ACPI_ADD_PTR (ACPI_IORT_ITS_GROUP, IortNode, NodeOffset);
265             break;
266 
267         case ACPI_IORT_NODE_NAMED_COMPONENT:
268 
269             InfoTable = AcpiDmTableInfoIort1;
270             Length = ACPI_OFFSET (ACPI_IORT_NAMED_COMPONENT, DeviceName);
271             String = ACPI_ADD_PTR (char, IortNode, NodeOffset + Length);
272             Length += strlen (String) + 1;
273             break;
274 
275         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
276 
277             InfoTable = AcpiDmTableInfoIort2;
278             Length = IortNode->Length - NodeOffset;
279             break;
280 
281         case ACPI_IORT_NODE_SMMU:
282 
283             InfoTable = AcpiDmTableInfoIort3;
284             Length = ACPI_OFFSET (ACPI_IORT_SMMU, Interrupts);
285             IortSmmu = ACPI_ADD_PTR (ACPI_IORT_SMMU, IortNode, NodeOffset);
286             break;
287 
288         case ACPI_IORT_NODE_SMMU_V3:
289 
290             InfoTable = AcpiDmTableInfoIort4;
291             Length = IortNode->Length - NodeOffset;
292             break;
293 
294         case ACPI_IORT_NODE_PMCG:
295 
296             InfoTable = AcpiDmTableInfoIort5;
297             Length = IortNode->Length - NodeOffset;
298             break;
299 
300         case ACPI_IORT_NODE_RMR:
301 
302             InfoTable = AcpiDmTableInfoIort6;
303             Length = IortNode->Length - NodeOffset;
304             IortRmr = ACPI_ADD_PTR (ACPI_IORT_RMR, IortNode, NodeOffset);
305             break;
306 
307         default:
308 
309             AcpiOsPrintf ("\n**** Unknown IORT node type 0x%X\n",
310                 IortNode->Type);
311 
312             /* Attempt to continue */
313 
314             if (!IortNode->Length)
315             {
316                 AcpiOsPrintf ("Invalid zero length IORT node\n");
317                 return;
318             }
319             goto NextSubtable;
320         }
321 
322         /* Dump the node subtable header */
323 
324         AcpiOsPrintf ("\n");
325         Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
326             ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
327             Length, InfoTable);
328         if (ACPI_FAILURE (Status))
329         {
330             return;
331         }
332 
333         NodeOffset += Length;
334 
335         /* Dump the node specific data */
336 
337         switch (IortNode->Type)
338         {
339         case ACPI_IORT_NODE_ITS_GROUP:
340 
341             /* Validate IortItsGroup to avoid compiler warnings */
342 
343             if (IortItsGroup)
344             {
345                 for (i = 0; i < IortItsGroup->ItsCount; i++)
346                 {
347                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
348                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
349                         4, AcpiDmTableInfoIort0a);
350                     if (ACPI_FAILURE (Status))
351                     {
352                         return;
353                     }
354 
355                     NodeOffset += 4;
356                 }
357             }
358             break;
359 
360         case ACPI_IORT_NODE_NAMED_COMPONENT:
361 
362             /* Dump the Padding (optional) */
363 
364             if (IortNode->Length > NodeOffset)
365             {
366                 MappingByteLength =
367                     IortNode->MappingCount * sizeof (ACPI_IORT_ID_MAPPING);
368                 Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
369                     Table, IortNode->Length - NodeOffset - MappingByteLength,
370                     AcpiDmTableInfoIort1a);
371                 if (ACPI_FAILURE (Status))
372                 {
373                     return;
374                 }
375             }
376             break;
377 
378         case ACPI_IORT_NODE_SMMU:
379 
380             AcpiOsPrintf ("\n");
381 
382             /* Validate IortSmmu to avoid compiler warnings */
383 
384             if (IortSmmu)
385             {
386                 Length = 2 * sizeof (UINT64);
387                 NodeOffset = IortSmmu->GlobalInterruptOffset;
388                 Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
389                     ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
390                     Length, AcpiDmTableInfoIort3a);
391                 if (ACPI_FAILURE (Status))
392                 {
393                     return;
394                 }
395 
396                 NodeOffset = IortSmmu->ContextInterruptOffset;
397                 for (i = 0; i < IortSmmu->ContextInterruptCount; i++)
398                 {
399                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
400                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
401                         8, AcpiDmTableInfoIort3b);
402                     if (ACPI_FAILURE (Status))
403                     {
404                         return;
405                     }
406 
407                     NodeOffset += 8;
408                 }
409 
410                 NodeOffset = IortSmmu->PmuInterruptOffset;
411                 for (i = 0; i < IortSmmu->PmuInterruptCount; i++)
412                 {
413                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
414                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
415                         8, AcpiDmTableInfoIort3c);
416                     if (ACPI_FAILURE (Status))
417                     {
418                         return;
419                     }
420 
421                     NodeOffset += 8;
422                 }
423             }
424             break;
425 
426         case ACPI_IORT_NODE_RMR:
427 
428             /* Validate IortRmr to avoid compiler warnings */
429             if (IortRmr)
430             {
431                 NodeOffset = IortRmr->RmrOffset;
432                 Length = sizeof (ACPI_IORT_RMR_DESC);
433                 for (i = 0; i < IortRmr->RmrCount; i++)
434                 {
435                     AcpiOsPrintf ("\n");
436                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
437                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
438                         Length, AcpiDmTableInfoIort6a);
439                     if (ACPI_FAILURE (Status))
440                     {
441                         return;
442                     }
443 
444                     NodeOffset += Length;
445                 }
446             }
447             break;
448 
449         default:
450 
451             break;
452         }
453 
454         /* Dump the ID mappings */
455 
456         NodeOffset = IortNode->MappingOffset;
457         for (i = 0; i < IortNode->MappingCount; i++)
458         {
459             AcpiOsPrintf ("\n");
460             Length = sizeof (ACPI_IORT_ID_MAPPING);
461             Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
462                 ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
463                 Length, AcpiDmTableInfoIortMap);
464             if (ACPI_FAILURE (Status))
465             {
466                 return;
467             }
468 
469             NodeOffset += Length;
470         }
471 
472 NextSubtable:
473         /* Point to next node subtable */
474 
475         Offset += IortNode->Length;
476     }
477 }
478 
479 
480 /*******************************************************************************
481  *
482  * FUNCTION:    AcpiDmDumpIvrs
483  *
484  * PARAMETERS:  Table               - A IVRS table
485  *
486  * RETURN:      None
487  *
488  * DESCRIPTION: Format the contents of a IVRS. Notes:
489  *              The IVRS is essentially a flat table, with the following
490  *              structure:
491  *              <Main ACPI Table Header>
492  *              <Main subtable - virtualization info>
493  *              <IVHD>
494  *                  <Device Entries>
495  *              ...
496  *              <IVHD>
497  *                  <Device Entries>
498  *              <IVMD>
499  *              ...
500  *
501  ******************************************************************************/
502 
503 void
504 AcpiDmDumpIvrs (
505     ACPI_TABLE_HEADER       *Table)
506 {
507     ACPI_STATUS             Status;
508     UINT32                  Offset = sizeof (ACPI_TABLE_IVRS);
509     UINT32                  EntryOffset;
510     UINT32                  EntryLength;
511     UINT32                  EntryType;
512     ACPI_IVRS_DEVICE_HID    *HidSubtable;
513     ACPI_IVRS_DE_HEADER     *DeviceEntry;
514     ACPI_IVRS_HEADER        *Subtable;
515     ACPI_DMTABLE_INFO       *InfoTable;
516 
517 
518     /* Main table */
519 
520     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs);
521     if (ACPI_FAILURE (Status))
522     {
523         return;
524     }
525 
526     /* Subtables */
527 
528     Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
529 
530     while (Offset < Table->Length)
531     {
532         switch (Subtable->Type)
533         {
534         /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
535 
536         case ACPI_IVRS_TYPE_HARDWARE1:
537 
538             AcpiOsPrintf ("\n");
539             InfoTable = AcpiDmTableInfoIvrsHware1;
540             break;
541 
542         /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
543 
544         case ACPI_IVRS_TYPE_HARDWARE2:
545         case ACPI_IVRS_TYPE_HARDWARE3:
546 
547             AcpiOsPrintf ("\n");
548             InfoTable = AcpiDmTableInfoIvrsHware23;
549             break;
550 
551         /* Types 20h-22h, IVMD (I/O Virtualization Memory Definition Block) */
552 
553         case ACPI_IVRS_TYPE_MEMORY1:
554         case ACPI_IVRS_TYPE_MEMORY2:
555         case ACPI_IVRS_TYPE_MEMORY3:
556 
557             AcpiOsPrintf ("\n");
558             InfoTable = AcpiDmTableInfoIvrsMemory;
559             break;
560 
561         default:
562 
563             AcpiOsPrintf ("\n**** Unknown IVRS subtable type 0x%X\n",
564                 Subtable->Type);
565 
566             /* Attempt to continue */
567 
568             if (!Subtable->Length)
569             {
570                 AcpiOsPrintf ("Invalid zero length subtable\n");
571                 return;
572             }
573             goto NextSubtable;
574         }
575 
576         /* Dump the subtable */
577 
578         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
579             Subtable->Length, InfoTable);
580         if (ACPI_FAILURE (Status))
581         {
582             return;
583         }
584 
585         /* The hardware subtables (IVHD) can contain multiple device entries */
586 
587         if (Subtable->Type == ACPI_IVRS_TYPE_HARDWARE1 ||
588             Subtable->Type == ACPI_IVRS_TYPE_HARDWARE2 ||
589             Subtable->Type == ACPI_IVRS_TYPE_HARDWARE3)
590         {
591             if (Subtable->Type == ACPI_IVRS_TYPE_HARDWARE1)
592             {
593                 EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE1);
594                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, Subtable,
595                     sizeof (ACPI_IVRS_HARDWARE1));
596             }
597             else
598             {
599                 /* ACPI_IVRS_TYPE_HARDWARE2, HARDWARE3 subtable types */
600 
601                 EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE2);
602                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, Subtable,
603                     sizeof (ACPI_IVRS_HARDWARE2));
604             }
605 
606             /* Process all of the Device Entries */
607 
608             while (EntryOffset < (Offset + Subtable->Length))
609             {
610                 AcpiOsPrintf ("\n");
611 
612                 /*
613                  * Upper 2 bits of Type encode the length of the device entry
614                  *
615                  * 00 = 4 byte
616                  * 01 = 8 byte
617                  * 1x = variable length
618                  */
619                 EntryType = DeviceEntry->Type;
620                 EntryLength = EntryType >> 6 == 1 ? 8 : 4;
621 
622                 switch (EntryType)
623                 {
624                 /* 4-byte device entries */
625 
626                 case ACPI_IVRS_TYPE_PAD4:
627                 case ACPI_IVRS_TYPE_ALL:
628                 case ACPI_IVRS_TYPE_SELECT:
629                 case ACPI_IVRS_TYPE_START:
630                 case ACPI_IVRS_TYPE_END:
631 
632                     InfoTable = AcpiDmTableInfoIvrs4;
633                     break;
634 
635                 /* 8-byte entries, type A */
636 
637                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
638                 case ACPI_IVRS_TYPE_ALIAS_START:
639 
640                     InfoTable = AcpiDmTableInfoIvrs8a;
641                     break;
642 
643                 /* 8-byte entries, type B */
644 
645                 case ACPI_IVRS_TYPE_PAD8:
646                 case ACPI_IVRS_TYPE_EXT_SELECT:
647                 case ACPI_IVRS_TYPE_EXT_START:
648 
649                     InfoTable = AcpiDmTableInfoIvrs8b;
650                     break;
651 
652                 /* 8-byte entries, type C */
653 
654                 case ACPI_IVRS_TYPE_SPECIAL:
655 
656                     InfoTable = AcpiDmTableInfoIvrs8c;
657                     break;
658 
659                 /* Variable-length entries */
660 
661                 case ACPI_IVRS_TYPE_HID:
662 
663                     EntryLength = 4;
664                     InfoTable = AcpiDmTableInfoIvrsHid;
665                     break;
666 
667                 default:
668                     InfoTable = AcpiDmTableInfoIvrs4;
669                     AcpiOsPrintf (
670                         "\n**** Unknown IVRS device entry type/length: "
671                         "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
672                         EntryType, EntryLength, EntryOffset);
673                     break;
674                 }
675 
676                 /* Dump the Device Entry */
677 
678                 Status = AcpiDmDumpTable (Table->Length, EntryOffset,
679                     DeviceEntry, EntryLength, InfoTable);
680                 if (ACPI_FAILURE (Status))
681                 {
682                     return;
683                 }
684 
685                 HidSubtable = ACPI_CAST_PTR (ACPI_IVRS_DEVICE_HID, DeviceEntry);
686                 EntryOffset += EntryLength;
687                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, HidSubtable,
688                     EntryLength);
689 
690                 if (EntryType == ACPI_IVRS_TYPE_HID)
691                 {
692                     /*
693                      * Determine if the HID is an integer or a string.
694                      * An integer is defined to be 32 bits, with the upper 32 bits
695                      * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
696                      * integer or a character string. If an integer, the lower
697                      * 4 bytes of the field contain the integer and the upper
698                      * 4 bytes are padded with 0".
699                      */
700                     if (UtIsIdInteger ((UINT8 *) &HidSubtable->AcpiHid))
701                     {
702                         Status = AcpiDmDumpTable (Table->Length, EntryOffset,
703                             &HidSubtable->AcpiHid, 8, AcpiDmTableInfoIvrsHidInteger);
704                     }
705                     else
706                     {
707                         Status = AcpiDmDumpTable (Table->Length, EntryOffset,
708                             &HidSubtable->AcpiHid, 8, AcpiDmTableInfoIvrsHidString);
709                     }
710                     if (ACPI_FAILURE (Status))
711                     {
712                         return;
713                     }
714 
715                     EntryOffset += 8;
716 
717                     /*
718                      * Determine if the CID is an integer or a string. The format
719                      * of the CID is the same as the HID above. From ACPI Spec:
720                      * "If present, CID must be a single Compatible Device ID
721                      * following the same format as the HID field."
722                      */
723                     if (UtIsIdInteger ((UINT8 *) &HidSubtable->AcpiCid))
724                     {
725                         Status = AcpiDmDumpTable (Table->Length, EntryOffset,
726                             &HidSubtable->AcpiCid, 8, AcpiDmTableInfoIvrsCidInteger);
727                     }
728                     else
729                     {
730                         Status = AcpiDmDumpTable (Table->Length, EntryOffset,
731                             &HidSubtable->AcpiCid, 8, AcpiDmTableInfoIvrsCidString);
732                     }
733                     if (ACPI_FAILURE (Status))
734                     {
735                         return;
736                     }
737 
738                     EntryOffset += 8;
739                     EntryLength = HidSubtable->UidLength;
740 
741                     if (EntryLength > ACPI_IVRS_UID_NOT_PRESENT)
742                     {
743                         /* Dump the UID based upon the UidType field (String or Integer) */
744 
745                         if (HidSubtable->UidType == ACPI_IVRS_UID_IS_STRING)
746                         {
747                             Status = AcpiDmDumpTable (Table->Length, EntryOffset,
748                                 &HidSubtable->UidType, EntryLength, AcpiDmTableInfoIvrsUidString);
749                             if (ACPI_FAILURE (Status))
750                             {
751                                 return;
752                             }
753                         }
754                         else /* ACPI_IVRS_UID_IS_INTEGER */
755                         {
756                             Status = AcpiDmDumpTable (Table->Length, EntryOffset,
757                                 &HidSubtable->UidType, EntryLength, AcpiDmTableInfoIvrsUidInteger);
758                             if (ACPI_FAILURE (Status))
759                             {
760                                 return;
761                             }
762                         }
763                     }
764 
765                     EntryOffset += EntryLength+2;
766                     DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER,
767                         Table, EntryOffset);
768                 }
769             }
770         }
771 
772 NextSubtable:
773         /* Point to next subtable */
774 
775         Offset += Subtable->Length;
776         Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Subtable, Subtable->Length);
777     }
778 }
779 
780 
781 /*******************************************************************************
782  *
783  * FUNCTION:    AcpiDmDumpLpit
784  *
785  * PARAMETERS:  Table               - A LPIT table
786  *
787  * RETURN:      None
788  *
789  * DESCRIPTION: Format the contents of a LPIT. This table type consists
790  *              of an open-ended number of subtables. Note: There are no
791  *              entries in the main table. An LPIT consists of the table
792  *              header and then subtables only.
793  *
794  ******************************************************************************/
795 
796 void
797 AcpiDmDumpLpit (
798     ACPI_TABLE_HEADER       *Table)
799 {
800     ACPI_STATUS             Status;
801     ACPI_LPIT_HEADER        *Subtable;
802     UINT32                  Length = Table->Length;
803     UINT32                  Offset = sizeof (ACPI_TABLE_LPIT);
804     ACPI_DMTABLE_INFO       *InfoTable;
805     UINT32                  SubtableLength;
806 
807 
808     /* Subtables */
809 
810     Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset);
811     while (Offset < Table->Length)
812     {
813         /* Common subtable header */
814 
815         Status = AcpiDmDumpTable (Length, Offset, Subtable,
816             sizeof (ACPI_LPIT_HEADER), AcpiDmTableInfoLpitHdr);
817         if (ACPI_FAILURE (Status))
818         {
819             return;
820         }
821 
822         switch (Subtable->Type)
823         {
824         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
825 
826             InfoTable = AcpiDmTableInfoLpit0;
827             SubtableLength = sizeof (ACPI_LPIT_NATIVE);
828             break;
829 
830         default:
831 
832             /* Cannot continue on unknown type - no length */
833 
834             AcpiOsPrintf ("\n**** Unknown LPIT subtable type 0x%X\n",
835                 Subtable->Type);
836             return;
837         }
838 
839         Status = AcpiDmDumpTable (Length, Offset, Subtable,
840             SubtableLength, InfoTable);
841         if (ACPI_FAILURE (Status))
842         {
843             return;
844         }
845 
846         AcpiOsPrintf ("\n");
847 
848         /* Point to next subtable */
849 
850         Offset += SubtableLength;
851         Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Subtable, SubtableLength);
852     }
853 }
854 
855 
856 /*******************************************************************************
857  *
858  * FUNCTION:    AcpiDmDumpMadt
859  *
860  * PARAMETERS:  Table               - A MADT table
861  *
862  * RETURN:      None
863  *
864  * DESCRIPTION: Format the contents of a MADT. This table type consists
865  *              of an open-ended number of subtables.
866  *
867  ******************************************************************************/
868 
869 void
870 AcpiDmDumpMadt (
871     ACPI_TABLE_HEADER       *Table)
872 {
873     ACPI_STATUS             Status;
874     ACPI_SUBTABLE_HEADER    *Subtable;
875     UINT32                  Length = Table->Length;
876     UINT32                  Offset = sizeof (ACPI_TABLE_MADT);
877     ACPI_DMTABLE_INFO       *InfoTable;
878 
879 
880     /* Main table */
881 
882     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoMadt);
883     if (ACPI_FAILURE (Status))
884     {
885         return;
886     }
887 
888     /* Subtables */
889 
890     Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
891     DbgPrint (ASL_PARSE_OUTPUT, "//0B) Offset %X, from table start: 0x%8.8X%8.8X\n",
892         Offset, ACPI_FORMAT_UINT64 (ACPI_CAST_PTR (char, Subtable) - ACPI_CAST_PTR (char, Table)));
893     while (Offset < Table->Length)
894     {
895         /* Common subtable header */
896 
897         AcpiOsPrintf ("\n");
898         Status = AcpiDmDumpTable (Length, Offset, Subtable,
899             Subtable->Length, AcpiDmTableInfoMadtHdr);
900         if (ACPI_FAILURE (Status))
901         {
902             return;
903         }
904 
905         DbgPrint (ASL_PARSE_OUTPUT, "subtableType: %X\n", Subtable->Type);
906         switch (Subtable->Type)
907         {
908         case ACPI_MADT_TYPE_LOCAL_APIC:
909 
910             InfoTable = AcpiDmTableInfoMadt0;
911             break;
912 
913         case ACPI_MADT_TYPE_IO_APIC:
914 
915             InfoTable = AcpiDmTableInfoMadt1;
916             break;
917 
918         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
919 
920             InfoTable = AcpiDmTableInfoMadt2;
921             break;
922 
923         case ACPI_MADT_TYPE_NMI_SOURCE:
924 
925             InfoTable = AcpiDmTableInfoMadt3;
926             break;
927 
928         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
929 
930             InfoTable = AcpiDmTableInfoMadt4;
931             break;
932 
933         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
934 
935             InfoTable = AcpiDmTableInfoMadt5;
936             break;
937 
938         case ACPI_MADT_TYPE_IO_SAPIC:
939 
940             InfoTable = AcpiDmTableInfoMadt6;
941             break;
942 
943         case ACPI_MADT_TYPE_LOCAL_SAPIC:
944 
945             InfoTable = AcpiDmTableInfoMadt7;
946             break;
947 
948         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
949 
950             InfoTable = AcpiDmTableInfoMadt8;
951             break;
952 
953         case ACPI_MADT_TYPE_LOCAL_X2APIC:
954 
955             InfoTable = AcpiDmTableInfoMadt9;
956             break;
957 
958         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
959 
960             InfoTable = AcpiDmTableInfoMadt10;
961             break;
962 
963         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
964 
965             InfoTable = AcpiDmTableInfoMadt11;
966             break;
967 
968         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
969 
970             InfoTable = AcpiDmTableInfoMadt12;
971             break;
972 
973         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
974 
975             InfoTable = AcpiDmTableInfoMadt13;
976             break;
977 
978         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
979 
980             InfoTable = AcpiDmTableInfoMadt14;
981             break;
982 
983         case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
984 
985             InfoTable = AcpiDmTableInfoMadt15;
986             break;
987 
988         case ACPI_MADT_TYPE_MULTIPROC_WAKEUP:
989 
990             InfoTable = AcpiDmTableInfoMadt16;
991             break;
992 
993         default:
994 
995             if ((Subtable->Type >= ACPI_MADT_TYPE_RESERVED) &&
996                 (Subtable->Type < ACPI_MADT_TYPE_OEM_RESERVED))
997             {
998                 AcpiOsPrintf ("\n**** Unknown MADT subtable type 0x%X\n\n",
999                     Subtable->Type);
1000                 goto NextSubtable;
1001             }
1002             else if (Subtable->Type >= ACPI_MADT_TYPE_OEM_RESERVED)
1003             {
1004                 DbgPrint (ASL_PARSE_OUTPUT, "//[Found an OEM structure, type = %0x]\n",
1005                     Subtable->Type);
1006                 Offset += sizeof (ACPI_SUBTABLE_HEADER);
1007                 DbgPrint (ASL_PARSE_OUTPUT, "//[0) Subtable->Length = %X, Subtable = %p, Offset = %X]\n",
1008                     Subtable->Length, Subtable, Offset);
1009                 DbgPrint (ASL_PARSE_OUTPUT, "//[0A) Offset from table start: 0x%8.8X%8.8X]\n",
1010                     ACPI_FORMAT_UINT64 (ACPI_CAST_PTR (char, Subtable) - ACPI_CAST_PTR (char, Table)));
1011             }
1012 
1013             /* Attempt to continue */
1014 
1015             if (!Subtable->Length)
1016             {
1017                 AcpiOsPrintf ("Invalid zero length subtable\n");
1018                 return;
1019             }
1020 
1021             /* Dump the OEM data */
1022 
1023             Status = AcpiDmDumpTable (Length, Offset, ACPI_CAST_PTR (UINT8, Table) + Offset,
1024                 Subtable->Length - sizeof (ACPI_SUBTABLE_HEADER), AcpiDmTableInfoMadt17);
1025             if (ACPI_FAILURE (Status))
1026             {
1027                 return;
1028             }
1029 
1030             DbgPrint (ASL_PARSE_OUTPUT, "//[1) Subtable->Length = %X, Offset = %X]\n",
1031                 Subtable->Length, Offset);
1032             Offset -= sizeof (ACPI_SUBTABLE_HEADER);
1033 
1034             goto NextSubtable;
1035         }
1036 
1037         DbgPrint (ASL_PARSE_OUTPUT, "//[2) Subtable->Length = %X, Offset = %X]\n",
1038             Subtable->Length, Offset);
1039         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1040             Subtable->Length, InfoTable);
1041         if (ACPI_FAILURE (Status))
1042         {
1043             return;
1044         }
1045 
1046 NextSubtable:
1047         /* Point to next subtable */
1048 
1049         DbgPrint (ASL_PARSE_OUTPUT, "//[3) Subtable->Length = %X, Offset = %X]\n",
1050             Subtable->Length, Offset);
1051         DbgPrint (ASL_PARSE_OUTPUT, "//[4) Offset from table start: 0x%8.8X%8.8X (%p) %p]\n",
1052             ACPI_FORMAT_UINT64 (ACPI_CAST_PTR (UINT8, Subtable) - ACPI_CAST_PTR (UINT8, Table)), Subtable, Table);
1053         if (Offset > Table->Length)
1054         {
1055             return;
1056         }
1057 
1058         Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable,
1059             Subtable->Length);
1060 
1061         DbgPrint (ASL_PARSE_OUTPUT, "//[5) Next Subtable %p, length %X]\n",
1062             Subtable, Subtable->Length);
1063         DbgPrint (ASL_PARSE_OUTPUT, "//[5B) Offset from table start: 0x%8.8X%8.8X (%p)]\n",
1064             ACPI_FORMAT_UINT64 (ACPI_CAST_PTR (char, Subtable) - ACPI_CAST_PTR (char, Table)), Subtable);
1065 
1066         Offset = ACPI_CAST_PTR (char, Subtable) - ACPI_CAST_PTR (char, Table);
1067         if (Offset >= Table->Length)
1068         {
1069             return;
1070         }
1071     }
1072 }
1073 
1074 
1075 /*******************************************************************************
1076  *
1077  * FUNCTION:    AcpiDmDumpMcfg
1078  *
1079  * PARAMETERS:  Table               - A MCFG Table
1080  *
1081  * RETURN:      None
1082  *
1083  * DESCRIPTION: Format the contents of a MCFG table
1084  *
1085  ******************************************************************************/
1086 
1087 void
1088 AcpiDmDumpMcfg (
1089     ACPI_TABLE_HEADER       *Table)
1090 {
1091     ACPI_STATUS             Status;
1092     UINT32                  Offset = sizeof (ACPI_TABLE_MCFG);
1093     ACPI_MCFG_ALLOCATION    *Subtable;
1094 
1095 
1096     /* Main table */
1097 
1098     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMcfg);
1099     if (ACPI_FAILURE (Status))
1100     {
1101         return;
1102     }
1103 
1104     /* Subtables */
1105 
1106     Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
1107     while (Offset < Table->Length)
1108     {
1109         if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length)
1110         {
1111             AcpiOsPrintf ("Warning: there are %u invalid trailing bytes\n",
1112                 (UINT32) sizeof (ACPI_MCFG_ALLOCATION) - (Offset - Table->Length));
1113             return;
1114         }
1115 
1116         AcpiOsPrintf ("\n");
1117         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1118             sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0);
1119         if (ACPI_FAILURE (Status))
1120         {
1121             return;
1122         }
1123 
1124         /* Point to next subtable (each subtable is of fixed length) */
1125 
1126         Offset += sizeof (ACPI_MCFG_ALLOCATION);
1127         Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Subtable,
1128             sizeof (ACPI_MCFG_ALLOCATION));
1129     }
1130 }
1131 
1132 
1133 /*******************************************************************************
1134  *
1135  * FUNCTION:    AcpiDmDumpMpst
1136  *
1137  * PARAMETERS:  Table               - A MPST Table
1138  *
1139  * RETURN:      None
1140  *
1141  * DESCRIPTION: Format the contents of a MPST table
1142  *
1143  ******************************************************************************/
1144 
1145 void
1146 AcpiDmDumpMpst (
1147     ACPI_TABLE_HEADER       *Table)
1148 {
1149     ACPI_STATUS             Status;
1150     UINT32                  Offset = sizeof (ACPI_TABLE_MPST);
1151     ACPI_MPST_POWER_NODE    *Subtable0;
1152     ACPI_MPST_POWER_STATE   *Subtable0A;
1153     ACPI_MPST_COMPONENT     *Subtable0B;
1154     ACPI_MPST_DATA_HDR      *Subtable1;
1155     ACPI_MPST_POWER_DATA    *Subtable2;
1156     UINT16                  SubtableCount;
1157     UINT32                  PowerStateCount;
1158     UINT32                  ComponentCount;
1159 
1160 
1161     /* Main table */
1162 
1163     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMpst);
1164     if (ACPI_FAILURE (Status))
1165     {
1166         return;
1167     }
1168 
1169     /* Subtable: Memory Power Node(s) */
1170 
1171     SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount;
1172     Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
1173 
1174     while ((Offset < Table->Length) && SubtableCount)
1175     {
1176         AcpiOsPrintf ("\n");
1177         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0,
1178             sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0);
1179         if (ACPI_FAILURE (Status))
1180         {
1181             return;
1182         }
1183 
1184         /* Extract the sub-subtable counts */
1185 
1186         PowerStateCount = Subtable0->NumPowerStates;
1187         ComponentCount = Subtable0->NumPhysicalComponents;
1188         Offset += sizeof (ACPI_MPST_POWER_NODE);
1189 
1190         /* Sub-subtables - Memory Power State Structure(s) */
1191 
1192         Subtable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, Subtable0,
1193             sizeof (ACPI_MPST_POWER_NODE));
1194 
1195         while (PowerStateCount)
1196         {
1197             AcpiOsPrintf ("\n");
1198             Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0A,
1199                 sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A);
1200             if (ACPI_FAILURE (Status))
1201             {
1202                 return;
1203             }
1204 
1205             Subtable0A++;
1206             PowerStateCount--;
1207             Offset += sizeof (ACPI_MPST_POWER_STATE);
1208        }
1209 
1210         /* Sub-subtables - Physical Component ID Structure(s) */
1211 
1212         Subtable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, Subtable0A);
1213 
1214         if (ComponentCount)
1215         {
1216             AcpiOsPrintf ("\n");
1217         }
1218 
1219         while (ComponentCount)
1220         {
1221             Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0B,
1222                 sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B);
1223             if (ACPI_FAILURE (Status))
1224             {
1225                 return;
1226             }
1227 
1228             Subtable0B++;
1229             ComponentCount--;
1230             Offset += sizeof (ACPI_MPST_COMPONENT);
1231         }
1232 
1233         /* Point to next Memory Power Node subtable */
1234 
1235         SubtableCount--;
1236         Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Subtable0,
1237             sizeof (ACPI_MPST_POWER_NODE) +
1238             (sizeof (ACPI_MPST_POWER_STATE) * Subtable0->NumPowerStates) +
1239             (sizeof (ACPI_MPST_COMPONENT) * Subtable0->NumPhysicalComponents));
1240     }
1241 
1242     /* Subtable: Count of Memory Power State Characteristic structures */
1243 
1244     AcpiOsPrintf ("\n");
1245     Subtable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable0);
1246     Status = AcpiDmDumpTable (Table->Length, Offset, Subtable1,
1247         sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1);
1248     if (ACPI_FAILURE (Status))
1249     {
1250         return;
1251     }
1252 
1253     SubtableCount = Subtable1->CharacteristicsCount;
1254     Offset += sizeof (ACPI_MPST_DATA_HDR);
1255 
1256     /* Subtable: Memory Power State Characteristics structure(s) */
1257 
1258     Subtable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, Subtable1,
1259         sizeof (ACPI_MPST_DATA_HDR));
1260 
1261     while ((Offset < Table->Length) && SubtableCount)
1262     {
1263         AcpiOsPrintf ("\n");
1264         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable2,
1265             sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2);
1266         if (ACPI_FAILURE (Status))
1267         {
1268             return;
1269         }
1270 
1271         Subtable2++;
1272         SubtableCount--;
1273         Offset += sizeof (ACPI_MPST_POWER_DATA);
1274     }
1275 }
1276 
1277 
1278 /*******************************************************************************
1279  *
1280  * FUNCTION:    AcpiDmDumpMsct
1281  *
1282  * PARAMETERS:  Table               - A MSCT table
1283  *
1284  * RETURN:      None
1285  *
1286  * DESCRIPTION: Format the contents of a MSCT
1287  *
1288  ******************************************************************************/
1289 
1290 void
1291 AcpiDmDumpMsct (
1292     ACPI_TABLE_HEADER       *Table)
1293 {
1294     ACPI_STATUS             Status;
1295     UINT32                  Offset = sizeof (ACPI_TABLE_MSCT);
1296     ACPI_MSCT_PROXIMITY     *Subtable;
1297 
1298 
1299     /* Main table */
1300 
1301     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct);
1302     if (ACPI_FAILURE (Status))
1303     {
1304         return;
1305     }
1306 
1307     /* Subtables */
1308 
1309     Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
1310     while (Offset < Table->Length)
1311     {
1312         /* Common subtable header */
1313 
1314         AcpiOsPrintf ("\n");
1315         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1316             sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0);
1317         if (ACPI_FAILURE (Status))
1318         {
1319             return;
1320         }
1321 
1322         /* Point to next subtable */
1323 
1324         Offset += sizeof (ACPI_MSCT_PROXIMITY);
1325         Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Subtable,
1326             sizeof (ACPI_MSCT_PROXIMITY));
1327     }
1328 }
1329 
1330 
1331 /*******************************************************************************
1332  *
1333  * FUNCTION:    AcpiDmDumpNfit
1334  *
1335  * PARAMETERS:  Table               - A NFIT table
1336  *
1337  * RETURN:      None
1338  *
1339  * DESCRIPTION: Format the contents of an NFIT.
1340  *
1341  ******************************************************************************/
1342 
1343 void
1344 AcpiDmDumpNfit (
1345     ACPI_TABLE_HEADER       *Table)
1346 {
1347     ACPI_STATUS             Status;
1348     UINT32                  Offset = sizeof (ACPI_TABLE_NFIT);
1349     UINT32                  FieldOffset = 0;
1350     UINT32                  Length;
1351     ACPI_NFIT_HEADER        *Subtable;
1352     ACPI_DMTABLE_INFO       *InfoTable;
1353     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
1354     ACPI_NFIT_SMBIOS        *SmbiosInfo = NULL;
1355     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
1356     UINT32                  i;
1357 
1358 
1359     /* Main table */
1360 
1361     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoNfit);
1362     if (ACPI_FAILURE (Status))
1363     {
1364         return;
1365     }
1366 
1367     /* Subtables */
1368 
1369     Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset);
1370     while (Offset < Table->Length)
1371     {
1372         /* NFIT subtable header */
1373 
1374         AcpiOsPrintf ("\n");
1375         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1376             Subtable->Length, AcpiDmTableInfoNfitHdr);
1377         if (ACPI_FAILURE (Status))
1378         {
1379             return;
1380         }
1381 
1382         switch (Subtable->Type)
1383         {
1384         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
1385 
1386             InfoTable = AcpiDmTableInfoNfit0;
1387             break;
1388 
1389         case ACPI_NFIT_TYPE_MEMORY_MAP:
1390 
1391             InfoTable = AcpiDmTableInfoNfit1;
1392             break;
1393 
1394         case ACPI_NFIT_TYPE_INTERLEAVE:
1395 
1396             /* Has a variable number of 32-bit values at the end */
1397 
1398             InfoTable = AcpiDmTableInfoNfit2;
1399             FieldOffset = sizeof (ACPI_NFIT_INTERLEAVE);
1400             break;
1401 
1402         case ACPI_NFIT_TYPE_SMBIOS:
1403 
1404             SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, Subtable);
1405             InfoTable = AcpiDmTableInfoNfit3;
1406             break;
1407 
1408         case ACPI_NFIT_TYPE_CONTROL_REGION:
1409 
1410             InfoTable = AcpiDmTableInfoNfit4;
1411             break;
1412 
1413         case ACPI_NFIT_TYPE_DATA_REGION:
1414 
1415             InfoTable = AcpiDmTableInfoNfit5;
1416             break;
1417 
1418         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1419 
1420             /* Has a variable number of 64-bit addresses at the end */
1421 
1422             InfoTable = AcpiDmTableInfoNfit6;
1423             FieldOffset = sizeof (ACPI_NFIT_FLUSH_ADDRESS) - sizeof (UINT64);
1424             break;
1425 
1426         case ACPI_NFIT_TYPE_CAPABILITIES:    /* ACPI 6.0A */
1427 
1428             InfoTable = AcpiDmTableInfoNfit7;
1429             break;
1430 
1431         default:
1432             AcpiOsPrintf ("\n**** Unknown NFIT subtable type 0x%X\n",
1433                 Subtable->Type);
1434 
1435             /* Attempt to continue */
1436 
1437             if (!Subtable->Length)
1438             {
1439                 AcpiOsPrintf ("Invalid zero length subtable\n");
1440                 return;
1441             }
1442             goto NextSubtable;
1443         }
1444 
1445         AcpiOsPrintf ("\n");
1446         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1447             Subtable->Length, InfoTable);
1448         if (ACPI_FAILURE (Status))
1449         {
1450             return;
1451         }
1452 
1453         /* Per-subtable variable-length fields */
1454 
1455         switch (Subtable->Type)
1456         {
1457         case ACPI_NFIT_TYPE_INTERLEAVE:
1458 
1459             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable);
1460             for (i = 0; i < Interleave->LineCount; i++)
1461             {
1462                 Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
1463                     &Interleave->LineOffset[i],
1464                     sizeof (UINT32), AcpiDmTableInfoNfit2a);
1465                 if (ACPI_FAILURE (Status))
1466                 {
1467                     return;
1468                 }
1469 
1470                 FieldOffset += sizeof (UINT32);
1471             }
1472             break;
1473 
1474         case ACPI_NFIT_TYPE_SMBIOS:
1475 
1476             Length = Subtable->Length -
1477                 sizeof (ACPI_NFIT_SMBIOS) + sizeof (UINT8);
1478 
1479             if (Length)
1480             {
1481                 Status = AcpiDmDumpTable (Table->Length,
1482                     sizeof (ACPI_NFIT_SMBIOS) - sizeof (UINT8),
1483                     SmbiosInfo,
1484                     Length, AcpiDmTableInfoNfit3a);
1485                 if (ACPI_FAILURE (Status))
1486                 {
1487                     return;
1488                 }
1489             }
1490 
1491             break;
1492 
1493         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1494 
1495             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable);
1496             for (i = 0; i < Hint->HintCount; i++)
1497             {
1498                 Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
1499                     &Hint->HintAddress[i],
1500                     sizeof (UINT64), AcpiDmTableInfoNfit6a);
1501                 if (ACPI_FAILURE (Status))
1502                 {
1503                     return;
1504                 }
1505 
1506                 FieldOffset += sizeof (UINT64);
1507             }
1508             break;
1509 
1510         default:
1511             break;
1512         }
1513 
1514 NextSubtable:
1515         /* Point to next subtable */
1516 
1517         Offset += Subtable->Length;
1518         Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Subtable, Subtable->Length);
1519     }
1520 }
1521 
1522 
1523 /*******************************************************************************
1524  *
1525  * FUNCTION:    AcpiDmDumpNhlt
1526  *
1527  * PARAMETERS:  Table               - A NHLT table
1528  *
1529  * RETURN:      None
1530  *
1531  * DESCRIPTION: Format the contents of an NHLT.
1532  *
1533  ******************************************************************************/
1534 
1535 void
1536 AcpiDmDumpNhlt (
1537     ACPI_TABLE_HEADER       *Table)
1538 {
1539     ACPI_STATUS             Status;
1540     UINT32                  Offset;
1541     UINT32                  TableLength = Table->Length;
1542     UINT32                  EndpointCount;
1543     UINT8                   FormatsCount;
1544     ACPI_NHLT_ENDPOINT      *Subtable;
1545     ACPI_NHLT_FORMAT_CONFIG *FormatSubtable;
1546     ACPI_TABLE_NHLT         *InfoTable;
1547     UINT32                  CapabilitiesSize;
1548     UINT32                  i;
1549     UINT32                  j;
1550     UINT32                  EndpointEndOffset;
1551     UINT8                   ConfigType = 0;
1552     UINT8                   ArrayType;
1553     UINT8                   MicrophoneCount;
1554     ACPI_NHLT_VENDOR_MIC_COUNT          *MicCount;
1555     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A  *DevSpecific;
1556     ACPI_NHLT_FORMATS_CONFIG            *FormatsConfig;
1557     ACPI_NHLT_DEVICE_INFO_COUNT         *Count;
1558     ACPI_NHLT_DEVICE_INFO               *DeviceInfo;
1559     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B  *Capabilities;
1560 
1561 
1562     /* Main table */
1563 
1564     AcpiOsPrintf ("    /* Main table */\n");
1565 
1566     Status = AcpiDmDumpTable (TableLength, 0, Table, 0, AcpiDmTableInfoNhlt);
1567     if (ACPI_FAILURE (Status))
1568     {
1569         return;
1570     }
1571 
1572     /* Get the Endpoint Descriptor Count */
1573 
1574     InfoTable = ACPI_ADD_PTR (ACPI_TABLE_NHLT, Table, 0);
1575     EndpointCount = InfoTable->EndpointCount;
1576 
1577     /* Subtables */
1578 
1579     Offset = sizeof (ACPI_TABLE_NHLT);
1580 
1581     while (Offset < TableLength)
1582     {
1583         /* A variable number of Endpoint Descriptors - process each */
1584 
1585         for (i = 0; i < EndpointCount; i++)
1586         {
1587             /* Do the Endpoint Descriptor table */
1588 
1589             Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1590 
1591             /* Check for endpoint descriptor length beyond end-of-table */
1592 
1593             if (Subtable->DescriptorLength > TableLength)
1594             {
1595                 Offset += 1;
1596                 AcpiOsPrintf ("\n    /* Endpoint Descriptor Length larger than"
1597                     " table size: %X, table %X, adjusting table offset (+1) */\n",
1598                     Subtable->DescriptorLength, TableLength);
1599 
1600                 Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1601             }
1602 
1603             AcpiOsPrintf ("\n    /* Endpoint Descriptor #%u */\n", i+1);
1604             Status = AcpiDmDumpTable (TableLength, Offset, Subtable,
1605                 Subtable->DescriptorLength, AcpiDmTableInfoNhlt0);
1606             if (ACPI_FAILURE (Status))
1607             {
1608                 return;
1609             }
1610 
1611             EndpointEndOffset = Subtable->DescriptorLength + Offset;
1612 
1613             /* Check for endpoint descriptor beyond end-of-table */
1614 
1615             if (Subtable->DescriptorLength > TableLength)
1616             {
1617                 AcpiOsPrintf ("\n    /* Endpoint Descriptor Length larger than table size: %X, table %X */\n",
1618                     Subtable->DescriptorLength, TableLength);
1619             }
1620 
1621             Offset += sizeof (ACPI_NHLT_ENDPOINT);
1622             Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1623 
1624             /* Do the Device Specific table */
1625 
1626             AcpiOsPrintf ("\n    /* Endpoint Device_Specific_Config table */\n");
1627             DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable);
1628             CapabilitiesSize = DevSpecific->CapabilitiesSize;
1629             Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1630                 sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B), AcpiDmTableInfoNhlt5b);
1631             if (ACPI_FAILURE (Status))
1632             {
1633                 return;
1634             }
1635 
1636             ArrayType = 0;
1637 
1638             /* Different subtables based upon capabilities_size */
1639 
1640             switch (CapabilitiesSize)
1641             {
1642             case 0:
1643                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B);
1644                 break;
1645 
1646             case 1:
1647                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1648                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_C), AcpiDmTableInfoNhlt5c);
1649                 if (ACPI_FAILURE (Status))
1650                 {
1651                     return;
1652                 }
1653                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_C);
1654                 break;
1655 
1656             case 2:
1657                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1658                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG), AcpiDmTableInfoNhlt5);
1659                 if (ACPI_FAILURE (Status))
1660                 {
1661                     return;
1662                 }
1663                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG);
1664                 break;
1665 
1666             case 3:
1667             default:
1668                 /* Extract the ConfigType and ArrayType */
1669 
1670                 ConfigType = DevSpecific->ConfigType;
1671                 ArrayType = DevSpecific->ArrayType;
1672 
1673                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1674                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A), AcpiDmTableInfoNhlt5a);
1675                 if (ACPI_FAILURE (Status))
1676                 {
1677                     return;
1678                 }
1679 
1680                 /* Capabilities Size == 3 */
1681                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A);
1682                 break;
1683 
1684             case 7:
1685                 ConfigType = DevSpecific->ConfigType;
1686                 Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1687                 DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable);
1688 
1689                 AcpiOsPrintf ("\n    /* Render Feedback Device-Specific table */\n");
1690                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1691                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG), AcpiDmTableInfoNhlt5);
1692                 if (ACPI_FAILURE (Status))
1693                 {
1694                     return;
1695                 }
1696 
1697                 /* Capabilities Size = 7 */
1698                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG);
1699 
1700                 if (ConfigType == ACPI_NHLT_CONFIG_TYPE_RENDER_FEEDBACK)
1701                 {
1702                     Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1703                     DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable);
1704 
1705                     Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1706                         sizeof (ACPI_NHLT_RENDER_FEEDBACK_DEVICE_SPECIFIC_CONFIG), AcpiDmTableInfoNhlt6b);
1707                     if (ACPI_FAILURE (Status))
1708                     {
1709                         return;
1710                     }
1711                     Offset += sizeof (ACPI_NHLT_RENDER_FEEDBACK_DEVICE_SPECIFIC_CONFIG);
1712                 }
1713                 break;
1714            }
1715 
1716             /* Check for a vendor-defined mic array */
1717 
1718             if (ConfigType == ACPI_NHLT_CONFIG_TYPE_MIC_ARRAY)
1719             {
1720                 if ((ArrayType & ACPI_NHLT_ARRAY_TYPE_MASK) == ACPI_NHLT_VENDOR_DEFINED)
1721                 {
1722                     /* Vendor-defined microphone array; get the microphone count first */
1723 
1724                     AcpiOsPrintf ("\n    /* Vendor-defined microphone count */\n");
1725                     MicCount = ACPI_ADD_PTR (ACPI_NHLT_VENDOR_MIC_COUNT, Table, Offset);
1726                     MicrophoneCount = MicCount->MicrophoneCount;
1727 
1728                     Status = AcpiDmDumpTable (TableLength, Offset, MicCount,
1729                         sizeof (ACPI_NHLT_VENDOR_MIC_COUNT), AcpiDmTableInfoNhlt6a);
1730                     Offset += sizeof (ACPI_NHLT_VENDOR_MIC_COUNT);
1731                     if (ACPI_FAILURE (Status))
1732                     {
1733                         return;
1734                     }
1735 
1736                     /* Get the vendor microphone config structure(s) */
1737 
1738                     for (j = 0; j < MicrophoneCount; j++)
1739                     {
1740                         AcpiOsPrintf ("\n    /* Vendor-defined microphone array #%u*/\n", j+1);
1741                         DevSpecific = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Table, Offset);
1742 
1743                         Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1744                             sizeof (ACPI_NHLT_VENDOR_MIC_CONFIG), AcpiDmTableInfoNhlt6);
1745                         if (ACPI_FAILURE (Status))
1746                         {
1747                             return;
1748                         }
1749 
1750                         Offset += sizeof (ACPI_NHLT_VENDOR_MIC_CONFIG);
1751                     }
1752 
1753                     /* Check for Microphone SNR and sensitivity extension */
1754 
1755                     if ((ArrayType & ACPI_NHLT_ARRAY_TYPE_EXT_MASK) == ACPI_NHLT_MIC_SNR_SENSITIVITY_EXT)
1756                     {
1757                         AcpiOsPrintf ("\n    /* Microphone SNR and sensitivity array */\n");
1758                         DevSpecific = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Table, Offset);
1759 
1760                         Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1761                             sizeof (ACPI_NHLT_MIC_SNR_SENSITIVITY_EXTENSION), AcpiDmTableInfoNhlt9);
1762                         if (ACPI_FAILURE (Status))
1763                         {
1764                             return;
1765                         }
1766 
1767                         Offset += sizeof (ACPI_NHLT_MIC_SNR_SENSITIVITY_EXTENSION);
1768                     }
1769                 }
1770             }
1771 
1772             /* Do the Formats_Config table - starts with the FormatsCount field */
1773 
1774             FormatsConfig = ACPI_ADD_PTR (ACPI_NHLT_FORMATS_CONFIG, Table, Offset);
1775             FormatsCount = FormatsConfig->FormatsCount;
1776 
1777             AcpiOsPrintf ("\n    /* Formats_Config table */\n");
1778 
1779             /* Dump the FormatsCount value */
1780 
1781             if (FormatsCount > 0)
1782             {
1783                 Status = AcpiDmDumpTable (TableLength, Offset, FormatsConfig,
1784                     sizeof (ACPI_NHLT_FORMATS_CONFIG), AcpiDmTableInfoNhlt4);
1785                 if (ACPI_FAILURE (Status))
1786                 {
1787                     return;
1788                 }
1789             }
1790             Offset += sizeof (ACPI_NHLT_FORMATS_CONFIG);
1791 
1792             /* A variable number of Format_Config Descriptors - process each */
1793 
1794             for (j = 0; j < FormatsCount; j++)
1795             {
1796                 FormatSubtable = ACPI_ADD_PTR (ACPI_NHLT_FORMAT_CONFIG, Table, Offset);
1797                 CapabilitiesSize = FormatSubtable->CapabilitySize;
1798 
1799                 /* Do the Wave_extensible struct */
1800 
1801                 AcpiOsPrintf ("\n    /* Wave_Format_Extensible table #%u */\n", j+1);
1802                 Status = AcpiDmDumpTable (TableLength, Offset, FormatSubtable,
1803                     sizeof (ACPI_NHLT_FORMAT_CONFIG), AcpiDmTableInfoNhlt3);
1804                 if (ACPI_FAILURE (Status))
1805                 {
1806                     return;
1807                 }
1808 
1809                 Offset += sizeof (ACPI_NHLT_FORMAT_CONFIG);
1810 
1811                 if (CapabilitiesSize > 0)
1812                 {
1813                     UINT8* CapabilitiesBuf = ACPI_ADD_PTR (UINT8, Table, Offset);
1814                     /* Do the Capabilities array (of bytes) */
1815 
1816                     AcpiOsPrintf ("\n    /* Specific_Config table #%u */\n", j+1);
1817 
1818                     Status = AcpiDmDumpTable (TableLength, Offset, CapabilitiesBuf,
1819                         CapabilitiesSize, AcpiDmTableInfoNhlt3a);
1820                     if (ACPI_FAILURE (Status))
1821                     {
1822                         return;
1823                     }
1824 
1825                     Offset += CapabilitiesSize; /* + sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B); */
1826                 }
1827 
1828             } /* for (j = 0; j < FormatsCount; j++) */
1829 
1830             /*
1831              * If we are not done with the current Endpoint yet, then there must be
1832              * some non documented structure(s) yet to be processed. First, get
1833              * the count of such structure(s).
1834              */
1835             if (Offset < EndpointEndOffset)
1836             {
1837                 AcpiOsPrintf ("\n    /* Structures that are not part of NHLT spec */\n");
1838                 Count = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_INFO_COUNT, Table, Offset);
1839                 Status = AcpiDmDumpTable (TableLength, Offset, Count,
1840                     sizeof (ACPI_NHLT_DEVICE_INFO_COUNT), AcpiDmTableInfoNhlt7);
1841                 if (ACPI_FAILURE (Status))
1842                 {
1843                     return;
1844                 }
1845                 Offset += sizeof (ACPI_NHLT_DEVICE_INFO_COUNT);
1846 
1847                 /* Variable number of device structures */
1848 
1849                 for (j = 0; j < Count->StructureCount; j++)
1850                 {
1851                     DeviceInfo = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_INFO, Table, Offset);
1852                     AcpiOsPrintf ("\n    /* Device Info structure #%u (not part of NHLT spec) */\n", j+1);
1853 
1854                     /*
1855                      * Dump the following Device Info fields:
1856                      *  1) Device ID
1857                      *  2) Device Instance ID
1858                      *  3) Device Port ID
1859                      */
1860                     Status = AcpiDmDumpTable (TableLength, Offset, DeviceInfo,
1861                         sizeof (ACPI_NHLT_DEVICE_INFO), AcpiDmTableInfoNhlt7a);
1862                     if (ACPI_FAILURE (Status))
1863                     {
1864                         return;
1865                     }
1866 
1867                     Offset += sizeof (ACPI_NHLT_DEVICE_INFO);
1868                 }
1869 
1870                 /*
1871                  * Check that the current offset is not beyond the end of
1872                  * this endpoint descriptor. If it is not, print those
1873                  * undocumented bytes.
1874                  */
1875                 if (Offset < EndpointEndOffset)
1876                 {
1877                     /* Unknown data at the end of the Endpoint */
1878                     UINT32 size = EndpointEndOffset - Offset;
1879                     UINT8* buffer = ACPI_ADD_PTR (UINT8, Table, Offset);
1880                     AcpiOsPrintf ("\n    /* Unknown data at the end of the Endpoint, size: %X */\n", size);
1881                     Status = AcpiDmDumpTable (TableLength, Offset, buffer,
1882                         size, AcpiDmTableInfoNhlt7b);
1883                     Offset = EndpointEndOffset;
1884                 }
1885 
1886                 /* Should be at the end of the Endpoint structure. */
1887             }
1888 
1889         } /* for (i = 0; i < EndpointCount; i++) */
1890 
1891 
1892         /*
1893          * Done with all of the Endpoint Descriptors, Emit the table terminator
1894          * (if such a legacy structure is present -- not in NHLT specification)
1895          */
1896         if (Offset < TableLength)
1897         {
1898             Capabilities = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B, Table, Offset);
1899             AcpiOsPrintf ("\n/* Terminating specific config (not part of NHLT spec) */\n");
1900 
1901             Status = AcpiDmDumpTable (TableLength, Offset, Capabilities,
1902                 sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B), AcpiDmTableInfoNhlt5b);
1903             if (ACPI_FAILURE (Status))
1904             {
1905                 return;
1906             }
1907             Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B);
1908 
1909             if (Capabilities->CapabilitiesSize > 0)
1910             {
1911                 UINT32 remainingBytes = TableLength - Offset;
1912                 UINT8* buffer = ACPI_ADD_PTR (UINT8, Table, Offset);
1913 
1914                 if (remainingBytes != Capabilities->CapabilitiesSize)
1915                     AcpiOsPrintf ("\n/* Incorrect config size, should be %X, is %X */\n",
1916                         Capabilities->CapabilitiesSize, remainingBytes);
1917                 Status = AcpiDmDumpTable (TableLength, Offset, buffer,
1918                         remainingBytes, AcpiDmTableInfoNhlt3a);
1919             }
1920         }
1921 
1922         return;
1923     }
1924 }
1925 
1926 
1927 /*******************************************************************************
1928  *
1929  * FUNCTION:    AcpiDmDumpPcct
1930  *
1931  * PARAMETERS:  Table               - A PCCT table
1932  *
1933  * RETURN:      None
1934  *
1935  * DESCRIPTION: Format the contents of a PCCT. This table type consists
1936  *              of an open-ended number of subtables.
1937  *
1938  ******************************************************************************/
1939 
1940 void
1941 AcpiDmDumpPcct (
1942     ACPI_TABLE_HEADER       *Table)
1943 {
1944     ACPI_STATUS             Status;
1945     ACPI_PCCT_SUBSPACE      *Subtable;
1946     ACPI_DMTABLE_INFO       *InfoTable;
1947     UINT32                  Length = Table->Length;
1948     UINT32                  Offset = sizeof (ACPI_TABLE_PCCT);
1949 
1950 
1951     /* Main table */
1952 
1953     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct);
1954     if (ACPI_FAILURE (Status))
1955     {
1956         return;
1957     }
1958 
1959     /* Subtables */
1960 
1961     Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
1962     while (Offset < Table->Length)
1963     {
1964         /* Common subtable header */
1965 
1966         AcpiOsPrintf ("\n");
1967         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1968             Subtable->Header.Length, AcpiDmTableInfoPcctHdr);
1969         if (ACPI_FAILURE (Status))
1970         {
1971             return;
1972         }
1973 
1974         switch (Subtable->Header.Type)
1975         {
1976         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1977 
1978             InfoTable = AcpiDmTableInfoPcct0;
1979             break;
1980 
1981         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1982 
1983             InfoTable = AcpiDmTableInfoPcct1;
1984             break;
1985 
1986         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
1987 
1988             InfoTable = AcpiDmTableInfoPcct2;
1989             break;
1990 
1991         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
1992 
1993             InfoTable = AcpiDmTableInfoPcct3;
1994             break;
1995 
1996         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
1997 
1998             InfoTable = AcpiDmTableInfoPcct4;
1999             break;
2000 
2001         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
2002 
2003             InfoTable = AcpiDmTableInfoPcct5;
2004             break;
2005 
2006         default:
2007 
2008             AcpiOsPrintf (
2009                 "\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n",
2010                 Subtable->Header.Type);
2011             return;
2012         }
2013 
2014         AcpiOsPrintf ("\n");
2015         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2016             Subtable->Header.Length, InfoTable);
2017         if (ACPI_FAILURE (Status))
2018         {
2019             return;
2020         }
2021 
2022         /* Point to next subtable */
2023 
2024         Offset += Subtable->Header.Length;
2025         Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Subtable,
2026             Subtable->Header.Length);
2027     }
2028 }
2029 
2030 
2031 /*******************************************************************************
2032  *
2033  * FUNCTION:    AcpiDmDumpPdtt
2034  *
2035  * PARAMETERS:  Table               - A PDTT table
2036  *
2037  * RETURN:      None
2038  *
2039  * DESCRIPTION: Format the contents of a Pdtt. This is a variable-length
2040  *              table that contains an open-ended number of IDs
2041  *              at the end of the table.
2042  *
2043  ******************************************************************************/
2044 
2045 void
2046 AcpiDmDumpPdtt (
2047     ACPI_TABLE_HEADER       *Table)
2048 {
2049     ACPI_STATUS             Status;
2050     ACPI_PDTT_CHANNEL       *Subtable;
2051     UINT32                  Length = Table->Length;
2052     UINT32                  Offset = sizeof (ACPI_TABLE_PDTT);
2053 
2054 
2055     /* Main table */
2056 
2057     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPdtt);
2058     if (ACPI_FAILURE (Status))
2059     {
2060         return;
2061     }
2062 
2063     /* Subtables. Currently there is only one type, but can be multiples */
2064 
2065     Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Table, Offset);
2066     while (Offset < Table->Length)
2067     {
2068         AcpiOsPrintf ("\n");
2069         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2070             sizeof (ACPI_PDTT_CHANNEL), AcpiDmTableInfoPdtt0);
2071         if (ACPI_FAILURE (Status))
2072         {
2073             return;
2074         }
2075 
2076         /* Point to next subtable */
2077 
2078         Offset += sizeof (ACPI_PDTT_CHANNEL);
2079         Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Subtable,
2080             sizeof (ACPI_PDTT_CHANNEL));
2081     }
2082 }
2083 
2084 
2085 /*******************************************************************************
2086  *
2087  * FUNCTION:    AcpiDmDumpPhat
2088  *
2089  * PARAMETERS:  Table               - A PHAT table
2090  *
2091  * RETURN:      None
2092  *
2093  * DESCRIPTION: Format the contents of a PHAT.
2094  *
2095  ******************************************************************************/
2096 
2097 void
2098 AcpiDmDumpPhat (
2099     ACPI_TABLE_HEADER       *Table)
2100 {
2101     ACPI_STATUS             Status;
2102     ACPI_DMTABLE_INFO       *InfoTable;
2103     ACPI_PHAT_HEADER        *Subtable;
2104     ACPI_PHAT_VERSION_DATA  *VersionData;
2105     UINT32                  RecordCount;
2106     UINT32                  Length = Table->Length;
2107     UINT32                  Offset = sizeof (ACPI_TABLE_PHAT);
2108     UINT32                  OriginalOffset;
2109     UINT32                  SubtableLength;
2110     UINT32                  PathLength;
2111     UINT32                  VendorLength;
2112     UINT16                  RecordType;
2113     const wchar_t           *WideString;
2114 
2115 
2116     Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, sizeof (ACPI_TABLE_PHAT));
2117 
2118     while (Offset < Table->Length)
2119     {
2120         /* Common subtable header */
2121 
2122         AcpiOsPrintf ("\n");
2123         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2124             sizeof (ACPI_PHAT_HEADER), AcpiDmTableInfoPhatHdr);
2125         if (ACPI_FAILURE (Status))
2126         {
2127             return;
2128         }
2129 
2130         DbgPrint (ASL_DEBUG_OUTPUT, "\n/* %u, Subtable->Type %X */\n",
2131             __LINE__, Subtable->Type);
2132 
2133         switch (Subtable->Type)
2134         {
2135         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
2136 
2137             InfoTable = AcpiDmTableInfoPhat0;
2138             SubtableLength = Offset += sizeof (ACPI_PHAT_VERSION_DATA);
2139             break;
2140 
2141         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
2142 
2143             InfoTable = AcpiDmTableInfoPhat1;
2144             SubtableLength = Offset += sizeof (ACPI_PHAT_TYPE_FW_HEALTH_DATA);
2145             break;
2146 
2147         default:
2148 
2149             DbgPrint (ASL_DEBUG_OUTPUT, "\n**** Unknown PHAT subtable type 0x%X\n\n",
2150                 Subtable->Type);
2151 
2152             return;
2153         }
2154 
2155         Status = AcpiDmDumpTable (Length, SubtableLength, Subtable,
2156             SubtableLength, InfoTable);
2157         if (ACPI_FAILURE (Status))
2158         {
2159             return;
2160         }
2161 
2162         OriginalOffset = Offset;
2163         switch (Subtable->Type)
2164         {
2165         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
2166 
2167             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, Subtable);
2168             RecordCount = VersionData->ElementCount;
2169             RecordType = *ACPI_CAST_PTR (UINT8, Subtable);
2170 
2171             /*
2172              * Skip past a zero-valued block (not part of the ACPI PHAT specification).
2173              * First, check for a zero length record and a zero element count
2174              */
2175             if (!VersionData->Header.Length && !VersionData->ElementCount)
2176             {
2177                 while (RecordType == 0)
2178                 {
2179                     Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, Offset);
2180                     RecordType = *ACPI_CAST_PTR (UINT8, Subtable);
2181                     RecordCount = VersionData->ElementCount;
2182                     Offset += 1;
2183                 }
2184 
2185                 Offset -= 1;
2186                 AcpiOsPrintf ("\n/* Warning: Block of zeros found above starting at Offset %X Length %X */\n"
2187                     "/* (not compliant to PHAT specification -- ignoring block) */\n",
2188                     OriginalOffset - 12, Offset - OriginalOffset + 12);
2189             }
2190 
2191             DbgPrint (ASL_DEBUG_OUTPUT, "/* %u, RecordCount: %X, Offset %X, SubtableLength %X */\n",
2192                 __LINE__, RecordCount, Offset, SubtableLength);
2193 
2194             /* Emit each of the version elements */
2195 
2196             while (RecordCount && VersionData->Header.Length)
2197             {
2198                 AcpiOsPrintf ("\n/* Version Element #%Xh Offset %Xh */\n\n",
2199                     VersionData->ElementCount - RecordCount + 1, Offset);
2200 
2201                 Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, Offset);
2202                 Status = AcpiDmDumpTable (Length, Offset, Subtable,
2203                     sizeof (ACPI_PHAT_VERSION_ELEMENT), AcpiDmTableInfoPhat0a);
2204                 if (ACPI_FAILURE (Status))
2205                 {
2206                     return;
2207                 }
2208 
2209                 Offset += sizeof (ACPI_PHAT_VERSION_ELEMENT);
2210                 RecordCount--;
2211             }
2212 
2213             break;
2214 
2215         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
2216 
2217             /*
2218              * Get the length of the Device Path (UEFI wide string).
2219              * Include the wide null terminator (+2),
2220              */
2221             WideString = ACPI_ADD_PTR (wchar_t, Subtable,
2222                 sizeof (ACPI_PHAT_HEALTH_DATA));
2223 
2224             PathLength = (wcslen (WideString) * 2) + 2;
2225             DbgPrint (ASL_DEBUG_OUTPUT, "/* %u, PathLength %X, Offset %X, Table->Length %X */\n",
2226                 __LINE__, PathLength, Offset, Length);
2227 
2228             Status = AcpiDmDumpTable (Length, Offset,
2229                 ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA)),
2230                 PathLength, AcpiDmTableInfoPhat1a);
2231             Offset += PathLength;
2232             if (ACPI_FAILURE (Status))
2233             {
2234                 return;
2235             }
2236 
2237             /* Get Device-Specific Data - length of which is the remaining subtable length. */
2238 
2239             VendorLength =
2240                 Subtable->Length - sizeof (ACPI_PHAT_HEALTH_DATA) - PathLength;
2241             DbgPrint (ASL_DEBUG_OUTPUT, "%u, Subtable->Length %X, VendorLength %X, Offset %X PathLength: %X\n",
2242                 __LINE__, Subtable->Length, VendorLength, Offset, PathLength);
2243 
2244             if (VendorLength)
2245             {
2246                 /* Point past the Device Path, Compile the Device-Specific Data */
2247 
2248                 Status = AcpiDmDumpTable (Length, Offset,
2249                     ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA) + PathLength),
2250                     VendorLength, AcpiDmTableInfoPhat1b);
2251                 if (ACPI_FAILURE (Status))
2252                 {
2253                     return;
2254                 }
2255 
2256                 Offset += VendorLength;
2257             }
2258 
2259             if (ACPI_FAILURE (Status))
2260             {
2261                 return;
2262             }
2263             break;
2264 
2265         default:
2266 
2267             AcpiOsPrintf ("\n**** Unknown PHAT subtable type 0x%X\n\n",
2268                 Subtable->Type);
2269             return;
2270         }
2271 
2272         /* Next subtable */
2273 
2274         DbgPrint (ASL_DEBUG_OUTPUT, "/* %u, Bottom of main loop: Offset %X, "
2275             "Subtable->Length %X, Table->Length %X */\n",
2276             __LINE__, Offset, Subtable->Length, Table->Length);
2277 
2278         Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table,
2279             Offset);
2280     }
2281 }
2282 
2283 
2284 /*******************************************************************************
2285  *
2286  * FUNCTION:    AcpiDmDumpPmtt
2287  *
2288  * PARAMETERS:  Table               - A PMTT table
2289  *
2290  * RETURN:      None
2291  *
2292  * DESCRIPTION: Format the contents of a PMTT. This table type consists
2293  *              of an open-ended number of subtables.
2294  *
2295  ******************************************************************************/
2296 
2297 void
2298 AcpiDmDumpPmtt (
2299     ACPI_TABLE_HEADER       *Table)
2300 {
2301     ACPI_STATUS             Status;
2302     ACPI_PMTT_HEADER        *Subtable;
2303     UINT32                  Length = Table->Length;
2304     UINT32                  Offset = sizeof (ACPI_TABLE_PMTT);
2305 
2306 
2307     /* Main table */
2308 
2309     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt);
2310     if (ACPI_FAILURE (Status))
2311     {
2312         return;
2313     }
2314 
2315     /* Subtables */
2316 
2317     Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
2318     while (Offset < Table->Length)
2319     {
2320         /* Each of the types below contain the common subtable header */
2321 
2322         AcpiOsPrintf ("\n");
2323         switch (Subtable->Type)
2324         {
2325         case ACPI_PMTT_TYPE_SOCKET:
2326 
2327             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2328                 Subtable->Length, AcpiDmTableInfoPmtt0);
2329             if (ACPI_FAILURE (Status))
2330             {
2331                 return;
2332             }
2333             break;
2334 
2335         case ACPI_PMTT_TYPE_CONTROLLER:
2336             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2337                 Subtable->Length, AcpiDmTableInfoPmtt1);
2338             if (ACPI_FAILURE (Status))
2339             {
2340                 return;
2341             }
2342             break;
2343 
2344        case ACPI_PMTT_TYPE_DIMM:
2345             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2346                 Subtable->Length, AcpiDmTableInfoPmtt2);
2347             if (ACPI_FAILURE (Status))
2348             {
2349                 return;
2350             }
2351             break;
2352 
2353         case ACPI_PMTT_TYPE_VENDOR:
2354             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2355                 Subtable->Length, AcpiDmTableInfoPmttVendor);
2356             if (ACPI_FAILURE (Status))
2357             {
2358                 return;
2359             }
2360             break;
2361 
2362         default:
2363             AcpiOsPrintf (
2364                 "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
2365                 Subtable->Type);
2366             return;
2367         }
2368 
2369         /* Point to next subtable */
2370 
2371         Offset += Subtable->Length;
2372         Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
2373             Subtable, Subtable->Length);
2374     }
2375 }
2376 
2377 
2378 /*******************************************************************************
2379  *
2380  * FUNCTION:    AcpiDmDumpPptt
2381  *
2382  * PARAMETERS:  Table               - A PMTT table
2383  *
2384  * RETURN:      None
2385  *
2386  * DESCRIPTION: Format the contents of a PPTT. This table type consists
2387  *              of an open-ended number of subtables.
2388  *
2389  ******************************************************************************/
2390 
2391 void
2392 AcpiDmDumpPptt (
2393     ACPI_TABLE_HEADER       *Table)
2394 {
2395     ACPI_STATUS             Status;
2396     ACPI_SUBTABLE_HEADER    *Subtable;
2397     ACPI_PPTT_PROCESSOR     *PpttProcessor;
2398     UINT8                   Length;
2399     UINT8                   SubtableOffset;
2400     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
2401     ACPI_DMTABLE_INFO       *InfoTable;
2402     UINT32                  i;
2403 
2404 
2405     /* There is no main table (other than the standard ACPI header) */
2406 
2407     /* Subtables */
2408 
2409     Offset = sizeof (ACPI_TABLE_HEADER);
2410     while (Offset < Table->Length)
2411     {
2412         AcpiOsPrintf ("\n");
2413 
2414         /* Common subtable header */
2415 
2416         Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
2417         if (Subtable->Length < sizeof (ACPI_SUBTABLE_HEADER))
2418         {
2419             AcpiOsPrintf ("Invalid subtable length\n");
2420             return;
2421         }
2422         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2423             Subtable->Length, AcpiDmTableInfoPpttHdr);
2424         if (ACPI_FAILURE (Status))
2425         {
2426             return;
2427         }
2428 
2429         switch (Subtable->Type)
2430         {
2431         case ACPI_PPTT_TYPE_PROCESSOR:
2432 
2433             InfoTable = AcpiDmTableInfoPptt0;
2434             Length = sizeof (ACPI_PPTT_PROCESSOR);
2435             break;
2436 
2437         case ACPI_PPTT_TYPE_CACHE:
2438 
2439             InfoTable = AcpiDmTableInfoPptt1;
2440             Length = sizeof (ACPI_PPTT_CACHE);
2441             break;
2442 
2443         case ACPI_PPTT_TYPE_ID:
2444 
2445             InfoTable = AcpiDmTableInfoPptt2;
2446             Length = sizeof (ACPI_PPTT_ID);
2447             break;
2448 
2449         default:
2450 
2451             AcpiOsPrintf ("\n**** Unknown PPTT subtable type 0x%X\n\n",
2452                 Subtable->Type);
2453 
2454             /* Attempt to continue */
2455 
2456             goto NextSubtable;
2457         }
2458 
2459         if (Subtable->Length < Length)
2460         {
2461             AcpiOsPrintf ("Invalid subtable length\n");
2462             return;
2463         }
2464         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2465             Subtable->Length, InfoTable);
2466         if (ACPI_FAILURE (Status))
2467         {
2468             return;
2469         }
2470         SubtableOffset = Length;
2471 
2472         switch (Subtable->Type)
2473         {
2474         case ACPI_PPTT_TYPE_PROCESSOR:
2475 
2476             PpttProcessor = ACPI_CAST_PTR (ACPI_PPTT_PROCESSOR, Subtable);
2477 
2478             /* Dump SMBIOS handles */
2479 
2480             if ((UINT8)(Subtable->Length - SubtableOffset) <
2481                 (UINT8)(PpttProcessor->NumberOfPrivResources * 4))
2482             {
2483                 AcpiOsPrintf ("Invalid private resource number\n");
2484                 return;
2485             }
2486             for (i = 0; i < PpttProcessor->NumberOfPrivResources; i++)
2487             {
2488                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2489                     ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
2490                     4, AcpiDmTableInfoPptt0a);
2491                 if (ACPI_FAILURE (Status))
2492                 {
2493                     return;
2494                 }
2495 
2496                 SubtableOffset += 4;
2497             }
2498             break;
2499 
2500         case ACPI_PPTT_TYPE_CACHE:
2501 
2502             if (Table->Revision < 3)
2503             {
2504                 break;
2505             }
2506             Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2507                 ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
2508                 sizeof (ACPI_PPTT_CACHE_V1), AcpiDmTableInfoPptt1a);
2509             if (ACPI_FAILURE (Status))
2510             {
2511                 return;
2512             }
2513             break;
2514 
2515         default:
2516 
2517             break;
2518         }
2519 
2520 NextSubtable:
2521         /* Point to next subtable */
2522 
2523         Offset += Subtable->Length;
2524     }
2525 }
2526 
2527 
2528 /*******************************************************************************
2529  *
2530  * FUNCTION:    AcpiDmDumpPrmt
2531  *
2532  * PARAMETERS:  Table               - A PRMT table
2533  *
2534  * RETURN:      None
2535  *
2536  * DESCRIPTION: Format the contents of a PRMT. This table type consists
2537  *              of an open-ended number of subtables.
2538  *
2539  ******************************************************************************/
2540 
2541 void
2542 AcpiDmDumpPrmt (
2543     ACPI_TABLE_HEADER       *Table)
2544 {
2545     UINT32                  CurrentOffset = sizeof (ACPI_TABLE_HEADER);
2546     ACPI_TABLE_PRMT_HEADER  *PrmtHeader;
2547     ACPI_PRMT_MODULE_INFO   *PrmtModuleInfo;
2548     ACPI_PRMT_HANDLER_INFO  *PrmtHandlerInfo;
2549     ACPI_STATUS             Status;
2550     UINT32                  i, j;
2551 
2552 
2553     /* Main table header */
2554 
2555     PrmtHeader = ACPI_ADD_PTR (ACPI_TABLE_PRMT_HEADER, Table, CurrentOffset);
2556     Status = AcpiDmDumpTable (Table->Length, CurrentOffset, PrmtHeader,
2557         sizeof (ACPI_TABLE_PRMT_HEADER), AcpiDmTableInfoPrmtHdr);
2558     if (ACPI_FAILURE (Status))
2559     {
2560         AcpiOsPrintf ("Invalid PRMT header\n");
2561         return;
2562     }
2563 
2564     CurrentOffset += sizeof (ACPI_TABLE_PRMT_HEADER);
2565 
2566     /* PRM Module Information Structure array */
2567 
2568     for (i = 0; i < PrmtHeader->ModuleInfoCount; ++i)
2569     {
2570         PrmtModuleInfo = ACPI_ADD_PTR (ACPI_PRMT_MODULE_INFO, Table, CurrentOffset);
2571         Status = AcpiDmDumpTable (Table->Length, CurrentOffset, PrmtModuleInfo,
2572             sizeof (ACPI_PRMT_MODULE_INFO), AcpiDmTableInfoPrmtModule);
2573 
2574         CurrentOffset += sizeof (ACPI_PRMT_MODULE_INFO);
2575 
2576         /* PRM handler information structure array */
2577 
2578         for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; ++j)
2579         {
2580             PrmtHandlerInfo = ACPI_ADD_PTR (ACPI_PRMT_HANDLER_INFO, Table, CurrentOffset);
2581             Status = AcpiDmDumpTable (Table->Length, CurrentOffset, PrmtHandlerInfo,
2582                 sizeof (ACPI_PRMT_HANDLER_INFO), AcpiDmTableInfoPrmtHandler);
2583 
2584             CurrentOffset += sizeof (ACPI_PRMT_HANDLER_INFO);
2585         }
2586     }
2587 }
2588 
2589 
2590 /*******************************************************************************
2591  *
2592  * FUNCTION:    AcpiDmDumpRgrt
2593  *
2594  * PARAMETERS:  Table               - A RGRT table
2595  *
2596  * RETURN:      None
2597  *
2598  * DESCRIPTION: Format the contents of a RGRT
2599  *
2600  ******************************************************************************/
2601 
2602 void
2603 AcpiDmDumpRgrt (
2604     ACPI_TABLE_HEADER       *Table)
2605 {
2606     ACPI_STATUS             Status;
2607     ACPI_TABLE_RGRT         *Subtable = ACPI_CAST_PTR (ACPI_TABLE_RGRT, Table);
2608     UINT32                  Offset = sizeof (ACPI_TABLE_RGRT);
2609 
2610 
2611     /* Main table */
2612 
2613     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoRgrt);
2614     if (ACPI_FAILURE (Status))
2615     {
2616         return;
2617     }
2618 
2619     /* Dump the binary image as a subtable */
2620 
2621     Status = AcpiDmDumpTable (Table->Length, Offset, &Subtable->Image,
2622         Table->Length - Offset, AcpiDmTableInfoRgrt0);
2623     if (ACPI_FAILURE (Status))
2624     {
2625         return;
2626     }
2627 }
2628 
2629 
2630 /*******************************************************************************
2631  *
2632  * FUNCTION:    AcpiDmDumpS3pt
2633  *
2634  * PARAMETERS:  Table               - A S3PT table
2635  *
2636  * RETURN:      Length of the table
2637  *
2638  * DESCRIPTION: Format the contents of a S3PT
2639  *
2640  ******************************************************************************/
2641 
2642 UINT32
2643 AcpiDmDumpS3pt (
2644     ACPI_TABLE_HEADER       *Tables)
2645 {
2646     ACPI_STATUS             Status;
2647     UINT32                  Offset = sizeof (ACPI_TABLE_S3PT);
2648     ACPI_FPDT_HEADER        *Subtable;
2649     ACPI_DMTABLE_INFO       *InfoTable;
2650     ACPI_TABLE_S3PT         *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
2651 
2652 
2653     /* Main table */
2654 
2655     Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt);
2656     if (ACPI_FAILURE (Status))
2657     {
2658         return 0;
2659     }
2660 
2661     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, S3ptTable, Offset);
2662     while (Offset < S3ptTable->Length)
2663     {
2664         /* Common subtable header */
2665 
2666         AcpiOsPrintf ("\n");
2667         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
2668             Subtable->Length, AcpiDmTableInfoS3ptHdr);
2669         if (ACPI_FAILURE (Status))
2670         {
2671             return 0;
2672         }
2673 
2674         switch (Subtable->Type)
2675         {
2676         case ACPI_S3PT_TYPE_RESUME:
2677 
2678             InfoTable = AcpiDmTableInfoS3pt0;
2679             break;
2680 
2681         case ACPI_S3PT_TYPE_SUSPEND:
2682 
2683             InfoTable = AcpiDmTableInfoS3pt1;
2684             break;
2685 
2686         default:
2687 
2688             AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n",
2689                 Subtable->Type);
2690 
2691             /* Attempt to continue */
2692 
2693             if (!Subtable->Length)
2694             {
2695                 AcpiOsPrintf ("Invalid zero length subtable\n");
2696                 return 0;
2697             }
2698             goto NextSubtable;
2699         }
2700 
2701         AcpiOsPrintf ("\n");
2702         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
2703             Subtable->Length, InfoTable);
2704         if (ACPI_FAILURE (Status))
2705         {
2706             return 0;
2707         }
2708 
2709 NextSubtable:
2710         /* Point to next subtable */
2711 
2712         Offset += Subtable->Length;
2713         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable, Subtable->Length);
2714     }
2715 
2716     return (S3ptTable->Length);
2717 }
2718 
2719 
2720 /*******************************************************************************
2721  *
2722  * FUNCTION:    AcpiDmDumpSdev
2723  *
2724  * PARAMETERS:  Table               - A SDEV table
2725  *
2726  * RETURN:      None
2727  *
2728  * DESCRIPTION: Format the contents of a SDEV. This is a variable-length
2729  *              table that contains variable strings and vendor data.
2730  *
2731  ******************************************************************************/
2732 
2733 void
2734 AcpiDmDumpSdev (
2735     ACPI_TABLE_HEADER       *Table)
2736 {
2737     ACPI_STATUS                 Status;
2738     ACPI_SDEV_HEADER            *Subtable;
2739     ACPI_SDEV_PCIE              *Pcie;
2740     ACPI_SDEV_NAMESPACE         *Namesp;
2741     ACPI_DMTABLE_INFO           *InfoTable;
2742     ACPI_DMTABLE_INFO           *SecureComponentInfoTable;
2743     UINT32                      Length = Table->Length;
2744     UINT32                      Offset = sizeof (ACPI_TABLE_SDEV);
2745     UINT16                      PathOffset;
2746     UINT16                      PathLength;
2747     UINT16                      VendorDataOffset;
2748     UINT16                      VendorDataLength;
2749     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
2750     UINT32                      CurrentOffset = 0;
2751 
2752 
2753     /* Main table */
2754 
2755     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoSdev);
2756     if (ACPI_FAILURE (Status))
2757     {
2758         return;
2759     }
2760 
2761     /* Subtables */
2762 
2763     Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Table, Offset);
2764     while (Offset < Table->Length)
2765     {
2766         /* Common subtable header */
2767 
2768         AcpiOsPrintf ("\n");
2769         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2770             Subtable->Length, AcpiDmTableInfoSdevHdr);
2771         if (ACPI_FAILURE (Status))
2772         {
2773             return;
2774         }
2775 
2776         switch (Subtable->Type)
2777         {
2778         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2779 
2780             InfoTable = AcpiDmTableInfoSdev0;
2781             break;
2782 
2783         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2784 
2785             InfoTable = AcpiDmTableInfoSdev1;
2786             break;
2787 
2788         default:
2789             goto NextSubtable;
2790         }
2791 
2792         AcpiOsPrintf ("\n");
2793         Status = AcpiDmDumpTable (Table->Length, 0, Subtable,
2794             Subtable->Length, InfoTable);
2795         if (ACPI_FAILURE (Status))
2796         {
2797             return;
2798         }
2799 
2800         switch (Subtable->Type)
2801         {
2802         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2803 
2804             CurrentOffset = sizeof (ACPI_SDEV_NAMESPACE);
2805             if (Subtable->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
2806             {
2807                 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
2808                     ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_SDEV_NAMESPACE)));
2809 
2810                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2811                     ACPI_ADD_PTR(UINT8, Subtable, sizeof (ACPI_SDEV_NAMESPACE)),
2812                     sizeof (ACPI_SDEV_SECURE_COMPONENT), AcpiDmTableInfoSdev0b);
2813                 if (ACPI_FAILURE (Status))
2814                 {
2815                     return;
2816                 }
2817                 CurrentOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2818 
2819                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2820                     ACPI_ADD_PTR(UINT8, Subtable, SecureComponent->SecureComponentOffset),
2821                     sizeof (ACPI_SDEV_HEADER), AcpiDmTableInfoSdevSecCompHdr);
2822                 if (ACPI_FAILURE (Status))
2823                 {
2824                     return;
2825                 }
2826                 CurrentOffset += sizeof (ACPI_SDEV_HEADER);
2827 
2828                 switch (Subtable->Type)
2829                 {
2830                 case ACPI_SDEV_TYPE_ID_COMPONENT:
2831 
2832                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
2833                     break;
2834 
2835                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
2836 
2837                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
2838                     break;
2839 
2840                 default:
2841                     goto NextSubtable;
2842                 }
2843 
2844                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2845                     ACPI_ADD_PTR(UINT8, Subtable, SecureComponent->SecureComponentOffset),
2846                     SecureComponent->SecureComponentLength, SecureComponentInfoTable);
2847                 CurrentOffset += SecureComponent->SecureComponentLength;
2848             }
2849 
2850             /* Dump the PCIe device ID(s) */
2851 
2852             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable);
2853             PathOffset = Namesp->DeviceIdOffset;
2854             PathLength = Namesp->DeviceIdLength;
2855 
2856             if (PathLength)
2857             {
2858                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2859                     ACPI_ADD_PTR (UINT8, Namesp, PathOffset),
2860                     PathLength, AcpiDmTableInfoSdev0a);
2861                 if (ACPI_FAILURE (Status))
2862                 {
2863                     return;
2864                 }
2865                 CurrentOffset += PathLength;
2866             }
2867 
2868             /* Dump the vendor-specific data */
2869 
2870             VendorDataLength =
2871                 Namesp->VendorDataLength;
2872             VendorDataOffset =
2873                 Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2874 
2875             if (VendorDataLength)
2876             {
2877                 Status = AcpiDmDumpTable (Table->Length, 0,
2878                     ACPI_ADD_PTR (UINT8, Namesp, VendorDataOffset),
2879                     VendorDataLength, AcpiDmTableInfoSdev1b);
2880                 if (ACPI_FAILURE (Status))
2881                 {
2882                     return;
2883                 }
2884             }
2885             break;
2886 
2887         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2888 
2889             /* PCI path substructures */
2890 
2891             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable);
2892             PathOffset = Pcie->PathOffset;
2893             PathLength = Pcie->PathLength;
2894 
2895             while (PathLength)
2896             {
2897                 Status = AcpiDmDumpTable (Table->Length,
2898                     PathOffset + Offset,
2899                     ACPI_ADD_PTR (UINT8, Pcie, PathOffset),
2900                     sizeof (ACPI_SDEV_PCIE_PATH), AcpiDmTableInfoSdev1a);
2901                 if (ACPI_FAILURE (Status))
2902                 {
2903                     return;
2904                 }
2905 
2906                 PathOffset += sizeof (ACPI_SDEV_PCIE_PATH);
2907                 PathLength -= sizeof (ACPI_SDEV_PCIE_PATH);
2908             }
2909 
2910             /* VendorData */
2911 
2912             VendorDataLength = Pcie->VendorDataLength;
2913             VendorDataOffset = Pcie->PathOffset + Pcie->PathLength;
2914 
2915             if (VendorDataLength)
2916             {
2917                 Status = AcpiDmDumpTable (Table->Length, 0,
2918                     ACPI_ADD_PTR (UINT8, Pcie, VendorDataOffset),
2919                     VendorDataLength, AcpiDmTableInfoSdev1b);
2920                 if (ACPI_FAILURE (Status))
2921                 {
2922                     return;
2923                 }
2924             }
2925             break;
2926 
2927         default:
2928             goto NextSubtable;
2929         }
2930 
2931 NextSubtable:
2932         /* Point to next subtable */
2933 
2934         Offset += Subtable->Length;
2935         Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Subtable,
2936             Subtable->Length);
2937     }
2938 }
2939