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                  k;
1498     UINT32                  EndpointEndOffset;
1499     UINT8                   ConfigType = 0;
1500     UINT8                   ArrayType;
1501     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A  *DevSpecific;
1502     ACPI_NHLT_FORMATS_CONFIG            *FormatsConfig;
1503     ACPI_NHLT_LINUX_SPECIFIC_COUNT      *Count;
1504     ACPI_NHLT_LINUX_SPECIFIC_DATA       *LinuxData;
1505 
1506 
1507     /* Main table */
1508 
1509     AcpiOsPrintf ("/* Main table */\n");
1510 
1511     Status = AcpiDmDumpTable (TableLength, 0, Table, 0, AcpiDmTableInfoNhlt);
1512     if (ACPI_FAILURE (Status))
1513     {
1514         return;
1515     }
1516 
1517     /* Get the Endpoint Descriptor Count */
1518 
1519     InfoTable = ACPI_ADD_PTR (ACPI_TABLE_NHLT, Table, 0);
1520     EndpointCount = InfoTable->EndpointCount;
1521 
1522     /* Subtables */
1523 
1524     Offset = sizeof (ACPI_TABLE_NHLT);
1525 
1526     while (Offset < TableLength)
1527     {
1528         /* A variable number of Endpoint Descriptors - process each */
1529 
1530         for (i = 0; i < EndpointCount; i++)
1531         {
1532             /* Do the Endpoint Descriptor table */
1533 
1534             Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1535             if (Subtable->DescriptorLength > TableLength)
1536             {
1537                 Offset += 1;
1538                 AcpiOsPrintf ("\n/* Endpoint Descriptor Length larger than"
1539                     " table size: %X, table %X, adjusting table offset (+1) */\n",
1540                     Subtable->DescriptorLength, TableLength);
1541 
1542                 Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1543             }
1544 
1545             AcpiOsPrintf ("\n/* Endpoint Descriptor #%u */\n", i+1);
1546             Status = AcpiDmDumpTable (TableLength, Offset, Subtable,
1547                 Subtable->DescriptorLength, AcpiDmTableInfoNhlt0);
1548             if (ACPI_FAILURE (Status))
1549             {
1550                 return;
1551             }
1552             EndpointEndOffset = Subtable->DescriptorLength + Offset;
1553 
1554             /* Check for endpoint descriptor beyond end-of-table */
1555 
1556             if (Subtable->DescriptorLength > TableLength)
1557             {
1558                 AcpiOsPrintf ("\n/* Endpoint Descriptor Length larger than table size: %X, table %X */\n",
1559                     Subtable->DescriptorLength, TableLength);
1560             }
1561             Offset += sizeof (ACPI_NHLT_ENDPOINT);
1562             Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1563 
1564             /* Do the Device Specific table */
1565 
1566             AcpiOsPrintf ("\n/* Endpoint Device_Specific_Config table */\n");
1567             DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable);
1568             CapabilitiesSize = DevSpecific->CapabilitiesSize;
1569 
1570             /* Different subtables based upon capabilities_size */
1571 
1572             switch (CapabilitiesSize)
1573             {
1574             case 0:
1575                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1576                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B), AcpiDmTableInfoNhlt5b);
1577                 if (ACPI_FAILURE (Status))
1578                 {
1579                     return;
1580                 }
1581                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B);
1582                 break;
1583 
1584             case 1:
1585                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1586                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_C), AcpiDmTableInfoNhlt5c);
1587                 if (ACPI_FAILURE (Status))
1588                 {
1589                     return;
1590                 }
1591                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_C);
1592                 break;
1593 
1594             case 2:
1595                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1596                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG), AcpiDmTableInfoNhlt5);
1597                 if (ACPI_FAILURE (Status))
1598                 {
1599                     return;
1600                 }
1601                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG);
1602                 break;
1603 
1604             case 3:
1605                 ConfigType = DevSpecific->ConfigType;
1606                 ArrayType = DevSpecific->ArrayType;
1607 
1608                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1609                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A), AcpiDmTableInfoNhlt5a);
1610                 if (ACPI_FAILURE (Status))
1611                 {
1612                     return;
1613                 }
1614 
1615                 /* Capabilities Size == 3 */
1616                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A);
1617 
1618                 /* Check for a vendor-defined mic array */
1619 
1620                 if ((ConfigType == ACPI_NHLT_TYPE_MIC_ARRAY) && ((ArrayType & ARRAY_TYPE_MASK) == VENDOR_DEFINED))
1621                 {
1622                     /* Vendor-defined microphone array */
1623 
1624                     AcpiOsPrintf ("\n/* Vendor-defined microphone array */\n");
1625 
1626                     Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1627                         sizeof (ACPI_NHLT_VENDOR_MIC_CONFIG), AcpiDmTableInfoNhlt6);
1628                     if (ACPI_FAILURE (Status))
1629                     {
1630                         return;
1631                     }
1632                     Offset += sizeof (ACPI_NHLT_VENDOR_MIC_CONFIG);
1633                 }
1634                 break;
1635 
1636             default:
1637                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1638                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B), AcpiDmTableInfoNhlt5b);
1639                 if (ACPI_FAILURE (Status))
1640                 {
1641                     return;
1642                 }
1643 
1644                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B);
1645                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1646                     CapabilitiesSize, AcpiDmTableInfoNhlt3a);
1647                 if (ACPI_FAILURE (Status))
1648                 {
1649                     return;
1650                 }
1651                 Offset += CapabilitiesSize;
1652                 break;
1653             }
1654 
1655             /* Do the Formats_Config table */
1656 
1657             FormatsConfig = ACPI_ADD_PTR (ACPI_NHLT_FORMATS_CONFIG, Table, Offset);
1658             FormatsCount = FormatsConfig->FormatsCount;
1659 
1660             AcpiOsPrintf ("\n/* Formats_Config table */\n");
1661 
1662             Status = AcpiDmDumpTable (TableLength, Offset, FormatsConfig,
1663                 sizeof (ACPI_NHLT_FORMATS_CONFIG), AcpiDmTableInfoNhlt4);
1664             if (ACPI_FAILURE (Status))
1665             {
1666                 return;
1667             }
1668             Offset += sizeof (ACPI_NHLT_FORMATS_CONFIG);
1669 
1670             /* A variable number of Format_Config Descriptors - process each */
1671 
1672             for (j = 0; j < FormatsCount; j++)
1673             {
1674                 FormatSubtable = ACPI_ADD_PTR (ACPI_NHLT_FORMAT_CONFIG, Table, Offset);
1675                 CapabilitiesSize = FormatSubtable->CapabilitySize;
1676 
1677                 /* Do the Wave_extensible struct */
1678 
1679                 AcpiOsPrintf ("\n/* Wave_Format_Extensible table #%u */\n", j+1);
1680                 Status = AcpiDmDumpTable (TableLength, Offset, FormatSubtable,
1681                     sizeof (ACPI_NHLT_FORMAT_CONFIG), AcpiDmTableInfoNhlt3);
1682                 if (ACPI_FAILURE (Status))
1683                 {
1684                     return;
1685                 }
1686                 Offset += sizeof (ACPI_NHLT_WAVE_EXTENSIBLE);
1687 
1688                 /* Do the Capabilities array */
1689 
1690                 Offset += sizeof (UINT32);
1691                 AcpiOsPrintf ("\n/* Specific_Config table #%u */\n", j+1);
1692                 FormatSubtable = ACPI_ADD_PTR (ACPI_NHLT_FORMAT_CONFIG, Table, Offset);
1693                 Status = AcpiDmDumpTable (TableLength, Offset, FormatSubtable,
1694                     CapabilitiesSize, AcpiDmTableInfoNhlt3a);
1695                 if (ACPI_FAILURE (Status))
1696                 {
1697                     return;
1698                 }
1699                 Offset += CapabilitiesSize;
1700             }
1701 
1702             /*
1703              * If we are not done with the Endpoint(s) yet, then there must be
1704              * some Linux-specific structure(s) yet to be processed.
1705              */
1706             if (Offset < EndpointEndOffset)
1707             {
1708                 AcpiOsPrintf ("\n");
1709                 Count = ACPI_ADD_PTR (ACPI_NHLT_LINUX_SPECIFIC_COUNT, Table, Offset);
1710                 Status = AcpiDmDumpTable (TableLength, Offset, Count,
1711                     sizeof (ACPI_NHLT_LINUX_SPECIFIC_COUNT), AcpiDmTableInfoNhlt7);
1712                 if (ACPI_FAILURE (Status))
1713                 {
1714                     return;
1715                 }
1716                 Offset += sizeof (ACPI_NHLT_LINUX_SPECIFIC_COUNT);
1717 
1718                 /* Variable number of linux-specific structures */
1719 
1720                 for (k = 0; k < Count->StructureCount; k++)
1721                 {
1722                     LinuxData = ACPI_ADD_PTR (ACPI_NHLT_LINUX_SPECIFIC_DATA, Table, Offset);
1723 
1724                     AcpiOsPrintf ("\n/* Linux-specific structure #%u */\n", k+1);
1725 
1726                     Status = AcpiDmDumpTable (TableLength, Offset, LinuxData,
1727                         sizeof (ACPI_NHLT_LINUX_SPECIFIC_DATA), AcpiDmTableInfoNhlt7a);
1728                     if (ACPI_FAILURE (Status))
1729                     {
1730                         return;
1731                     }
1732 
1733                     Offset += sizeof (ACPI_NHLT_LINUX_SPECIFIC_DATA);
1734                 }
1735 
1736                 /* Should be at the end of the Endpoint structure. Skip any extra bytes */
1737 
1738                 if (Offset < EndpointEndOffset)
1739                 {
1740                     AcpiOsPrintf ("\n/* Endpoint descriptor ended before endpoint size was reached. "
1741                         "skipped %X input bytes, current offset: %X, Endpoint End Offset: %X */\n",
1742                         EndpointEndOffset - Offset, Offset, EndpointEndOffset);
1743                     AcpiUtDumpBuffer (((UINT8 *)Table)+Offset,
1744                         EndpointEndOffset - Offset, DB_BYTE_DISPLAY, Offset);
1745                     Offset = EndpointEndOffset;
1746                 }
1747             }
1748         }
1749 
1750         /* Emit the table terminator (if present) */
1751 
1752         if (Offset == TableLength - sizeof (ACPI_NHLT_TABLE_TERMINATOR))
1753         {
1754             LinuxData = ACPI_ADD_PTR (ACPI_NHLT_LINUX_SPECIFIC_DATA, Table, Offset);
1755             AcpiOsPrintf ("\n/* Table terminator structure */\n");
1756 
1757             Status = AcpiDmDumpTable (TableLength, Offset, LinuxData,
1758                 sizeof (ACPI_NHLT_TABLE_TERMINATOR), AcpiDmTableInfoNhlt8);
1759             if (ACPI_FAILURE (Status))
1760             {
1761                 return;
1762             }
1763         }
1764 
1765         return;
1766     }
1767 }
1768 
1769 
1770 /*******************************************************************************
1771  *
1772  * FUNCTION:    AcpiDmDumpPcct
1773  *
1774  * PARAMETERS:  Table               - A PCCT table
1775  *
1776  * RETURN:      None
1777  *
1778  * DESCRIPTION: Format the contents of a PCCT. This table type consists
1779  *              of an open-ended number of subtables.
1780  *
1781  ******************************************************************************/
1782 
1783 void
1784 AcpiDmDumpPcct (
1785     ACPI_TABLE_HEADER       *Table)
1786 {
1787     ACPI_STATUS             Status;
1788     ACPI_PCCT_SUBSPACE      *Subtable;
1789     ACPI_DMTABLE_INFO       *InfoTable;
1790     UINT32                  Length = Table->Length;
1791     UINT32                  Offset = sizeof (ACPI_TABLE_PCCT);
1792 
1793 
1794     /* Main table */
1795 
1796     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct);
1797     if (ACPI_FAILURE (Status))
1798     {
1799         return;
1800     }
1801 
1802     /* Subtables */
1803 
1804     Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
1805     while (Offset < Table->Length)
1806     {
1807         /* Common subtable header */
1808 
1809         AcpiOsPrintf ("\n");
1810         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1811             Subtable->Header.Length, AcpiDmTableInfoPcctHdr);
1812         if (ACPI_FAILURE (Status))
1813         {
1814             return;
1815         }
1816 
1817         switch (Subtable->Header.Type)
1818         {
1819         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1820 
1821             InfoTable = AcpiDmTableInfoPcct0;
1822             break;
1823 
1824         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1825 
1826             InfoTable = AcpiDmTableInfoPcct1;
1827             break;
1828 
1829         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
1830 
1831             InfoTable = AcpiDmTableInfoPcct2;
1832             break;
1833 
1834         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
1835 
1836             InfoTable = AcpiDmTableInfoPcct3;
1837             break;
1838 
1839         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
1840 
1841             InfoTable = AcpiDmTableInfoPcct4;
1842             break;
1843 
1844         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
1845 
1846             InfoTable = AcpiDmTableInfoPcct5;
1847             break;
1848 
1849         default:
1850 
1851             AcpiOsPrintf (
1852                 "\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n",
1853                 Subtable->Header.Type);
1854             return;
1855         }
1856 
1857         AcpiOsPrintf ("\n");
1858         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1859             Subtable->Header.Length, InfoTable);
1860         if (ACPI_FAILURE (Status))
1861         {
1862             return;
1863         }
1864 
1865         /* Point to next subtable */
1866 
1867         Offset += Subtable->Header.Length;
1868         Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Subtable,
1869             Subtable->Header.Length);
1870     }
1871 }
1872 
1873 
1874 /*******************************************************************************
1875  *
1876  * FUNCTION:    AcpiDmDumpPdtt
1877  *
1878  * PARAMETERS:  Table               - A PDTT table
1879  *
1880  * RETURN:      None
1881  *
1882  * DESCRIPTION: Format the contents of a Pdtt. This is a variable-length
1883  *              table that contains an open-ended number of IDs
1884  *              at the end of the table.
1885  *
1886  ******************************************************************************/
1887 
1888 void
1889 AcpiDmDumpPdtt (
1890     ACPI_TABLE_HEADER       *Table)
1891 {
1892     ACPI_STATUS             Status;
1893     ACPI_PDTT_CHANNEL       *Subtable;
1894     UINT32                  Length = Table->Length;
1895     UINT32                  Offset = sizeof (ACPI_TABLE_PDTT);
1896 
1897 
1898     /* Main table */
1899 
1900     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPdtt);
1901     if (ACPI_FAILURE (Status))
1902     {
1903         return;
1904     }
1905 
1906     /* Subtables. Currently there is only one type, but can be multiples */
1907 
1908     Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Table, Offset);
1909     while (Offset < Table->Length)
1910     {
1911         AcpiOsPrintf ("\n");
1912         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1913             sizeof (ACPI_PDTT_CHANNEL), AcpiDmTableInfoPdtt0);
1914         if (ACPI_FAILURE (Status))
1915         {
1916             return;
1917         }
1918 
1919         /* Point to next subtable */
1920 
1921         Offset += sizeof (ACPI_PDTT_CHANNEL);
1922         Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Subtable,
1923             sizeof (ACPI_PDTT_CHANNEL));
1924     }
1925 }
1926 
1927 
1928 /*******************************************************************************
1929  *
1930  * FUNCTION:    AcpiDmDumpPhat
1931  *
1932  * PARAMETERS:  Table               - A PHAT table
1933  *
1934  * RETURN:      None
1935  *
1936  * DESCRIPTION: Format the contents of a PHAT.
1937  *
1938  ******************************************************************************/
1939 
1940 void
1941 AcpiDmDumpPhat (
1942     ACPI_TABLE_HEADER       *Table)
1943 {
1944     ACPI_STATUS             Status;
1945     ACPI_DMTABLE_INFO       *InfoTable;
1946     ACPI_PHAT_HEADER        *Subtable;
1947     ACPI_PHAT_VERSION_DATA  *VersionData;
1948     UINT32                  RecordCount;
1949     UINT32                  Length = Table->Length;
1950     UINT32                  Offset = sizeof (ACPI_TABLE_PHAT);
1951     UINT32                  SubtableLength;
1952     UINT32                  PathLength;
1953     UINT32                  VendorLength;
1954 
1955 
1956     Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, sizeof (ACPI_TABLE_PHAT));
1957 
1958     while (Offset < Table->Length)
1959     {
1960         /* Common subtable header */
1961 
1962         AcpiOsPrintf ("\n");
1963         Status = AcpiDmDumpTable (Length, 0, Subtable,
1964             sizeof (ACPI_PHAT_HEADER), AcpiDmTableInfoPhatHdr);
1965         if (ACPI_FAILURE (Status))
1966         {
1967             return;
1968         }
1969 
1970         switch (Subtable->Type)
1971         {
1972         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1973 
1974             InfoTable = AcpiDmTableInfoPhat0;
1975             SubtableLength = sizeof (ACPI_PHAT_VERSION_DATA);
1976             break;
1977 
1978         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1979 
1980             InfoTable = AcpiDmTableInfoPhat1;
1981             SubtableLength = sizeof (ACPI_PHAT_HEALTH_DATA);
1982             break;
1983 
1984         default:
1985 
1986             AcpiOsPrintf ("\n**** Unknown PHAT subtable type 0x%X\n\n",
1987                 Subtable->Type);
1988 
1989             return;
1990         }
1991 
1992         Status = AcpiDmDumpTable (Length, 0, Subtable,
1993             SubtableLength, InfoTable);
1994         if (ACPI_FAILURE (Status))
1995         {
1996             return;
1997         }
1998 
1999         switch (Subtable->Type)
2000         {
2001         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
2002 
2003             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, Subtable);
2004             RecordCount = VersionData->ElementCount;
2005             while (RecordCount)
2006             {
2007                 Status = AcpiDmDumpTable (Length, Offset,
2008                     ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_VERSION_DATA)),
2009                     sizeof (ACPI_PHAT_VERSION_ELEMENT), AcpiDmTableInfoPhat0a);
2010                 if (ACPI_FAILURE (Status))
2011                 {
2012                     return;
2013                 }
2014 
2015                 RecordCount--;
2016             }
2017 
2018             break;
2019 
2020         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
2021 
2022             /* account for the null terminator */
2023 
2024             PathLength = strlen (ACPI_ADD_PTR (char, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA))) + 1;
2025             Status = AcpiDmDumpTable (Length, Offset,
2026                 ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA)),
2027                 PathLength, AcpiDmTableInfoPhat1a);
2028             if (ACPI_FAILURE (Status))
2029             {
2030                 return;
2031             }
2032 
2033             /* Get vendor data - data length is the remaining subtable length */
2034 
2035             VendorLength =
2036                 Subtable->Length - sizeof (ACPI_PHAT_HEALTH_DATA) - PathLength;
2037             Status = AcpiDmDumpTable (Length, 0,
2038                 ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA) + PathLength),
2039                 VendorLength, AcpiDmTableInfoPhat1b);
2040             if (ACPI_FAILURE (Status))
2041             {
2042                 return;
2043             }
2044             break;
2045 
2046         default:
2047 
2048             AcpiOsPrintf ("\n**** Unknown PHAT subtable type 0x%X\n\n",
2049                 Subtable->Type);
2050             return;
2051         }
2052 
2053         /* Next subtable */
2054 
2055         Offset += Subtable->Length;
2056         Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable,
2057             Subtable->Length);
2058     }
2059 }
2060 
2061 
2062 /*******************************************************************************
2063  *
2064  * FUNCTION:    AcpiDmDumpPmtt
2065  *
2066  * PARAMETERS:  Table               - A PMTT table
2067  *
2068  * RETURN:      None
2069  *
2070  * DESCRIPTION: Format the contents of a PMTT. This table type consists
2071  *              of an open-ended number of subtables.
2072  *
2073  ******************************************************************************/
2074 
2075 void
2076 AcpiDmDumpPmtt (
2077     ACPI_TABLE_HEADER       *Table)
2078 {
2079     ACPI_STATUS             Status;
2080     ACPI_PMTT_HEADER        *Subtable;
2081     UINT32                  Length = Table->Length;
2082     UINT32                  Offset = sizeof (ACPI_TABLE_PMTT);
2083 
2084 
2085     /* Main table */
2086 
2087     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt);
2088     if (ACPI_FAILURE (Status))
2089     {
2090         return;
2091     }
2092 
2093     /* Subtables */
2094 
2095     Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
2096     while (Offset < Table->Length)
2097     {
2098         /* Each of the types below contain the common subtable header */
2099 
2100         AcpiOsPrintf ("\n");
2101         switch (Subtable->Type)
2102         {
2103         case ACPI_PMTT_TYPE_SOCKET:
2104 
2105             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2106                 Subtable->Length, AcpiDmTableInfoPmtt0);
2107             if (ACPI_FAILURE (Status))
2108             {
2109                 return;
2110             }
2111             break;
2112 
2113         case ACPI_PMTT_TYPE_CONTROLLER:
2114             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2115                 Subtable->Length, AcpiDmTableInfoPmtt1);
2116             if (ACPI_FAILURE (Status))
2117             {
2118                 return;
2119             }
2120             break;
2121 
2122        case ACPI_PMTT_TYPE_DIMM:
2123             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2124                 Subtable->Length, AcpiDmTableInfoPmtt2);
2125             if (ACPI_FAILURE (Status))
2126             {
2127                 return;
2128             }
2129             break;
2130 
2131         case ACPI_PMTT_TYPE_VENDOR:
2132             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2133                 Subtable->Length, AcpiDmTableInfoPmttVendor);
2134             if (ACPI_FAILURE (Status))
2135             {
2136                 return;
2137             }
2138             break;
2139 
2140         default:
2141             AcpiOsPrintf (
2142                 "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
2143                 Subtable->Type);
2144             return;
2145         }
2146 
2147         /* Point to next subtable */
2148 
2149         Offset += Subtable->Length;
2150         Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
2151             Subtable, Subtable->Length);
2152     }
2153 }
2154 
2155 
2156 /*******************************************************************************
2157  *
2158  * FUNCTION:    AcpiDmDumpPptt
2159  *
2160  * PARAMETERS:  Table               - A PMTT table
2161  *
2162  * RETURN:      None
2163  *
2164  * DESCRIPTION: Format the contents of a PPTT. This table type consists
2165  *              of an open-ended number of subtables.
2166  *
2167  ******************************************************************************/
2168 
2169 void
2170 AcpiDmDumpPptt (
2171     ACPI_TABLE_HEADER       *Table)
2172 {
2173     ACPI_STATUS             Status;
2174     ACPI_SUBTABLE_HEADER    *Subtable;
2175     ACPI_PPTT_PROCESSOR     *PpttProcessor;
2176     UINT8                   Length;
2177     UINT8                   SubtableOffset;
2178     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
2179     ACPI_DMTABLE_INFO       *InfoTable;
2180     UINT32                  i;
2181 
2182 
2183     /* There is no main table (other than the standard ACPI header) */
2184 
2185     /* Subtables */
2186 
2187     Offset = sizeof (ACPI_TABLE_HEADER);
2188     while (Offset < Table->Length)
2189     {
2190         AcpiOsPrintf ("\n");
2191 
2192         /* Common subtable header */
2193 
2194         Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
2195         if (Subtable->Length < sizeof (ACPI_SUBTABLE_HEADER))
2196         {
2197             AcpiOsPrintf ("Invalid subtable length\n");
2198             return;
2199         }
2200         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2201             Subtable->Length, AcpiDmTableInfoPpttHdr);
2202         if (ACPI_FAILURE (Status))
2203         {
2204             return;
2205         }
2206 
2207         switch (Subtable->Type)
2208         {
2209         case ACPI_PPTT_TYPE_PROCESSOR:
2210 
2211             InfoTable = AcpiDmTableInfoPptt0;
2212             Length = sizeof (ACPI_PPTT_PROCESSOR);
2213             break;
2214 
2215         case ACPI_PPTT_TYPE_CACHE:
2216 
2217             InfoTable = AcpiDmTableInfoPptt1;
2218             Length = sizeof (ACPI_PPTT_CACHE);
2219             break;
2220 
2221         case ACPI_PPTT_TYPE_ID:
2222 
2223             InfoTable = AcpiDmTableInfoPptt2;
2224             Length = sizeof (ACPI_PPTT_ID);
2225             break;
2226 
2227         default:
2228 
2229             AcpiOsPrintf ("\n**** Unknown PPTT subtable type 0x%X\n\n",
2230                 Subtable->Type);
2231 
2232             /* Attempt to continue */
2233 
2234             goto NextSubtable;
2235         }
2236 
2237         if (Subtable->Length < Length)
2238         {
2239             AcpiOsPrintf ("Invalid subtable length\n");
2240             return;
2241         }
2242         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2243             Subtable->Length, InfoTable);
2244         if (ACPI_FAILURE (Status))
2245         {
2246             return;
2247         }
2248         SubtableOffset = Length;
2249 
2250         switch (Subtable->Type)
2251         {
2252         case ACPI_PPTT_TYPE_PROCESSOR:
2253 
2254             PpttProcessor = ACPI_CAST_PTR (ACPI_PPTT_PROCESSOR, Subtable);
2255 
2256             /* Dump SMBIOS handles */
2257 
2258             if ((UINT8)(Subtable->Length - SubtableOffset) <
2259                 (UINT8)(PpttProcessor->NumberOfPrivResources * 4))
2260             {
2261                 AcpiOsPrintf ("Invalid private resource number\n");
2262                 return;
2263             }
2264             for (i = 0; i < PpttProcessor->NumberOfPrivResources; i++)
2265             {
2266                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2267                     ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
2268                     4, AcpiDmTableInfoPptt0a);
2269                 if (ACPI_FAILURE (Status))
2270                 {
2271                     return;
2272                 }
2273 
2274                 SubtableOffset += 4;
2275             }
2276             break;
2277 
2278         case ACPI_PPTT_TYPE_CACHE:
2279 
2280             if (Table->Revision < 3)
2281             {
2282                 break;
2283             }
2284             Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2285                 ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
2286                 sizeof (ACPI_PPTT_CACHE_V1), AcpiDmTableInfoPptt1a);
2287             if (ACPI_FAILURE (Status))
2288             {
2289                 return;
2290             }
2291             break;
2292 
2293         default:
2294 
2295             break;
2296         }
2297 
2298 NextSubtable:
2299         /* Point to next subtable */
2300 
2301         Offset += Subtable->Length;
2302     }
2303 }
2304 
2305 
2306 /*******************************************************************************
2307  *
2308  * FUNCTION:    AcpiDmDumpPrmt
2309  *
2310  * PARAMETERS:  Table               - A PRMT table
2311  *
2312  * RETURN:      None
2313  *
2314  * DESCRIPTION: Format the contents of a PRMT. This table type consists
2315  *              of an open-ended number of subtables.
2316  *
2317  ******************************************************************************/
2318 
2319 void
2320 AcpiDmDumpPrmt (
2321     ACPI_TABLE_HEADER       *Table)
2322 {
2323     UINT32                  CurrentOffset = sizeof (ACPI_TABLE_HEADER);
2324     ACPI_TABLE_PRMT_HEADER  *PrmtHeader;
2325     ACPI_PRMT_MODULE_INFO   *PrmtModuleInfo;
2326     ACPI_PRMT_HANDLER_INFO  *PrmtHandlerInfo;
2327     ACPI_STATUS             Status;
2328     UINT32                  i, j;
2329 
2330 
2331     /* Main table header */
2332 
2333     PrmtHeader = ACPI_ADD_PTR (ACPI_TABLE_PRMT_HEADER, Table, CurrentOffset);
2334     Status = AcpiDmDumpTable (Table->Length, CurrentOffset, PrmtHeader,
2335         sizeof (ACPI_TABLE_PRMT_HEADER), AcpiDmTableInfoPrmtHdr);
2336     if (ACPI_FAILURE (Status))
2337     {
2338         AcpiOsPrintf ("Invalid PRMT header\n");
2339         return;
2340     }
2341 
2342     CurrentOffset += sizeof (ACPI_TABLE_PRMT_HEADER);
2343 
2344     /* PRM Module Information Structure array */
2345 
2346     for (i = 0; i < PrmtHeader->ModuleInfoCount; ++i)
2347     {
2348         PrmtModuleInfo = ACPI_ADD_PTR (ACPI_PRMT_MODULE_INFO, Table, CurrentOffset);
2349         Status = AcpiDmDumpTable (Table->Length, CurrentOffset, PrmtModuleInfo,
2350             sizeof (ACPI_PRMT_MODULE_INFO), AcpiDmTableInfoPrmtModule);
2351 
2352         CurrentOffset += sizeof (ACPI_PRMT_MODULE_INFO);
2353 
2354         /* PRM handler information structure array */
2355 
2356         for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; ++j)
2357         {
2358             PrmtHandlerInfo = ACPI_ADD_PTR (ACPI_PRMT_HANDLER_INFO, Table, CurrentOffset);
2359             Status = AcpiDmDumpTable (Table->Length, CurrentOffset, PrmtHandlerInfo,
2360                 sizeof (ACPI_PRMT_HANDLER_INFO), AcpiDmTableInfoPrmtHandler);
2361 
2362             CurrentOffset += sizeof (ACPI_PRMT_HANDLER_INFO);
2363         }
2364     }
2365 }
2366 
2367 
2368 /*******************************************************************************
2369  *
2370  * FUNCTION:    AcpiDmDumpRgrt
2371  *
2372  * PARAMETERS:  Table               - A RGRT table
2373  *
2374  * RETURN:      None
2375  *
2376  * DESCRIPTION: Format the contents of a RGRT
2377  *
2378  ******************************************************************************/
2379 
2380 void
2381 AcpiDmDumpRgrt (
2382     ACPI_TABLE_HEADER       *Table)
2383 {
2384     ACPI_STATUS             Status;
2385     ACPI_TABLE_RGRT         *Subtable = ACPI_CAST_PTR (ACPI_TABLE_RGRT, Table);
2386     UINT32                  Offset = sizeof (ACPI_TABLE_RGRT);
2387 
2388 
2389     /* Main table */
2390 
2391     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoRgrt);
2392     if (ACPI_FAILURE (Status))
2393     {
2394         return;
2395     }
2396 
2397     /* Dump the binary image as a subtable */
2398 
2399     Status = AcpiDmDumpTable (Table->Length, Offset, &Subtable->Image,
2400         Table->Length - Offset, AcpiDmTableInfoRgrt0);
2401     if (ACPI_FAILURE (Status))
2402     {
2403         return;
2404     }
2405 }
2406 
2407 
2408 /*******************************************************************************
2409  *
2410  * FUNCTION:    AcpiDmDumpS3pt
2411  *
2412  * PARAMETERS:  Table               - A S3PT table
2413  *
2414  * RETURN:      Length of the table
2415  *
2416  * DESCRIPTION: Format the contents of a S3PT
2417  *
2418  ******************************************************************************/
2419 
2420 UINT32
2421 AcpiDmDumpS3pt (
2422     ACPI_TABLE_HEADER       *Tables)
2423 {
2424     ACPI_STATUS             Status;
2425     UINT32                  Offset = sizeof (ACPI_TABLE_S3PT);
2426     ACPI_FPDT_HEADER        *Subtable;
2427     ACPI_DMTABLE_INFO       *InfoTable;
2428     ACPI_TABLE_S3PT         *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
2429 
2430 
2431     /* Main table */
2432 
2433     Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt);
2434     if (ACPI_FAILURE (Status))
2435     {
2436         return 0;
2437     }
2438 
2439     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, S3ptTable, Offset);
2440     while (Offset < S3ptTable->Length)
2441     {
2442         /* Common subtable header */
2443 
2444         AcpiOsPrintf ("\n");
2445         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
2446             Subtable->Length, AcpiDmTableInfoS3ptHdr);
2447         if (ACPI_FAILURE (Status))
2448         {
2449             return 0;
2450         }
2451 
2452         switch (Subtable->Type)
2453         {
2454         case ACPI_S3PT_TYPE_RESUME:
2455 
2456             InfoTable = AcpiDmTableInfoS3pt0;
2457             break;
2458 
2459         case ACPI_S3PT_TYPE_SUSPEND:
2460 
2461             InfoTable = AcpiDmTableInfoS3pt1;
2462             break;
2463 
2464         default:
2465 
2466             AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n",
2467                 Subtable->Type);
2468 
2469             /* Attempt to continue */
2470 
2471             if (!Subtable->Length)
2472             {
2473                 AcpiOsPrintf ("Invalid zero length subtable\n");
2474                 return 0;
2475             }
2476             goto NextSubtable;
2477         }
2478 
2479         AcpiOsPrintf ("\n");
2480         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
2481             Subtable->Length, InfoTable);
2482         if (ACPI_FAILURE (Status))
2483         {
2484             return 0;
2485         }
2486 
2487 NextSubtable:
2488         /* Point to next subtable */
2489 
2490         Offset += Subtable->Length;
2491         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable, Subtable->Length);
2492     }
2493 
2494     return (S3ptTable->Length);
2495 }
2496 
2497 
2498 /*******************************************************************************
2499  *
2500  * FUNCTION:    AcpiDmDumpSdev
2501  *
2502  * PARAMETERS:  Table               - A SDEV table
2503  *
2504  * RETURN:      None
2505  *
2506  * DESCRIPTION: Format the contents of a SDEV. This is a variable-length
2507  *              table that contains variable strings and vendor data.
2508  *
2509  ******************************************************************************/
2510 
2511 void
2512 AcpiDmDumpSdev (
2513     ACPI_TABLE_HEADER       *Table)
2514 {
2515     ACPI_STATUS                 Status;
2516     ACPI_SDEV_HEADER            *Subtable;
2517     ACPI_SDEV_PCIE              *Pcie;
2518     ACPI_SDEV_NAMESPACE         *Namesp;
2519     ACPI_DMTABLE_INFO           *InfoTable;
2520     ACPI_DMTABLE_INFO           *SecureComponentInfoTable;
2521     UINT32                      Length = Table->Length;
2522     UINT32                      Offset = sizeof (ACPI_TABLE_SDEV);
2523     UINT16                      PathOffset;
2524     UINT16                      PathLength;
2525     UINT16                      VendorDataOffset;
2526     UINT16                      VendorDataLength;
2527     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
2528     UINT32                      CurrentOffset = 0;
2529 
2530 
2531     /* Main table */
2532 
2533     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoSdev);
2534     if (ACPI_FAILURE (Status))
2535     {
2536         return;
2537     }
2538 
2539     /* Subtables */
2540 
2541     Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Table, Offset);
2542     while (Offset < Table->Length)
2543     {
2544         /* Common subtable header */
2545 
2546         AcpiOsPrintf ("\n");
2547         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2548             Subtable->Length, AcpiDmTableInfoSdevHdr);
2549         if (ACPI_FAILURE (Status))
2550         {
2551             return;
2552         }
2553 
2554         switch (Subtable->Type)
2555         {
2556         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2557 
2558             InfoTable = AcpiDmTableInfoSdev0;
2559             break;
2560 
2561         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2562 
2563             InfoTable = AcpiDmTableInfoSdev1;
2564             break;
2565 
2566         default:
2567             goto NextSubtable;
2568         }
2569 
2570         AcpiOsPrintf ("\n");
2571         Status = AcpiDmDumpTable (Table->Length, 0, Subtable,
2572             Subtable->Length, InfoTable);
2573         if (ACPI_FAILURE (Status))
2574         {
2575             return;
2576         }
2577 
2578         switch (Subtable->Type)
2579         {
2580         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2581 
2582             CurrentOffset = sizeof (ACPI_SDEV_NAMESPACE);
2583             if (Subtable->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
2584             {
2585                 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
2586                     ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_SDEV_NAMESPACE)));
2587 
2588                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2589                     ACPI_ADD_PTR(UINT8, Subtable, sizeof (ACPI_SDEV_NAMESPACE)),
2590                     sizeof (ACPI_SDEV_SECURE_COMPONENT), AcpiDmTableInfoSdev0b);
2591                 if (ACPI_FAILURE (Status))
2592                 {
2593                     return;
2594                 }
2595                 CurrentOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2596 
2597                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2598                     ACPI_ADD_PTR(UINT8, Subtable, SecureComponent->SecureComponentOffset),
2599                     sizeof (ACPI_SDEV_HEADER), AcpiDmTableInfoSdevSecCompHdr);
2600                 if (ACPI_FAILURE (Status))
2601                 {
2602                     return;
2603                 }
2604                 CurrentOffset += sizeof (ACPI_SDEV_HEADER);
2605 
2606                 switch (Subtable->Type)
2607                 {
2608                 case ACPI_SDEV_TYPE_ID_COMPONENT:
2609 
2610                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
2611                     break;
2612 
2613                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
2614 
2615                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
2616                     break;
2617 
2618                 default:
2619                     goto NextSubtable;
2620                 }
2621 
2622                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2623                     ACPI_ADD_PTR(UINT8, Subtable, SecureComponent->SecureComponentOffset),
2624                     SecureComponent->SecureComponentLength, SecureComponentInfoTable);
2625                 CurrentOffset += SecureComponent->SecureComponentLength;
2626             }
2627 
2628             /* Dump the PCIe device ID(s) */
2629 
2630             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable);
2631             PathOffset = Namesp->DeviceIdOffset;
2632             PathLength = Namesp->DeviceIdLength;
2633 
2634             if (PathLength)
2635             {
2636                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2637                     ACPI_ADD_PTR (UINT8, Namesp, PathOffset),
2638                     PathLength, AcpiDmTableInfoSdev0a);
2639                 if (ACPI_FAILURE (Status))
2640                 {
2641                     return;
2642                 }
2643                 CurrentOffset += PathLength;
2644             }
2645 
2646             /* Dump the vendor-specific data */
2647 
2648             VendorDataLength =
2649                 Namesp->VendorDataLength;
2650             VendorDataOffset =
2651                 Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2652 
2653             if (VendorDataLength)
2654             {
2655                 Status = AcpiDmDumpTable (Table->Length, 0,
2656                     ACPI_ADD_PTR (UINT8, Namesp, VendorDataOffset),
2657                     VendorDataLength, AcpiDmTableInfoSdev1b);
2658                 if (ACPI_FAILURE (Status))
2659                 {
2660                     return;
2661                 }
2662             }
2663             break;
2664 
2665         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2666 
2667             /* PCI path substructures */
2668 
2669             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable);
2670             PathOffset = Pcie->PathOffset;
2671             PathLength = Pcie->PathLength;
2672 
2673             while (PathLength)
2674             {
2675                 Status = AcpiDmDumpTable (Table->Length,
2676                     PathOffset + Offset,
2677                     ACPI_ADD_PTR (UINT8, Pcie, PathOffset),
2678                     sizeof (ACPI_SDEV_PCIE_PATH), AcpiDmTableInfoSdev1a);
2679                 if (ACPI_FAILURE (Status))
2680                 {
2681                     return;
2682                 }
2683 
2684                 PathOffset += sizeof (ACPI_SDEV_PCIE_PATH);
2685                 PathLength -= sizeof (ACPI_SDEV_PCIE_PATH);
2686             }
2687 
2688             /* VendorData */
2689 
2690             VendorDataLength = Pcie->VendorDataLength;
2691             VendorDataOffset = Pcie->PathOffset + Pcie->PathLength;
2692 
2693             if (VendorDataLength)
2694             {
2695                 Status = AcpiDmDumpTable (Table->Length, 0,
2696                     ACPI_ADD_PTR (UINT8, Pcie, VendorDataOffset),
2697                     VendorDataLength, AcpiDmTableInfoSdev1b);
2698                 if (ACPI_FAILURE (Status))
2699                 {
2700                     return;
2701                 }
2702             }
2703             break;
2704 
2705         default:
2706             goto NextSubtable;
2707         }
2708 
2709 NextSubtable:
2710         /* Point to next subtable */
2711 
2712         Offset += Subtable->Length;
2713         Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Subtable,
2714             Subtable->Length);
2715     }
2716 }
2717