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