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