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 
157 /* This module used for application-level code only */
158 
159 #define _COMPONENT          ACPI_CA_DISASSEMBLER
160         ACPI_MODULE_NAME    ("dmtbdump2")
161 
162 
163 /*******************************************************************************
164  *
165  * FUNCTION:    AcpiDmDumpIort
166  *
167  * PARAMETERS:  Table               - A IORT table
168  *
169  * RETURN:      None
170  *
171  * DESCRIPTION: Format the contents of a IORT
172  *
173  ******************************************************************************/
174 
175 void
176 AcpiDmDumpIort (
177     ACPI_TABLE_HEADER       *Table)
178 {
179     ACPI_STATUS             Status;
180     ACPI_TABLE_IORT         *Iort;
181     ACPI_IORT_NODE          *IortNode;
182     ACPI_IORT_ITS_GROUP     *IortItsGroup = NULL;
183     ACPI_IORT_SMMU          *IortSmmu = NULL;
184     ACPI_IORT_RMR           *IortRmr = NULL;
185     UINT32                  Offset;
186     UINT32                  NodeOffset;
187     UINT32                  Length;
188     ACPI_DMTABLE_INFO       *InfoTable;
189     char                    *String;
190     UINT32                  i;
191     UINT32                  MappingByteLength;
192     UINT8                   Revision;
193 
194 
195     /* Main table */
196 
197     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIort);
198     if (ACPI_FAILURE (Status))
199     {
200         return;
201     }
202 
203     Revision = Table->Revision;
204 
205     /* Both IORT Rev E and E.a have known issues and are not supported */
206 
207     if (Revision == 1 || Revision == 2)
208     {
209         AcpiOsPrintf ("\n**** Unsupported IORT revision 0x%X\n",
210                       Revision);
211         return;
212     }
213 
214     Iort = ACPI_CAST_PTR (ACPI_TABLE_IORT, Table);
215     Offset = sizeof (ACPI_TABLE_IORT);
216 
217     /* Dump the OptionalPadding (optional) */
218 
219     if (Iort->NodeOffset > Offset)
220     {
221         Status = AcpiDmDumpTable (Table->Length, Offset, Table,
222             Iort->NodeOffset - Offset, AcpiDmTableInfoIortPad);
223         if (ACPI_FAILURE (Status))
224         {
225             return;
226         }
227     }
228 
229     Offset = Iort->NodeOffset;
230     while (Offset < Table->Length)
231     {
232         /* Common subtable header */
233 
234         IortNode = ACPI_ADD_PTR (ACPI_IORT_NODE, Table, Offset);
235         AcpiOsPrintf ("\n");
236         Length = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
237 
238         if (Revision == 0)
239         {
240             Status = AcpiDmDumpTable (Table->Length, Offset,
241                 IortNode, Length, AcpiDmTableInfoIortHdr);
242         }
243         else if (Revision >= 3)
244         {
245             Status = AcpiDmDumpTable (Table->Length, Offset,
246                 IortNode, Length, AcpiDmTableInfoIortHdr3);
247         }
248 
249         if (ACPI_FAILURE (Status))
250         {
251             return;
252         }
253 
254         NodeOffset = Length;
255 
256         switch (IortNode->Type)
257         {
258         case ACPI_IORT_NODE_ITS_GROUP:
259 
260             InfoTable = AcpiDmTableInfoIort0;
261             Length = ACPI_OFFSET (ACPI_IORT_ITS_GROUP, Identifiers);
262             IortItsGroup = ACPI_ADD_PTR (ACPI_IORT_ITS_GROUP, IortNode, NodeOffset);
263             break;
264 
265         case ACPI_IORT_NODE_NAMED_COMPONENT:
266 
267             InfoTable = AcpiDmTableInfoIort1;
268             Length = ACPI_OFFSET (ACPI_IORT_NAMED_COMPONENT, DeviceName);
269             String = ACPI_ADD_PTR (char, IortNode, NodeOffset + Length);
270             Length += strlen (String) + 1;
271             break;
272 
273         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
274 
275             InfoTable = AcpiDmTableInfoIort2;
276             Length = IortNode->Length - NodeOffset;
277             break;
278 
279         case ACPI_IORT_NODE_SMMU:
280 
281             InfoTable = AcpiDmTableInfoIort3;
282             Length = ACPI_OFFSET (ACPI_IORT_SMMU, Interrupts);
283             IortSmmu = ACPI_ADD_PTR (ACPI_IORT_SMMU, IortNode, NodeOffset);
284             break;
285 
286         case ACPI_IORT_NODE_SMMU_V3:
287 
288             InfoTable = AcpiDmTableInfoIort4;
289             Length = IortNode->Length - NodeOffset;
290             break;
291 
292         case ACPI_IORT_NODE_PMCG:
293 
294             InfoTable = AcpiDmTableInfoIort5;
295             Length = IortNode->Length - NodeOffset;
296             break;
297 
298         case ACPI_IORT_NODE_RMR:
299 
300             InfoTable = AcpiDmTableInfoIort6;
301             Length = IortNode->Length - NodeOffset;
302             IortRmr = ACPI_ADD_PTR (ACPI_IORT_RMR, IortNode, NodeOffset);
303             break;
304 
305         default:
306 
307             AcpiOsPrintf ("\n**** Unknown IORT node type 0x%X\n",
308                 IortNode->Type);
309 
310             /* Attempt to continue */
311 
312             if (!IortNode->Length)
313             {
314                 AcpiOsPrintf ("Invalid zero length IORT node\n");
315                 return;
316             }
317             goto NextSubtable;
318         }
319 
320         /* Dump the node subtable header */
321 
322         AcpiOsPrintf ("\n");
323         Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
324             ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
325             Length, InfoTable);
326         if (ACPI_FAILURE (Status))
327         {
328             return;
329         }
330 
331         NodeOffset += Length;
332 
333         /* Dump the node specific data */
334 
335         switch (IortNode->Type)
336         {
337         case ACPI_IORT_NODE_ITS_GROUP:
338 
339             /* Validate IortItsGroup to avoid compiler warnings */
340 
341             if (IortItsGroup)
342             {
343                 for (i = 0; i < IortItsGroup->ItsCount; i++)
344                 {
345                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
346                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
347                         4, AcpiDmTableInfoIort0a);
348                     if (ACPI_FAILURE (Status))
349                     {
350                         return;
351                     }
352 
353                     NodeOffset += 4;
354                 }
355             }
356             break;
357 
358         case ACPI_IORT_NODE_NAMED_COMPONENT:
359 
360             /* Dump the Padding (optional) */
361 
362             if (IortNode->Length > NodeOffset)
363             {
364                 MappingByteLength =
365                     IortNode->MappingCount * sizeof (ACPI_IORT_ID_MAPPING);
366                 Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
367                     Table, IortNode->Length - NodeOffset - MappingByteLength,
368                     AcpiDmTableInfoIort1a);
369                 if (ACPI_FAILURE (Status))
370                 {
371                     return;
372                 }
373             }
374             break;
375 
376         case ACPI_IORT_NODE_SMMU:
377 
378             AcpiOsPrintf ("\n");
379 
380             /* Validate IortSmmu to avoid compiler warnings */
381 
382             if (IortSmmu)
383             {
384                 Length = 2 * sizeof (UINT64);
385                 NodeOffset = IortSmmu->GlobalInterruptOffset;
386                 Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
387                     ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
388                     Length, AcpiDmTableInfoIort3a);
389                 if (ACPI_FAILURE (Status))
390                 {
391                     return;
392                 }
393 
394                 NodeOffset = IortSmmu->ContextInterruptOffset;
395                 for (i = 0; i < IortSmmu->ContextInterruptCount; i++)
396                 {
397                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
398                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
399                         8, AcpiDmTableInfoIort3b);
400                     if (ACPI_FAILURE (Status))
401                     {
402                         return;
403                     }
404 
405                     NodeOffset += 8;
406                 }
407 
408                 NodeOffset = IortSmmu->PmuInterruptOffset;
409                 for (i = 0; i < IortSmmu->PmuInterruptCount; i++)
410                 {
411                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
412                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
413                         8, AcpiDmTableInfoIort3c);
414                     if (ACPI_FAILURE (Status))
415                     {
416                         return;
417                     }
418 
419                     NodeOffset += 8;
420                 }
421             }
422             break;
423 
424         case ACPI_IORT_NODE_RMR:
425 
426             /* Validate IortRmr to avoid compiler warnings */
427             if (IortRmr)
428             {
429                 NodeOffset = IortRmr->RmrOffset;
430                 Length = sizeof (ACPI_IORT_RMR_DESC);
431                 for (i = 0; i < IortRmr->RmrCount; i++)
432                 {
433                     AcpiOsPrintf ("\n");
434                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
435                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
436                         Length, AcpiDmTableInfoIort6a);
437                     if (ACPI_FAILURE (Status))
438                     {
439                         return;
440                     }
441 
442                     NodeOffset += Length;
443                 }
444             }
445             break;
446 
447 	default:
448 
449             break;
450         }
451 
452         /* Dump the ID mappings */
453 
454         NodeOffset = IortNode->MappingOffset;
455         for (i = 0; i < IortNode->MappingCount; i++)
456         {
457             AcpiOsPrintf ("\n");
458             Length = sizeof (ACPI_IORT_ID_MAPPING);
459             Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
460                 ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
461                 Length, AcpiDmTableInfoIortMap);
462             if (ACPI_FAILURE (Status))
463             {
464                 return;
465             }
466 
467             NodeOffset += Length;
468         }
469 
470 NextSubtable:
471         /* Point to next node subtable */
472 
473         Offset += IortNode->Length;
474     }
475 }
476 
477 
478 /*******************************************************************************
479  *
480  * FUNCTION:    AcpiDmDumpIvrs
481  *
482  * PARAMETERS:  Table               - A IVRS table
483  *
484  * RETURN:      None
485  *
486  * DESCRIPTION: Format the contents of a IVRS
487  *
488  ******************************************************************************/
489 
490 void
491 AcpiDmDumpIvrs (
492     ACPI_TABLE_HEADER       *Table)
493 {
494     ACPI_STATUS             Status;
495     UINT32                  Offset = sizeof (ACPI_TABLE_IVRS);
496     UINT32                  EntryOffset;
497     UINT32                  EntryLength;
498     UINT32                  EntryType;
499     ACPI_IVRS_DEVICE_HID    *HidSubtable;
500     ACPI_IVRS_DE_HEADER     *DeviceEntry;
501     ACPI_IVRS_HEADER        *Subtable;
502     ACPI_DMTABLE_INFO       *InfoTable;
503 
504 
505     /* Main table */
506 
507     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs);
508     if (ACPI_FAILURE (Status))
509     {
510         return;
511     }
512 
513     /* Subtables */
514 
515     Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
516     while (Offset < Table->Length)
517     {
518         /* Common subtable header */
519 
520         AcpiOsPrintf ("\n");
521         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
522             Subtable->Length, AcpiDmTableInfoIvrsHdr);
523         if (ACPI_FAILURE (Status))
524         {
525             return;
526         }
527 
528         switch (Subtable->Type)
529         {
530         case ACPI_IVRS_TYPE_HARDWARE1:
531 
532             InfoTable = AcpiDmTableInfoIvrs0;
533             break;
534 
535         case ACPI_IVRS_TYPE_HARDWARE2:
536         case ACPI_IVRS_TYPE_HARDWARE3:
537 
538             InfoTable = AcpiDmTableInfoIvrs01;
539             break;
540 
541         case ACPI_IVRS_TYPE_MEMORY1:
542         case ACPI_IVRS_TYPE_MEMORY2:
543         case ACPI_IVRS_TYPE_MEMORY3:
544 
545             InfoTable = AcpiDmTableInfoIvrs1;
546             break;
547 
548         default:
549 
550             AcpiOsPrintf ("\n**** Unknown IVRS subtable type 0x%X\n",
551                 Subtable->Type);
552 
553             /* Attempt to continue */
554 
555             if (!Subtable->Length)
556             {
557                 AcpiOsPrintf ("Invalid zero length subtable\n");
558                 return;
559             }
560             goto NextSubtable;
561         }
562 
563         /* Dump the subtable */
564 
565         AcpiOsPrintf ("\n");
566         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
567             Subtable->Length, InfoTable);
568         if (ACPI_FAILURE (Status))
569         {
570             return;
571         }
572 
573         /* The hardware subtable can contain multiple device entries */
574 
575         if (Subtable->Type == ACPI_IVRS_TYPE_HARDWARE1 ||
576             Subtable->Type == ACPI_IVRS_TYPE_HARDWARE2 ||
577             Subtable->Type == ACPI_IVRS_TYPE_HARDWARE3)
578         {
579             if (Subtable->Type == ACPI_IVRS_TYPE_HARDWARE1)
580             {
581                 EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE1);
582                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, Subtable,
583                     sizeof (ACPI_IVRS_HARDWARE1));
584             }
585             else
586             {
587                 /* ACPI_IVRS_TYPE_HARDWARE2 subtable type */
588 
589                 EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE2);
590                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, Subtable,
591                     sizeof (ACPI_IVRS_HARDWARE2));
592             }
593 
594             while (EntryOffset < (Offset + Subtable->Length))
595             {
596                 AcpiOsPrintf ("\n");
597                 /*
598                  * Upper 2 bits of Type encode the length of the device entry
599                  *
600                  * 00 = 4 byte
601                  * 01 = 8 byte
602                  * 1x = variable length
603                  */
604                 EntryType = DeviceEntry->Type;
605                 EntryLength = EntryType >> 6 == 1 ? 8 : 4;
606 
607                 switch (EntryType)
608                 {
609                 /* 4-byte device entries */
610 
611                 case ACPI_IVRS_TYPE_PAD4:
612                 case ACPI_IVRS_TYPE_ALL:
613                 case ACPI_IVRS_TYPE_SELECT:
614                 case ACPI_IVRS_TYPE_START:
615                 case ACPI_IVRS_TYPE_END:
616 
617                     InfoTable = AcpiDmTableInfoIvrs4;
618                     break;
619 
620                 /* 8-byte entries, type A */
621 
622                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
623                 case ACPI_IVRS_TYPE_ALIAS_START:
624 
625                     InfoTable = AcpiDmTableInfoIvrs8a;
626                     break;
627 
628                 /* 8-byte entries, type B */
629 
630                 case ACPI_IVRS_TYPE_PAD8:
631                 case ACPI_IVRS_TYPE_EXT_SELECT:
632                 case ACPI_IVRS_TYPE_EXT_START:
633 
634                     InfoTable = AcpiDmTableInfoIvrs8b;
635                     break;
636 
637                 /* 8-byte entries, type C */
638 
639                 case ACPI_IVRS_TYPE_SPECIAL:
640 
641                     InfoTable = AcpiDmTableInfoIvrs8c;
642                     break;
643 
644                 /* Variable-length entries */
645 
646                 case ACPI_IVRS_TYPE_HID:
647 
648                     EntryLength = 22;
649                     InfoTable = AcpiDmTableInfoIvrsHid;
650                     break;
651 
652                 default:
653                     InfoTable = AcpiDmTableInfoIvrs4;
654                     AcpiOsPrintf (
655                         "\n**** Unknown IVRS device entry type/length: "
656                         "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
657                         EntryType, EntryLength, EntryOffset);
658                     break;
659                 }
660 
661                 /* Dump the Device Entry */
662 
663                 Status = AcpiDmDumpTable (Table->Length, EntryOffset,
664                     DeviceEntry, EntryLength, InfoTable);
665                 if (ACPI_FAILURE (Status))
666                 {
667                     return;
668                 }
669 
670                 HidSubtable = ACPI_CAST_PTR (ACPI_IVRS_DEVICE_HID, DeviceEntry);
671                 EntryOffset += EntryLength;
672                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, DeviceEntry,
673                     EntryLength);
674 
675                 if (EntryType == ACPI_IVRS_TYPE_HID)
676                 {
677                     EntryLength = HidSubtable->UidLength;
678                     Status = AcpiDmDumpTable (Table->Length, EntryOffset,
679                         Table, EntryLength, AcpiDmTableInfoIvrsHid1);
680                     if (ACPI_FAILURE (Status))
681                     {
682                         return;
683                     }
684                     EntryOffset += EntryLength;
685                     DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER,
686                         DeviceEntry, EntryLength);
687                 }
688             }
689         }
690 
691 NextSubtable:
692         /* Point to next subtable */
693 
694         Offset += Subtable->Length;
695         Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Subtable, Subtable->Length);
696     }
697 }
698 
699 
700 /*******************************************************************************
701  *
702  * FUNCTION:    AcpiDmDumpLpit
703  *
704  * PARAMETERS:  Table               - A LPIT table
705  *
706  * RETURN:      None
707  *
708  * DESCRIPTION: Format the contents of a LPIT. This table type consists
709  *              of an open-ended number of subtables. Note: There are no
710  *              entries in the main table. An LPIT consists of the table
711  *              header and then subtables only.
712  *
713  ******************************************************************************/
714 
715 void
716 AcpiDmDumpLpit (
717     ACPI_TABLE_HEADER       *Table)
718 {
719     ACPI_STATUS             Status;
720     ACPI_LPIT_HEADER        *Subtable;
721     UINT32                  Length = Table->Length;
722     UINT32                  Offset = sizeof (ACPI_TABLE_LPIT);
723     ACPI_DMTABLE_INFO       *InfoTable;
724     UINT32                  SubtableLength;
725 
726 
727     /* Subtables */
728 
729     Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset);
730     while (Offset < Table->Length)
731     {
732         /* Common subtable header */
733 
734         Status = AcpiDmDumpTable (Length, Offset, Subtable,
735             sizeof (ACPI_LPIT_HEADER), AcpiDmTableInfoLpitHdr);
736         if (ACPI_FAILURE (Status))
737         {
738             return;
739         }
740 
741         switch (Subtable->Type)
742         {
743         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
744 
745             InfoTable = AcpiDmTableInfoLpit0;
746             SubtableLength = sizeof (ACPI_LPIT_NATIVE);
747             break;
748 
749         default:
750 
751             /* Cannot continue on unknown type - no length */
752 
753             AcpiOsPrintf ("\n**** Unknown LPIT subtable type 0x%X\n",
754                 Subtable->Type);
755             return;
756         }
757 
758         Status = AcpiDmDumpTable (Length, Offset, Subtable,
759             SubtableLength, InfoTable);
760         if (ACPI_FAILURE (Status))
761         {
762             return;
763         }
764 
765         AcpiOsPrintf ("\n");
766 
767         /* Point to next subtable */
768 
769         Offset += SubtableLength;
770         Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Subtable, SubtableLength);
771     }
772 }
773 
774 
775 /*******************************************************************************
776  *
777  * FUNCTION:    AcpiDmDumpMadt
778  *
779  * PARAMETERS:  Table               - A MADT table
780  *
781  * RETURN:      None
782  *
783  * DESCRIPTION: Format the contents of a MADT. This table type consists
784  *              of an open-ended number of subtables.
785  *
786  ******************************************************************************/
787 
788 void
789 AcpiDmDumpMadt (
790     ACPI_TABLE_HEADER       *Table)
791 {
792     ACPI_STATUS             Status;
793     ACPI_SUBTABLE_HEADER    *Subtable;
794     UINT32                  Length = Table->Length;
795     UINT32                  Offset = sizeof (ACPI_TABLE_MADT);
796     ACPI_DMTABLE_INFO       *InfoTable;
797 
798 
799     /* Main table */
800 
801     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoMadt);
802     if (ACPI_FAILURE (Status))
803     {
804         return;
805     }
806 
807     /* Subtables */
808 
809     Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
810     while (Offset < Table->Length)
811     {
812         /* Common subtable header */
813 
814         AcpiOsPrintf ("\n");
815         Status = AcpiDmDumpTable (Length, Offset, Subtable,
816             Subtable->Length, AcpiDmTableInfoMadtHdr);
817         if (ACPI_FAILURE (Status))
818         {
819             return;
820         }
821 
822         switch (Subtable->Type)
823         {
824         case ACPI_MADT_TYPE_LOCAL_APIC:
825 
826             InfoTable = AcpiDmTableInfoMadt0;
827             break;
828 
829         case ACPI_MADT_TYPE_IO_APIC:
830 
831             InfoTable = AcpiDmTableInfoMadt1;
832             break;
833 
834         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
835 
836             InfoTable = AcpiDmTableInfoMadt2;
837             break;
838 
839         case ACPI_MADT_TYPE_NMI_SOURCE:
840 
841             InfoTable = AcpiDmTableInfoMadt3;
842             break;
843 
844         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
845 
846             InfoTable = AcpiDmTableInfoMadt4;
847             break;
848 
849         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
850 
851             InfoTable = AcpiDmTableInfoMadt5;
852             break;
853 
854         case ACPI_MADT_TYPE_IO_SAPIC:
855 
856             InfoTable = AcpiDmTableInfoMadt6;
857             break;
858 
859         case ACPI_MADT_TYPE_LOCAL_SAPIC:
860 
861             InfoTable = AcpiDmTableInfoMadt7;
862             break;
863 
864         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
865 
866             InfoTable = AcpiDmTableInfoMadt8;
867             break;
868 
869         case ACPI_MADT_TYPE_LOCAL_X2APIC:
870 
871             InfoTable = AcpiDmTableInfoMadt9;
872             break;
873 
874         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
875 
876             InfoTable = AcpiDmTableInfoMadt10;
877             break;
878 
879         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
880 
881             InfoTable = AcpiDmTableInfoMadt11;
882             break;
883 
884         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
885 
886             InfoTable = AcpiDmTableInfoMadt12;
887             break;
888 
889         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
890 
891             InfoTable = AcpiDmTableInfoMadt13;
892             break;
893 
894         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
895 
896             InfoTable = AcpiDmTableInfoMadt14;
897             break;
898 
899         case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
900 
901             InfoTable = AcpiDmTableInfoMadt15;
902             break;
903 
904         case ACPI_MADT_TYPE_MULTIPROC_WAKEUP:
905 
906             InfoTable = AcpiDmTableInfoMadt16;
907             break;
908 
909         default:
910 
911             AcpiOsPrintf ("\n**** Unknown MADT subtable type 0x%X\n\n",
912                 Subtable->Type);
913 
914             /* Attempt to continue */
915 
916             if (!Subtable->Length)
917             {
918                 AcpiOsPrintf ("Invalid zero length subtable\n");
919                 return;
920             }
921 
922             goto NextSubtable;
923         }
924 
925         Status = AcpiDmDumpTable (Length, Offset, Subtable,
926             Subtable->Length, InfoTable);
927         if (ACPI_FAILURE (Status))
928         {
929             return;
930         }
931 
932 NextSubtable:
933         /* Point to next subtable */
934 
935         Offset += Subtable->Length;
936         Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable,
937             Subtable->Length);
938     }
939 }
940 
941 
942 /*******************************************************************************
943  *
944  * FUNCTION:    AcpiDmDumpMcfg
945  *
946  * PARAMETERS:  Table               - A MCFG Table
947  *
948  * RETURN:      None
949  *
950  * DESCRIPTION: Format the contents of a MCFG table
951  *
952  ******************************************************************************/
953 
954 void
955 AcpiDmDumpMcfg (
956     ACPI_TABLE_HEADER       *Table)
957 {
958     ACPI_STATUS             Status;
959     UINT32                  Offset = sizeof (ACPI_TABLE_MCFG);
960     ACPI_MCFG_ALLOCATION    *Subtable;
961 
962 
963     /* Main table */
964 
965     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMcfg);
966     if (ACPI_FAILURE (Status))
967     {
968         return;
969     }
970 
971     /* Subtables */
972 
973     Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
974     while (Offset < Table->Length)
975     {
976         if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length)
977         {
978             AcpiOsPrintf ("Warning: there are %u invalid trailing bytes\n",
979                 (UINT32) sizeof (ACPI_MCFG_ALLOCATION) - (Offset - Table->Length));
980             return;
981         }
982 
983         AcpiOsPrintf ("\n");
984         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
985             sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0);
986         if (ACPI_FAILURE (Status))
987         {
988             return;
989         }
990 
991         /* Point to next subtable (each subtable is of fixed length) */
992 
993         Offset += sizeof (ACPI_MCFG_ALLOCATION);
994         Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Subtable,
995             sizeof (ACPI_MCFG_ALLOCATION));
996     }
997 }
998 
999 
1000 /*******************************************************************************
1001  *
1002  * FUNCTION:    AcpiDmDumpMpst
1003  *
1004  * PARAMETERS:  Table               - A MPST Table
1005  *
1006  * RETURN:      None
1007  *
1008  * DESCRIPTION: Format the contents of a MPST table
1009  *
1010  ******************************************************************************/
1011 
1012 void
1013 AcpiDmDumpMpst (
1014     ACPI_TABLE_HEADER       *Table)
1015 {
1016     ACPI_STATUS             Status;
1017     UINT32                  Offset = sizeof (ACPI_TABLE_MPST);
1018     ACPI_MPST_POWER_NODE    *Subtable0;
1019     ACPI_MPST_POWER_STATE   *Subtable0A;
1020     ACPI_MPST_COMPONENT     *Subtable0B;
1021     ACPI_MPST_DATA_HDR      *Subtable1;
1022     ACPI_MPST_POWER_DATA    *Subtable2;
1023     UINT16                  SubtableCount;
1024     UINT32                  PowerStateCount;
1025     UINT32                  ComponentCount;
1026 
1027 
1028     /* Main table */
1029 
1030     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMpst);
1031     if (ACPI_FAILURE (Status))
1032     {
1033         return;
1034     }
1035 
1036     /* Subtable: Memory Power Node(s) */
1037 
1038     SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount;
1039     Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
1040 
1041     while ((Offset < Table->Length) && SubtableCount)
1042     {
1043         AcpiOsPrintf ("\n");
1044         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0,
1045             sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0);
1046         if (ACPI_FAILURE (Status))
1047         {
1048             return;
1049         }
1050 
1051         /* Extract the sub-subtable counts */
1052 
1053         PowerStateCount = Subtable0->NumPowerStates;
1054         ComponentCount = Subtable0->NumPhysicalComponents;
1055         Offset += sizeof (ACPI_MPST_POWER_NODE);
1056 
1057         /* Sub-subtables - Memory Power State Structure(s) */
1058 
1059         Subtable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, Subtable0,
1060             sizeof (ACPI_MPST_POWER_NODE));
1061 
1062         while (PowerStateCount)
1063         {
1064             AcpiOsPrintf ("\n");
1065             Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0A,
1066                 sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A);
1067             if (ACPI_FAILURE (Status))
1068             {
1069                 return;
1070             }
1071 
1072             Subtable0A++;
1073             PowerStateCount--;
1074             Offset += sizeof (ACPI_MPST_POWER_STATE);
1075        }
1076 
1077         /* Sub-subtables - Physical Component ID Structure(s) */
1078 
1079         Subtable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, Subtable0A);
1080 
1081         if (ComponentCount)
1082         {
1083             AcpiOsPrintf ("\n");
1084         }
1085 
1086         while (ComponentCount)
1087         {
1088             Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0B,
1089                 sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B);
1090             if (ACPI_FAILURE (Status))
1091             {
1092                 return;
1093             }
1094 
1095             Subtable0B++;
1096             ComponentCount--;
1097             Offset += sizeof (ACPI_MPST_COMPONENT);
1098         }
1099 
1100         /* Point to next Memory Power Node subtable */
1101 
1102         SubtableCount--;
1103         Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Subtable0,
1104             sizeof (ACPI_MPST_POWER_NODE) +
1105             (sizeof (ACPI_MPST_POWER_STATE) * Subtable0->NumPowerStates) +
1106             (sizeof (ACPI_MPST_COMPONENT) * Subtable0->NumPhysicalComponents));
1107     }
1108 
1109     /* Subtable: Count of Memory Power State Characteristic structures */
1110 
1111     AcpiOsPrintf ("\n");
1112     Subtable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable0);
1113     Status = AcpiDmDumpTable (Table->Length, Offset, Subtable1,
1114         sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1);
1115     if (ACPI_FAILURE (Status))
1116     {
1117         return;
1118     }
1119 
1120     SubtableCount = Subtable1->CharacteristicsCount;
1121     Offset += sizeof (ACPI_MPST_DATA_HDR);
1122 
1123     /* Subtable: Memory Power State Characteristics structure(s) */
1124 
1125     Subtable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, Subtable1,
1126         sizeof (ACPI_MPST_DATA_HDR));
1127 
1128     while ((Offset < Table->Length) && SubtableCount)
1129     {
1130         AcpiOsPrintf ("\n");
1131         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable2,
1132             sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2);
1133         if (ACPI_FAILURE (Status))
1134         {
1135             return;
1136         }
1137 
1138         Subtable2++;
1139         SubtableCount--;
1140         Offset += sizeof (ACPI_MPST_POWER_DATA);
1141     }
1142 }
1143 
1144 
1145 /*******************************************************************************
1146  *
1147  * FUNCTION:    AcpiDmDumpMsct
1148  *
1149  * PARAMETERS:  Table               - A MSCT table
1150  *
1151  * RETURN:      None
1152  *
1153  * DESCRIPTION: Format the contents of a MSCT
1154  *
1155  ******************************************************************************/
1156 
1157 void
1158 AcpiDmDumpMsct (
1159     ACPI_TABLE_HEADER       *Table)
1160 {
1161     ACPI_STATUS             Status;
1162     UINT32                  Offset = sizeof (ACPI_TABLE_MSCT);
1163     ACPI_MSCT_PROXIMITY     *Subtable;
1164 
1165 
1166     /* Main table */
1167 
1168     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct);
1169     if (ACPI_FAILURE (Status))
1170     {
1171         return;
1172     }
1173 
1174     /* Subtables */
1175 
1176     Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
1177     while (Offset < Table->Length)
1178     {
1179         /* Common subtable header */
1180 
1181         AcpiOsPrintf ("\n");
1182         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1183             sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0);
1184         if (ACPI_FAILURE (Status))
1185         {
1186             return;
1187         }
1188 
1189         /* Point to next subtable */
1190 
1191         Offset += sizeof (ACPI_MSCT_PROXIMITY);
1192         Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Subtable,
1193             sizeof (ACPI_MSCT_PROXIMITY));
1194     }
1195 }
1196 
1197 
1198 /*******************************************************************************
1199  *
1200  * FUNCTION:    AcpiDmDumpNfit
1201  *
1202  * PARAMETERS:  Table               - A NFIT table
1203  *
1204  * RETURN:      None
1205  *
1206  * DESCRIPTION: Format the contents of an NFIT.
1207  *
1208  ******************************************************************************/
1209 
1210 void
1211 AcpiDmDumpNfit (
1212     ACPI_TABLE_HEADER       *Table)
1213 {
1214     ACPI_STATUS             Status;
1215     UINT32                  Offset = sizeof (ACPI_TABLE_NFIT);
1216     UINT32                  FieldOffset = 0;
1217     UINT32                  Length;
1218     ACPI_NFIT_HEADER        *Subtable;
1219     ACPI_DMTABLE_INFO       *InfoTable;
1220     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
1221     ACPI_NFIT_SMBIOS        *SmbiosInfo = NULL;
1222     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
1223     UINT32                  i;
1224 
1225 
1226     /* Main table */
1227 
1228     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoNfit);
1229     if (ACPI_FAILURE (Status))
1230     {
1231         return;
1232     }
1233 
1234     /* Subtables */
1235 
1236     Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset);
1237     while (Offset < Table->Length)
1238     {
1239         /* NFIT subtable header */
1240 
1241         AcpiOsPrintf ("\n");
1242         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1243             Subtable->Length, AcpiDmTableInfoNfitHdr);
1244         if (ACPI_FAILURE (Status))
1245         {
1246             return;
1247         }
1248 
1249         switch (Subtable->Type)
1250         {
1251         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
1252 
1253             InfoTable = AcpiDmTableInfoNfit0;
1254             break;
1255 
1256         case ACPI_NFIT_TYPE_MEMORY_MAP:
1257 
1258             InfoTable = AcpiDmTableInfoNfit1;
1259             break;
1260 
1261         case ACPI_NFIT_TYPE_INTERLEAVE:
1262 
1263             /* Has a variable number of 32-bit values at the end */
1264 
1265             InfoTable = AcpiDmTableInfoNfit2;
1266             FieldOffset = sizeof (ACPI_NFIT_INTERLEAVE);
1267             break;
1268 
1269         case ACPI_NFIT_TYPE_SMBIOS:
1270 
1271             SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, Subtable);
1272             InfoTable = AcpiDmTableInfoNfit3;
1273             break;
1274 
1275         case ACPI_NFIT_TYPE_CONTROL_REGION:
1276 
1277             InfoTable = AcpiDmTableInfoNfit4;
1278             break;
1279 
1280         case ACPI_NFIT_TYPE_DATA_REGION:
1281 
1282             InfoTable = AcpiDmTableInfoNfit5;
1283             break;
1284 
1285         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1286 
1287             /* Has a variable number of 64-bit addresses at the end */
1288 
1289             InfoTable = AcpiDmTableInfoNfit6;
1290             FieldOffset = sizeof (ACPI_NFIT_FLUSH_ADDRESS) - sizeof (UINT64);
1291             break;
1292 
1293         case ACPI_NFIT_TYPE_CAPABILITIES:    /* ACPI 6.0A */
1294 
1295             InfoTable = AcpiDmTableInfoNfit7;
1296             break;
1297 
1298         default:
1299             AcpiOsPrintf ("\n**** Unknown NFIT subtable type 0x%X\n",
1300                 Subtable->Type);
1301 
1302             /* Attempt to continue */
1303 
1304             if (!Subtable->Length)
1305             {
1306                 AcpiOsPrintf ("Invalid zero length subtable\n");
1307                 return;
1308             }
1309             goto NextSubtable;
1310         }
1311 
1312         AcpiOsPrintf ("\n");
1313         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1314             Subtable->Length, InfoTable);
1315         if (ACPI_FAILURE (Status))
1316         {
1317             return;
1318         }
1319 
1320         /* Per-subtable variable-length fields */
1321 
1322         switch (Subtable->Type)
1323         {
1324         case ACPI_NFIT_TYPE_INTERLEAVE:
1325 
1326             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable);
1327             for (i = 0; i < Interleave->LineCount; i++)
1328             {
1329                 Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
1330                     &Interleave->LineOffset[i],
1331                     sizeof (UINT32), AcpiDmTableInfoNfit2a);
1332                 if (ACPI_FAILURE (Status))
1333                 {
1334                     return;
1335                 }
1336 
1337                 FieldOffset += sizeof (UINT32);
1338             }
1339             break;
1340 
1341         case ACPI_NFIT_TYPE_SMBIOS:
1342 
1343             Length = Subtable->Length -
1344                 sizeof (ACPI_NFIT_SMBIOS) + sizeof (UINT8);
1345 
1346             if (Length)
1347             {
1348                 Status = AcpiDmDumpTable (Table->Length,
1349                     sizeof (ACPI_NFIT_SMBIOS) - sizeof (UINT8),
1350                     SmbiosInfo,
1351                     Length, AcpiDmTableInfoNfit3a);
1352                 if (ACPI_FAILURE (Status))
1353                 {
1354                     return;
1355                 }
1356             }
1357 
1358             break;
1359 
1360         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1361 
1362             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable);
1363             for (i = 0; i < Hint->HintCount; i++)
1364             {
1365                 Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
1366                     &Hint->HintAddress[i],
1367                     sizeof (UINT64), AcpiDmTableInfoNfit6a);
1368                 if (ACPI_FAILURE (Status))
1369                 {
1370                     return;
1371                 }
1372 
1373                 FieldOffset += sizeof (UINT64);
1374             }
1375             break;
1376 
1377         default:
1378             break;
1379         }
1380 
1381 NextSubtable:
1382         /* Point to next subtable */
1383 
1384         Offset += Subtable->Length;
1385         Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Subtable, Subtable->Length);
1386     }
1387 }
1388 
1389 
1390 /*******************************************************************************
1391  *
1392  * FUNCTION:    AcpiDmDumpPcct
1393  *
1394  * PARAMETERS:  Table               - A PCCT table
1395  *
1396  * RETURN:      None
1397  *
1398  * DESCRIPTION: Format the contents of a PCCT. This table type consists
1399  *              of an open-ended number of subtables.
1400  *
1401  ******************************************************************************/
1402 
1403 void
1404 AcpiDmDumpPcct (
1405     ACPI_TABLE_HEADER       *Table)
1406 {
1407     ACPI_STATUS             Status;
1408     ACPI_PCCT_SUBSPACE      *Subtable;
1409     ACPI_DMTABLE_INFO       *InfoTable;
1410     UINT32                  Length = Table->Length;
1411     UINT32                  Offset = sizeof (ACPI_TABLE_PCCT);
1412 
1413 
1414     /* Main table */
1415 
1416     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct);
1417     if (ACPI_FAILURE (Status))
1418     {
1419         return;
1420     }
1421 
1422     /* Subtables */
1423 
1424     Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
1425     while (Offset < Table->Length)
1426     {
1427         /* Common subtable header */
1428 
1429         AcpiOsPrintf ("\n");
1430         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1431             Subtable->Header.Length, AcpiDmTableInfoPcctHdr);
1432         if (ACPI_FAILURE (Status))
1433         {
1434             return;
1435         }
1436 
1437         switch (Subtable->Header.Type)
1438         {
1439         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1440 
1441             InfoTable = AcpiDmTableInfoPcct0;
1442             break;
1443 
1444         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1445 
1446             InfoTable = AcpiDmTableInfoPcct1;
1447             break;
1448 
1449         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
1450 
1451             InfoTable = AcpiDmTableInfoPcct2;
1452             break;
1453 
1454         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
1455 
1456             InfoTable = AcpiDmTableInfoPcct3;
1457             break;
1458 
1459         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
1460 
1461             InfoTable = AcpiDmTableInfoPcct4;
1462             break;
1463 
1464         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
1465 
1466             InfoTable = AcpiDmTableInfoPcct5;
1467             break;
1468 
1469         default:
1470 
1471             AcpiOsPrintf (
1472                 "\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n",
1473                 Subtable->Header.Type);
1474             return;
1475         }
1476 
1477         AcpiOsPrintf ("\n");
1478         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1479             Subtable->Header.Length, InfoTable);
1480         if (ACPI_FAILURE (Status))
1481         {
1482             return;
1483         }
1484 
1485         /* Point to next subtable */
1486 
1487         Offset += Subtable->Header.Length;
1488         Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Subtable,
1489             Subtable->Header.Length);
1490     }
1491 }
1492 
1493 
1494 /*******************************************************************************
1495  *
1496  * FUNCTION:    AcpiDmDumpPdtt
1497  *
1498  * PARAMETERS:  Table               - A PDTT table
1499  *
1500  * RETURN:      None
1501  *
1502  * DESCRIPTION: Format the contents of a Pdtt. This is a variable-length
1503  *              table that contains an open-ended number of IDs
1504  *              at the end of the table.
1505  *
1506  ******************************************************************************/
1507 
1508 void
1509 AcpiDmDumpPdtt (
1510     ACPI_TABLE_HEADER       *Table)
1511 {
1512     ACPI_STATUS             Status;
1513     ACPI_PDTT_CHANNEL       *Subtable;
1514     UINT32                  Length = Table->Length;
1515     UINT32                  Offset = sizeof (ACPI_TABLE_PDTT);
1516 
1517 
1518     /* Main table */
1519 
1520     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPdtt);
1521     if (ACPI_FAILURE (Status))
1522     {
1523         return;
1524     }
1525 
1526     /* Subtables. Currently there is only one type, but can be multiples */
1527 
1528     Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Table, Offset);
1529     while (Offset < Table->Length)
1530     {
1531         AcpiOsPrintf ("\n");
1532         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1533             sizeof (ACPI_PDTT_CHANNEL), AcpiDmTableInfoPdtt0);
1534         if (ACPI_FAILURE (Status))
1535         {
1536             return;
1537         }
1538 
1539         /* Point to next subtable */
1540 
1541         Offset += sizeof (ACPI_PDTT_CHANNEL);
1542         Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Subtable,
1543             sizeof (ACPI_PDTT_CHANNEL));
1544     }
1545 }
1546 
1547 
1548 /*******************************************************************************
1549  *
1550  * FUNCTION:    AcpiDmDumpPhat
1551  *
1552  * PARAMETERS:  Table               - A PHAT table
1553  *
1554  * RETURN:      None
1555  *
1556  * DESCRIPTION: Format the contents of a PHAT.
1557  *
1558  ******************************************************************************/
1559 
1560 void
1561 AcpiDmDumpPhat (
1562     ACPI_TABLE_HEADER       *Table)
1563 {
1564     ACPI_STATUS             Status;
1565     ACPI_DMTABLE_INFO       *InfoTable;
1566     ACPI_PHAT_HEADER        *Subtable;
1567     ACPI_PHAT_VERSION_DATA  *VersionData;
1568     UINT32                  RecordCount;
1569     UINT32                  Length = Table->Length;
1570     UINT32                  Offset = sizeof (ACPI_TABLE_PHAT);
1571     UINT32                  SubtableLength;
1572     UINT32                  PathLength;
1573     UINT32                  VendorLength;
1574 
1575 
1576     Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, sizeof (ACPI_TABLE_PHAT));
1577 
1578     while (Offset < Table->Length)
1579     {
1580         /* Common subtable header */
1581 
1582         AcpiOsPrintf ("\n");
1583         Status = AcpiDmDumpTable (Length, 0, Subtable,
1584             sizeof (ACPI_PHAT_HEADER), AcpiDmTableInfoPhatHdr);
1585         if (ACPI_FAILURE (Status))
1586         {
1587             return;
1588         }
1589 
1590         switch (Subtable->Type)
1591         {
1592         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1593 
1594             InfoTable = AcpiDmTableInfoPhat0;
1595             SubtableLength = sizeof (ACPI_PHAT_VERSION_DATA);
1596             break;
1597 
1598         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1599 
1600             InfoTable = AcpiDmTableInfoPhat1;
1601             SubtableLength = sizeof (ACPI_PHAT_HEALTH_DATA);
1602             break;
1603 
1604         default:
1605 
1606             AcpiOsPrintf ("\n**** Unknown PHAT subtable type 0x%X\n\n",
1607                 Subtable->Type);
1608 
1609             return;
1610         }
1611 
1612         Status = AcpiDmDumpTable (Length, 0, Subtable,
1613             SubtableLength, InfoTable);
1614         if (ACPI_FAILURE (Status))
1615         {
1616             return;
1617         }
1618 
1619         switch (Subtable->Type)
1620         {
1621         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1622 
1623             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, Subtable);
1624             RecordCount = VersionData->ElementCount;
1625             while (RecordCount)
1626             {
1627                 Status = AcpiDmDumpTable (Length, Offset,
1628                     ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_VERSION_DATA)),
1629                     sizeof (ACPI_PHAT_VERSION_ELEMENT), AcpiDmTableInfoPhat0a);
1630                 if (ACPI_FAILURE (Status))
1631                 {
1632                     return;
1633                 }
1634 
1635                 RecordCount--;
1636             }
1637 
1638             break;
1639 
1640         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1641 
1642             /* account for the null terminator */
1643 
1644             PathLength = strlen (ACPI_ADD_PTR (char, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA))) + 1;
1645             Status = AcpiDmDumpTable (Length, Offset,
1646                 ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA)),
1647                 PathLength, AcpiDmTableInfoPhat1a);
1648             if (ACPI_FAILURE (Status))
1649             {
1650                 return;
1651             }
1652 
1653             /* Get vendor data - data length is the remaining subtable length */
1654 
1655             VendorLength =
1656                 Subtable->Length - sizeof (ACPI_PHAT_HEALTH_DATA) - PathLength;
1657             Status = AcpiDmDumpTable (Length, 0,
1658                 ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA) + PathLength),
1659                 VendorLength, AcpiDmTableInfoPhat1b);
1660             if (ACPI_FAILURE (Status))
1661             {
1662                 return;
1663             }
1664             break;
1665 
1666         default:
1667 
1668             AcpiOsPrintf ("\n**** Unknown PHAT subtable type 0x%X\n\n",
1669                 Subtable->Type);
1670             return;
1671         }
1672 
1673         /* Next subtable */
1674 
1675         Offset += Subtable->Length;
1676         Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable,
1677             Subtable->Length);
1678     }
1679 }
1680 
1681 
1682 /*******************************************************************************
1683  *
1684  * FUNCTION:    AcpiDmDumpPmtt
1685  *
1686  * PARAMETERS:  Table               - A PMTT table
1687  *
1688  * RETURN:      None
1689  *
1690  * DESCRIPTION: Format the contents of a PMTT. This table type consists
1691  *              of an open-ended number of subtables.
1692  *
1693  ******************************************************************************/
1694 
1695 void
1696 AcpiDmDumpPmtt (
1697     ACPI_TABLE_HEADER       *Table)
1698 {
1699     ACPI_STATUS             Status;
1700     ACPI_PMTT_HEADER        *Subtable;
1701     UINT32                  Length = Table->Length;
1702     UINT32                  Offset = sizeof (ACPI_TABLE_PMTT);
1703 
1704 
1705     /* Main table */
1706 
1707     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt);
1708     if (ACPI_FAILURE (Status))
1709     {
1710         return;
1711     }
1712 
1713     /* Subtables */
1714 
1715     Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
1716     while (Offset < Table->Length)
1717     {
1718         /* Each of the types below contain the common subtable header */
1719 
1720         AcpiOsPrintf ("\n");
1721         switch (Subtable->Type)
1722         {
1723         case ACPI_PMTT_TYPE_SOCKET:
1724 
1725             Status = AcpiDmDumpTable (Length, Offset, Subtable,
1726                 Subtable->Length, AcpiDmTableInfoPmtt0);
1727             if (ACPI_FAILURE (Status))
1728             {
1729                 return;
1730             }
1731             break;
1732 
1733         case ACPI_PMTT_TYPE_CONTROLLER:
1734             Status = AcpiDmDumpTable (Length, Offset, Subtable,
1735                 Subtable->Length, AcpiDmTableInfoPmtt1);
1736             if (ACPI_FAILURE (Status))
1737             {
1738                 return;
1739             }
1740             break;
1741 
1742        case ACPI_PMTT_TYPE_DIMM:
1743             Status = AcpiDmDumpTable (Length, Offset, Subtable,
1744                 Subtable->Length, AcpiDmTableInfoPmtt2);
1745             if (ACPI_FAILURE (Status))
1746             {
1747                 return;
1748             }
1749             break;
1750 
1751         case ACPI_PMTT_TYPE_VENDOR:
1752             Status = AcpiDmDumpTable (Length, Offset, Subtable,
1753                 Subtable->Length, AcpiDmTableInfoPmttVendor);
1754             if (ACPI_FAILURE (Status))
1755             {
1756                 return;
1757             }
1758             break;
1759 
1760         default:
1761             AcpiOsPrintf (
1762                 "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
1763                 Subtable->Type);
1764             return;
1765         }
1766 
1767         /* Point to next subtable */
1768 
1769         Offset += Subtable->Length;
1770         Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
1771             Subtable, Subtable->Length);
1772     }
1773 }
1774 
1775 
1776 /*******************************************************************************
1777  *
1778  * FUNCTION:    AcpiDmDumpPptt
1779  *
1780  * PARAMETERS:  Table               - A PMTT table
1781  *
1782  * RETURN:      None
1783  *
1784  * DESCRIPTION: Format the contents of a PPTT. This table type consists
1785  *              of an open-ended number of subtables.
1786  *
1787  ******************************************************************************/
1788 
1789 void
1790 AcpiDmDumpPptt (
1791     ACPI_TABLE_HEADER       *Table)
1792 {
1793     ACPI_STATUS             Status;
1794     ACPI_SUBTABLE_HEADER    *Subtable;
1795     ACPI_PPTT_PROCESSOR     *PpttProcessor;
1796     UINT8                   Length;
1797     UINT8                   SubtableOffset;
1798     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
1799     ACPI_DMTABLE_INFO       *InfoTable;
1800     UINT32                  i;
1801 
1802 
1803     /* There is no main table (other than the standard ACPI header) */
1804 
1805     /* Subtables */
1806 
1807     Offset = sizeof (ACPI_TABLE_HEADER);
1808     while (Offset < Table->Length)
1809     {
1810         AcpiOsPrintf ("\n");
1811 
1812         /* Common subtable header */
1813 
1814         Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
1815         if (Subtable->Length < sizeof (ACPI_SUBTABLE_HEADER))
1816         {
1817             AcpiOsPrintf ("Invalid subtable length\n");
1818             return;
1819         }
1820         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1821             Subtable->Length, AcpiDmTableInfoPpttHdr);
1822         if (ACPI_FAILURE (Status))
1823         {
1824             return;
1825         }
1826 
1827         switch (Subtable->Type)
1828         {
1829         case ACPI_PPTT_TYPE_PROCESSOR:
1830 
1831             InfoTable = AcpiDmTableInfoPptt0;
1832             Length = sizeof (ACPI_PPTT_PROCESSOR);
1833             break;
1834 
1835         case ACPI_PPTT_TYPE_CACHE:
1836 
1837             InfoTable = AcpiDmTableInfoPptt1;
1838             Length = sizeof (ACPI_PPTT_CACHE);
1839             break;
1840 
1841         case ACPI_PPTT_TYPE_ID:
1842 
1843             InfoTable = AcpiDmTableInfoPptt2;
1844             Length = sizeof (ACPI_PPTT_ID);
1845             break;
1846 
1847         default:
1848 
1849             AcpiOsPrintf ("\n**** Unknown PPTT subtable type 0x%X\n\n",
1850                 Subtable->Type);
1851 
1852             /* Attempt to continue */
1853 
1854             goto NextSubtable;
1855         }
1856 
1857         if (Subtable->Length < Length)
1858         {
1859             AcpiOsPrintf ("Invalid subtable length\n");
1860             return;
1861         }
1862         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1863             Subtable->Length, InfoTable);
1864         if (ACPI_FAILURE (Status))
1865         {
1866             return;
1867         }
1868         SubtableOffset = Length;
1869 
1870         switch (Subtable->Type)
1871         {
1872         case ACPI_PPTT_TYPE_PROCESSOR:
1873 
1874             PpttProcessor = ACPI_CAST_PTR (ACPI_PPTT_PROCESSOR, Subtable);
1875 
1876             /* Dump SMBIOS handles */
1877 
1878             if ((UINT8)(Subtable->Length - SubtableOffset) <
1879                 (UINT8)(PpttProcessor->NumberOfPrivResources * 4))
1880             {
1881                 AcpiOsPrintf ("Invalid private resource number\n");
1882                 return;
1883             }
1884             for (i = 0; i < PpttProcessor->NumberOfPrivResources; i++)
1885             {
1886                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1887                     ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
1888                     4, AcpiDmTableInfoPptt0a);
1889                 if (ACPI_FAILURE (Status))
1890                 {
1891                     return;
1892                 }
1893 
1894                 SubtableOffset += 4;
1895             }
1896             break;
1897 
1898         case ACPI_PPTT_TYPE_CACHE:
1899 
1900             if (Table->Revision < 3)
1901             {
1902                 break;
1903             }
1904             Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1905                 ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
1906                 sizeof (ACPI_PPTT_CACHE_V1), AcpiDmTableInfoPptt1a);
1907             if (ACPI_FAILURE (Status))
1908             {
1909                 return;
1910             }
1911             break;
1912 
1913         default:
1914 
1915             break;
1916         }
1917 
1918 NextSubtable:
1919         /* Point to next subtable */
1920 
1921         Offset += Subtable->Length;
1922     }
1923 }
1924 
1925 
1926 /*******************************************************************************
1927  *
1928  * FUNCTION:    AcpiDmDumpS3pt
1929  *
1930  * PARAMETERS:  Table               - A S3PT table
1931  *
1932  * RETURN:      Length of the table
1933  *
1934  * DESCRIPTION: Format the contents of a S3PT
1935  *
1936  ******************************************************************************/
1937 
1938 UINT32
1939 AcpiDmDumpS3pt (
1940     ACPI_TABLE_HEADER       *Tables)
1941 {
1942     ACPI_STATUS             Status;
1943     UINT32                  Offset = sizeof (ACPI_TABLE_S3PT);
1944     ACPI_FPDT_HEADER        *Subtable;
1945     ACPI_DMTABLE_INFO       *InfoTable;
1946     ACPI_TABLE_S3PT         *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
1947 
1948 
1949     /* Main table */
1950 
1951     Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt);
1952     if (ACPI_FAILURE (Status))
1953     {
1954         return 0;
1955     }
1956 
1957     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, S3ptTable, Offset);
1958     while (Offset < S3ptTable->Length)
1959     {
1960         /* Common subtable header */
1961 
1962         AcpiOsPrintf ("\n");
1963         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
1964             Subtable->Length, AcpiDmTableInfoS3ptHdr);
1965         if (ACPI_FAILURE (Status))
1966         {
1967             return 0;
1968         }
1969 
1970         switch (Subtable->Type)
1971         {
1972         case ACPI_S3PT_TYPE_RESUME:
1973 
1974             InfoTable = AcpiDmTableInfoS3pt0;
1975             break;
1976 
1977         case ACPI_S3PT_TYPE_SUSPEND:
1978 
1979             InfoTable = AcpiDmTableInfoS3pt1;
1980             break;
1981 
1982         default:
1983 
1984             AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n",
1985                 Subtable->Type);
1986 
1987             /* Attempt to continue */
1988 
1989             if (!Subtable->Length)
1990             {
1991                 AcpiOsPrintf ("Invalid zero length subtable\n");
1992                 return 0;
1993             }
1994             goto NextSubtable;
1995         }
1996 
1997         AcpiOsPrintf ("\n");
1998         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
1999             Subtable->Length, InfoTable);
2000         if (ACPI_FAILURE (Status))
2001         {
2002             return 0;
2003         }
2004 
2005 NextSubtable:
2006         /* Point to next subtable */
2007 
2008         Offset += Subtable->Length;
2009         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable, Subtable->Length);
2010     }
2011 
2012     return (S3ptTable->Length);
2013 }
2014 
2015 
2016 /*******************************************************************************
2017  *
2018  * FUNCTION:    AcpiDmDumpSdev
2019  *
2020  * PARAMETERS:  Table               - A SDEV table
2021  *
2022  * RETURN:      None
2023  *
2024  * DESCRIPTION: Format the contents of a SDEV. This is a variable-length
2025  *              table that contains variable strings and vendor data.
2026  *
2027  ******************************************************************************/
2028 
2029 void
2030 AcpiDmDumpSdev (
2031     ACPI_TABLE_HEADER       *Table)
2032 {
2033     ACPI_STATUS                 Status;
2034     ACPI_SDEV_HEADER            *Subtable;
2035     ACPI_SDEV_PCIE              *Pcie;
2036     ACPI_SDEV_NAMESPACE         *Namesp;
2037     ACPI_DMTABLE_INFO           *InfoTable;
2038     ACPI_DMTABLE_INFO           *SecureComponentInfoTable;
2039     UINT32                      Length = Table->Length;
2040     UINT32                      Offset = sizeof (ACPI_TABLE_SDEV);
2041     UINT16                      PathOffset;
2042     UINT16                      PathLength;
2043     UINT16                      VendorDataOffset;
2044     UINT16                      VendorDataLength;
2045     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
2046     UINT32                      CurrentOffset = 0;
2047 
2048 
2049     /* Main table */
2050 
2051     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoSdev);
2052     if (ACPI_FAILURE (Status))
2053     {
2054         return;
2055     }
2056 
2057     /* Subtables */
2058 
2059     Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Table, Offset);
2060     while (Offset < Table->Length)
2061     {
2062         /* Common subtable header */
2063 
2064         AcpiOsPrintf ("\n");
2065         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2066             Subtable->Length, AcpiDmTableInfoSdevHdr);
2067         if (ACPI_FAILURE (Status))
2068         {
2069             return;
2070         }
2071 
2072         switch (Subtable->Type)
2073         {
2074         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2075 
2076             InfoTable = AcpiDmTableInfoSdev0;
2077             break;
2078 
2079         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2080 
2081             InfoTable = AcpiDmTableInfoSdev1;
2082             break;
2083 
2084         default:
2085             goto NextSubtable;
2086         }
2087 
2088         AcpiOsPrintf ("\n");
2089         Status = AcpiDmDumpTable (Table->Length, 0, Subtable,
2090             Subtable->Length, InfoTable);
2091         if (ACPI_FAILURE (Status))
2092         {
2093             return;
2094         }
2095 
2096         switch (Subtable->Type)
2097         {
2098         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2099 
2100             CurrentOffset = sizeof (ACPI_SDEV_NAMESPACE);
2101             if (Subtable->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
2102             {
2103                 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
2104                     ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_SDEV_NAMESPACE)));
2105 
2106                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2107                     ACPI_ADD_PTR(UINT8, Subtable, sizeof (ACPI_SDEV_NAMESPACE)),
2108                     sizeof (ACPI_SDEV_SECURE_COMPONENT), AcpiDmTableInfoSdev0b);
2109                 if (ACPI_FAILURE (Status))
2110                 {
2111                     return;
2112                 }
2113                 CurrentOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2114 
2115                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2116                     ACPI_ADD_PTR(UINT8, Subtable, SecureComponent->SecureComponentOffset),
2117                     sizeof (ACPI_SDEV_HEADER), AcpiDmTableInfoSdevSecCompHdr);
2118                 if (ACPI_FAILURE (Status))
2119                 {
2120                     return;
2121                 }
2122                 CurrentOffset += sizeof (ACPI_SDEV_HEADER);
2123 
2124                 switch (Subtable->Type)
2125                 {
2126                 case ACPI_SDEV_TYPE_ID_COMPONENT:
2127 
2128                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
2129                     break;
2130 
2131                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
2132 
2133                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
2134                     break;
2135 
2136                 default:
2137                     goto NextSubtable;
2138                 }
2139 
2140                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2141                     ACPI_ADD_PTR(UINT8, Subtable, SecureComponent->SecureComponentOffset),
2142                     SecureComponent->SecureComponentLength, SecureComponentInfoTable);
2143                 CurrentOffset += SecureComponent->SecureComponentLength;
2144             }
2145 
2146             /* Dump the PCIe device ID(s) */
2147 
2148             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable);
2149             PathOffset = Namesp->DeviceIdOffset;
2150             PathLength = Namesp->DeviceIdLength;
2151 
2152             if (PathLength)
2153             {
2154                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2155                     ACPI_ADD_PTR (UINT8, Namesp, PathOffset),
2156                     PathLength, AcpiDmTableInfoSdev0a);
2157                 if (ACPI_FAILURE (Status))
2158                 {
2159                     return;
2160                 }
2161                 CurrentOffset += PathLength;
2162             }
2163 
2164             /* Dump the vendor-specific data */
2165 
2166             VendorDataLength =
2167                 Namesp->VendorDataLength;
2168             VendorDataOffset =
2169                 Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2170 
2171             if (VendorDataLength)
2172             {
2173                 Status = AcpiDmDumpTable (Table->Length, 0,
2174                     ACPI_ADD_PTR (UINT8, Namesp, VendorDataOffset),
2175                     VendorDataLength, AcpiDmTableInfoSdev1b);
2176                 if (ACPI_FAILURE (Status))
2177                 {
2178                     return;
2179                 }
2180             }
2181             break;
2182 
2183         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2184 
2185             /* PCI path substructures */
2186 
2187             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable);
2188             PathOffset = Pcie->PathOffset;
2189             PathLength = Pcie->PathLength;
2190 
2191             while (PathLength)
2192             {
2193                 Status = AcpiDmDumpTable (Table->Length,
2194                     PathOffset + Offset,
2195                     ACPI_ADD_PTR (UINT8, Pcie, PathOffset),
2196                     sizeof (ACPI_SDEV_PCIE_PATH), AcpiDmTableInfoSdev1a);
2197                 if (ACPI_FAILURE (Status))
2198                 {
2199                     return;
2200                 }
2201 
2202                 PathOffset += sizeof (ACPI_SDEV_PCIE_PATH);
2203                 PathLength -= sizeof (ACPI_SDEV_PCIE_PATH);
2204             }
2205 
2206             /* VendorData */
2207 
2208             VendorDataLength = Pcie->VendorDataLength;
2209             VendorDataOffset = Pcie->PathOffset + Pcie->PathLength;
2210 
2211             if (VendorDataLength)
2212             {
2213                 Status = AcpiDmDumpTable (Table->Length, 0,
2214                     ACPI_ADD_PTR (UINT8, Pcie, VendorDataOffset),
2215                     VendorDataLength, AcpiDmTableInfoSdev1b);
2216                 if (ACPI_FAILURE (Status))
2217                 {
2218                     return;
2219                 }
2220             }
2221             break;
2222 
2223         default:
2224             goto NextSubtable;
2225         }
2226 
2227 NextSubtable:
2228         /* Point to next subtable */
2229 
2230         Offset += Subtable->Length;
2231         Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Subtable,
2232             Subtable->Length);
2233     }
2234 }
2235