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