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