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