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