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