xref: /freebsd/sys/contrib/dev/acpica/common/dmtbdump1.c (revision ab71bbb75a92412f6327ff152ebe638568e9021c)
1 /******************************************************************************
2  *
3  * Module Name: dmtbdump1 - 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 - 2022, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/include/acpi.h>
153 #include <contrib/dev/acpica/include/accommon.h>
154 #include <contrib/dev/acpica/include/acdisasm.h>
155 #include <contrib/dev/acpica/include/actables.h>
156 
157 /* This module used for application-level code only */
158 
159 #define _COMPONENT          ACPI_CA_DISASSEMBLER
160         ACPI_MODULE_NAME    ("dmtbdump1")
161 
162 
163 /*******************************************************************************
164  *
165  * FUNCTION:    AcpiDmDumpAest
166  *
167  * PARAMETERS:  Table               - A AEST table
168  *
169  * RETURN:      None
170  *
171  * DESCRIPTION: Format the contents of a AEST table
172  *
173  * NOTE: Assumes the following table structure:
174  *      For all AEST Error Nodes:
175  *          1) An AEST Error Node, followed immediately by:
176  *          2) Any node-specific data
177  *          3) An Interface Structure (one)
178  *          4) A list (array) of Interrupt Structures
179  *
180  * AEST - ARM Error Source table. Conforms to:
181  * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020
182  *
183  ******************************************************************************/
184 
185 void
186 AcpiDmDumpAest (
187     ACPI_TABLE_HEADER       *Table)
188 {
189     ACPI_STATUS             Status;
190     UINT32                  Offset = sizeof (ACPI_TABLE_HEADER);
191     ACPI_AEST_HEADER        *Subtable;
192     ACPI_AEST_HEADER        *NodeHeader;
193     ACPI_AEST_PROCESSOR     *ProcessorSubtable;
194     ACPI_DMTABLE_INFO       *InfoTable;
195     ACPI_SIZE               Length;
196     UINT8                   Type;
197 
198 
199     /* Very small, generic main table. AEST consists of mostly subtables */
200 
201     while (Offset < Table->Length)
202     {
203         NodeHeader = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
204 
205         /* Dump the common error node (subtable) header */
206 
207         Status = AcpiDmDumpTable (Table->Length, Offset, NodeHeader,
208             NodeHeader->Length, AcpiDmTableInfoAestHdr);
209         if (ACPI_FAILURE (Status))
210         {
211             return;
212         }
213 
214         Type = NodeHeader->Type;
215 
216         /* Setup the node-specific subtable based on the header Type field */
217 
218         switch (Type)
219         {
220         case ACPI_AEST_PROCESSOR_ERROR_NODE:
221             InfoTable = AcpiDmTableInfoAestProcError;
222             Length = sizeof (ACPI_AEST_PROCESSOR);
223             break;
224 
225         case ACPI_AEST_MEMORY_ERROR_NODE:
226             InfoTable = AcpiDmTableInfoAestMemError;
227             Length = sizeof (ACPI_AEST_MEMORY);
228             break;
229 
230         case ACPI_AEST_SMMU_ERROR_NODE:
231             InfoTable = AcpiDmTableInfoAestSmmuError;
232             Length = sizeof (ACPI_AEST_SMMU);
233             break;
234 
235         case ACPI_AEST_VENDOR_ERROR_NODE:
236             InfoTable = AcpiDmTableInfoAestVendorError;
237             Length = sizeof (ACPI_AEST_VENDOR);
238             break;
239 
240         case ACPI_AEST_GIC_ERROR_NODE:
241             InfoTable = AcpiDmTableInfoAestGicError;
242             Length = sizeof (ACPI_AEST_GIC);
243             break;
244 
245         /* Error case below */
246         default:
247 
248             AcpiOsPrintf ("\n**** Unknown AEST Error Subtable type 0x%X\n",
249                 Type);
250             return;
251         }
252 
253         /* Point past the common header (to the node-specific data) */
254 
255         Offset += sizeof (ACPI_AEST_HEADER);
256         Subtable = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
257         AcpiOsPrintf ("\n");
258 
259         /* Dump the node-specific subtable */
260 
261         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, Length,
262             InfoTable);
263         if (ACPI_FAILURE (Status))
264         {
265             return;
266         }
267         AcpiOsPrintf ("\n");
268 
269         if (Type == ACPI_AEST_PROCESSOR_ERROR_NODE)
270         {
271             /*
272              * Special handling for PROCESSOR_ERROR_NODE subtables
273              * (to handle the Resource Substructure via the ResourceType
274              * field).
275              */
276 
277             /* Point past the node-specific data */
278 
279             Offset += Length;
280             ProcessorSubtable = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR, Subtable);
281 
282             switch (ProcessorSubtable->ResourceType)
283             {
284             /* Setup the Resource Substructure subtable */
285 
286             case ACPI_AEST_CACHE_RESOURCE:
287                 InfoTable = AcpiDmTableInfoAestCacheRsrc;
288                 Length = sizeof (ACPI_AEST_PROCESSOR_CACHE);
289                 break;
290 
291             case ACPI_AEST_TLB_RESOURCE:
292                 InfoTable = AcpiDmTableInfoAestTlbRsrc;
293                 Length = sizeof (ACPI_AEST_PROCESSOR_TLB);
294                 break;
295 
296             case ACPI_AEST_GENERIC_RESOURCE:
297                 InfoTable = AcpiDmTableInfoAestGenRsrc;
298                 Length = sizeof (ACPI_AEST_PROCESSOR_GENERIC);
299                 break;
300 
301             /* Error case below */
302             default:
303                 AcpiOsPrintf ("\n**** Unknown AEST Processor Resource type 0x%X\n",
304                     ProcessorSubtable->ResourceType);
305                 return;
306             }
307 
308             ProcessorSubtable = ACPI_ADD_PTR (ACPI_AEST_PROCESSOR, Table,
309                 Offset);
310 
311             /* Dump the resource substructure subtable */
312 
313             Status = AcpiDmDumpTable (Table->Length, Offset, ProcessorSubtable,
314                 Length, InfoTable);
315             if (ACPI_FAILURE (Status))
316             {
317                 return;
318             }
319 
320             AcpiOsPrintf ("\n");
321         }
322 
323         /* Point past the resource substructure or the node-specific data */
324 
325         Offset += Length;
326 
327         /* Dump the interface structure, required to be present */
328 
329         Subtable = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
330         if (Subtable->Type >= ACPI_AEST_XFACE_RESERVED)
331         {
332             AcpiOsPrintf ("\n**** Unknown AEST Node Interface type 0x%X\n",
333                 Subtable->Type);
334             return;
335         }
336 
337         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
338             sizeof (ACPI_AEST_NODE_INTERFACE), AcpiDmTableInfoAestXface);
339         if (ACPI_FAILURE (Status))
340         {
341             return;
342         }
343 
344         /* Point past the interface structure */
345 
346         AcpiOsPrintf ("\n");
347         Offset += sizeof (ACPI_AEST_NODE_INTERFACE);
348 
349         /* Dump the entire interrupt structure array, if present */
350 
351         if (NodeHeader->NodeInterruptOffset)
352         {
353             Length = NodeHeader->NodeInterruptCount;
354             Subtable = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
355 
356             while (Length)
357             {
358                 /* Dump the interrupt structure */
359 
360                 Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
361                     sizeof (ACPI_AEST_NODE_INTERRUPT),
362                     AcpiDmTableInfoAestXrupt);
363                 if (ACPI_FAILURE (Status))
364                 {
365                     return;
366                 }
367 
368                 /* Point to the next interrupt structure */
369 
370                 Offset += sizeof (ACPI_AEST_NODE_INTERRUPT);
371                 Subtable = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
372                 Length--;
373                 AcpiOsPrintf ("\n");
374             }
375         }
376     }
377 }
378 
379 /*******************************************************************************
380  *
381  * FUNCTION:    AcpiDmDumpApmt
382  *
383  * PARAMETERS:  Table               - A APMT table
384  *
385  * RETURN:      None
386  *
387  * DESCRIPTION: Format the contents of a APMT. This table type consists
388  *              of an open-ended number of subtables.
389  *
390  *
391  * APMT - ARM Performance Monitoring Unit table. Conforms to:
392  * ARM Performance Monitoring Unit Architecture 1.0 Platform Design Document
393  * ARM DEN0117 v1.0 November 25, 2021
394  *
395  ******************************************************************************/
396 
397 void
398 AcpiDmDumpApmt (
399     ACPI_TABLE_HEADER       *Table)
400 {
401     ACPI_STATUS              Status;
402     ACPI_APMT_NODE           *Subtable;
403     UINT32                   Length = Table->Length;
404     UINT32                   Offset = sizeof (ACPI_TABLE_APMT);
405     UINT32                   NodeNum = 0;
406 
407     /* There is no main table (other than the standard ACPI header) */
408 
409     /* Subtables */
410 
411     Subtable = ACPI_ADD_PTR (ACPI_APMT_NODE, Table, Offset);
412     while (Offset < Table->Length)
413     {
414         AcpiOsPrintf ("\n");
415 
416         if (Subtable->Type >= ACPI_APMT_NODE_TYPE_COUNT)
417         {
418             AcpiOsPrintf ("\n**** Unknown APMT subtable type 0x%X\n",
419                 Subtable->Type);
420             return;
421         }
422 
423         AcpiOsPrintf ("/* APMT Node-%u */\n", NodeNum++);
424 
425         Status = AcpiDmDumpTable (Length, Offset, Subtable,
426             Subtable->Length, AcpiDmTableInfoApmtNode);
427         if (ACPI_FAILURE (Status))
428         {
429             return;
430         }
431 
432         /* Point to next subtable */
433 
434         Offset += Subtable->Length;
435         Subtable = ACPI_ADD_PTR (ACPI_APMT_NODE, Subtable,
436             Subtable->Length);
437         AcpiOsPrintf ("\n");
438     }
439 }
440 
441 
442 /*******************************************************************************
443  *
444  * FUNCTION:    AcpiDmDumpAsf
445  *
446  * PARAMETERS:  Table               - A ASF table
447  *
448  * RETURN:      None
449  *
450  * DESCRIPTION: Format the contents of a ASF table
451  *
452  ******************************************************************************/
453 
454 void
455 AcpiDmDumpAsf (
456     ACPI_TABLE_HEADER       *Table)
457 {
458     ACPI_STATUS             Status;
459     UINT32                  Offset = sizeof (ACPI_TABLE_HEADER);
460     ACPI_ASF_INFO           *Subtable;
461     ACPI_DMTABLE_INFO       *InfoTable;
462     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
463     UINT8                   *DataTable = NULL;
464     UINT32                  DataCount = 0;
465     UINT32                  DataLength = 0;
466     UINT32                  DataOffset = 0;
467     UINT32                  i;
468     UINT8                   Type;
469 
470 
471     /* No main table, only subtables */
472 
473     Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
474     while (Offset < Table->Length)
475     {
476         /* Common subtable header */
477 
478         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
479             Subtable->Header.Length, AcpiDmTableInfoAsfHdr);
480         if (ACPI_FAILURE (Status))
481         {
482             return;
483         }
484 
485         /* The actual type is the lower 7 bits of Type */
486 
487         Type = (UINT8) (Subtable->Header.Type & 0x7F);
488 
489         switch (Type)
490         {
491         case ACPI_ASF_TYPE_INFO:
492 
493             InfoTable = AcpiDmTableInfoAsf0;
494             break;
495 
496         case ACPI_ASF_TYPE_ALERT:
497 
498             InfoTable = AcpiDmTableInfoAsf1;
499             DataInfoTable = AcpiDmTableInfoAsf1a;
500             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ALERT));
501             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->Alerts;
502             DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->DataLength;
503             DataOffset = Offset + sizeof (ACPI_ASF_ALERT);
504             break;
505 
506         case ACPI_ASF_TYPE_CONTROL:
507 
508             InfoTable = AcpiDmTableInfoAsf2;
509             DataInfoTable = AcpiDmTableInfoAsf2a;
510             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_REMOTE));
511             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->Controls;
512             DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->DataLength;
513             DataOffset = Offset + sizeof (ACPI_ASF_REMOTE);
514             break;
515 
516         case ACPI_ASF_TYPE_BOOT:
517 
518             InfoTable = AcpiDmTableInfoAsf3;
519             break;
520 
521         case ACPI_ASF_TYPE_ADDRESS:
522 
523             InfoTable = AcpiDmTableInfoAsf4;
524             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ADDRESS));
525             DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, Subtable)->Devices;
526             DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS);
527             break;
528 
529         default:
530 
531             AcpiOsPrintf ("\n**** Unknown ASF subtable type 0x%X\n",
532                 Subtable->Header.Type);
533             return;
534         }
535 
536         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
537             Subtable->Header.Length, InfoTable);
538         if (ACPI_FAILURE (Status))
539         {
540             return;
541         }
542 
543         /* Dump variable-length extra data */
544 
545         switch (Type)
546         {
547         case ACPI_ASF_TYPE_ALERT:
548         case ACPI_ASF_TYPE_CONTROL:
549 
550             for (i = 0; i < DataCount; i++)
551             {
552                 AcpiOsPrintf ("\n");
553                 Status = AcpiDmDumpTable (Table->Length, DataOffset,
554                     DataTable, DataLength, DataInfoTable);
555                 if (ACPI_FAILURE (Status))
556                 {
557                     return;
558                 }
559 
560                 DataTable = ACPI_ADD_PTR (UINT8, DataTable, DataLength);
561                 DataOffset += DataLength;
562             }
563             break;
564 
565         case ACPI_ASF_TYPE_ADDRESS:
566 
567             for (i = 0; i < DataLength; i++)
568             {
569                 if (!(i % 16))
570                 {
571                     AcpiDmLineHeader (DataOffset, 1, "Addresses");
572                 }
573 
574                 AcpiOsPrintf ("%2.2X ", *DataTable);
575                 DataTable++;
576                 DataOffset++;
577 
578                 if (DataOffset > Table->Length)
579                 {
580                     AcpiOsPrintf (
581                         "**** ACPI table terminates in the middle of a "
582                         "data structure! (ASF! table)\n");
583                     return;
584                 }
585             }
586 
587             AcpiOsPrintf ("\n");
588             break;
589 
590         default:
591 
592             break;
593         }
594 
595         AcpiOsPrintf ("\n");
596 
597         /* Point to next subtable */
598 
599         if (!Subtable->Header.Length)
600         {
601             AcpiOsPrintf ("Invalid zero subtable header length\n");
602             return;
603         }
604 
605         Offset += Subtable->Header.Length;
606         Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Subtable,
607             Subtable->Header.Length);
608     }
609 }
610 
611 /*******************************************************************************
612  *
613  * FUNCTION:    AcpiDmDumpCedt
614  *
615  * PARAMETERS:  Table               - A CEDT table
616  *
617  * RETURN:      None
618  *
619  * DESCRIPTION: Format the contents of a CEDT. This table type consists
620  *              of an open-ended number of subtables.
621  *
622  ******************************************************************************/
623 
624 void
625 AcpiDmDumpCedt (
626     ACPI_TABLE_HEADER       *Table)
627 {
628     ACPI_STATUS             Status;
629     ACPI_CEDT_HEADER        *Subtable;
630     UINT32                  Length = Table->Length;
631     UINT32                  Offset = sizeof (ACPI_TABLE_CEDT);
632 
633 
634     /* There is no main table (other than the standard ACPI header) */
635 
636     Subtable = ACPI_ADD_PTR (ACPI_CEDT_HEADER, Table, Offset);
637     while (Offset < Table->Length)
638     {
639         /* Common subtable header */
640 
641         AcpiOsPrintf ("\n");
642         Status = AcpiDmDumpTable (Length, Offset, Subtable,
643             Subtable->Length, AcpiDmTableInfoCedtHdr);
644         if (ACPI_FAILURE (Status))
645         {
646             return;
647         }
648 
649         switch (Subtable->Type)
650         {
651         case ACPI_CEDT_TYPE_CHBS:
652             Status = AcpiDmDumpTable (Length, Offset, Subtable,
653                 Subtable->Length, AcpiDmTableInfoCedt0);
654             if (ACPI_FAILURE (Status)) {
655                 return;
656             }
657             break;
658 
659         case ACPI_CEDT_TYPE_CFMWS: {
660             ACPI_CEDT_CFMWS *ptr = (ACPI_CEDT_CFMWS *) Subtable;
661             unsigned int i, max = 0x01 << (ptr->InterleaveWays);
662 
663             /* print out table with first "Interleave target" */
664 
665             Status = AcpiDmDumpTable (Length, Offset, Subtable,
666                 Subtable->Length, AcpiDmTableInfoCedt1);
667             if (ACPI_FAILURE (Status)) {
668                 return;
669             }
670 
671             /* Now, print out any interleave targets beyond the first. */
672 
673             for (i = 1; i < max; i++) {
674                 unsigned int loc_offset = Offset + (i * 4) + ACPI_OFFSET(ACPI_CEDT_CFMWS, InterleaveTargets);
675                 unsigned int *trg = &(ptr->InterleaveTargets[i]);
676                 Status = AcpiDmDumpTable (Length, loc_offset, trg,
677                         Subtable->Length, AcpiDmTableInfoCedt1_te);
678                 if (ACPI_FAILURE (Status)) {
679                     return;
680                 }
681             }
682             break;
683         }
684 
685         default:
686             AcpiOsPrintf ("\n**** Unknown CEDT subtable type 0x%X\n\n",
687                 Subtable->Type);
688 
689             /* Attempt to continue */
690             if (!Subtable->Length)
691             {
692                 AcpiOsPrintf ("Invalid zero length subtable\n");
693                 return;
694             }
695         }
696 
697         /* Point to next subtable */
698         Offset += Subtable->Length;
699         Subtable = ACPI_ADD_PTR (ACPI_CEDT_HEADER, Subtable,
700             Subtable->Length);
701     }
702 }
703 
704 /*******************************************************************************
705  *
706  * FUNCTION:    AcpiDmDumpCpep
707  *
708  * PARAMETERS:  Table               - A CPEP table
709  *
710  * RETURN:      None
711  *
712  * DESCRIPTION: Format the contents of a CPEP. This table type consists
713  *              of an open-ended number of subtables.
714  *
715  ******************************************************************************/
716 
717 void
718 AcpiDmDumpCpep (
719     ACPI_TABLE_HEADER       *Table)
720 {
721     ACPI_STATUS             Status;
722     ACPI_CPEP_POLLING       *Subtable;
723     UINT32                  Length = Table->Length;
724     UINT32                  Offset = sizeof (ACPI_TABLE_CPEP);
725 
726 
727     /* Main table */
728 
729     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoCpep);
730     if (ACPI_FAILURE (Status))
731     {
732         return;
733     }
734 
735     /* Subtables */
736 
737     Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
738     while (Offset < Table->Length)
739     {
740         AcpiOsPrintf ("\n");
741         Status = AcpiDmDumpTable (Length, Offset, Subtable,
742             Subtable->Header.Length, AcpiDmTableInfoCpep0);
743         if (ACPI_FAILURE (Status))
744         {
745             return;
746         }
747 
748         /* Point to next subtable */
749 
750         Offset += Subtable->Header.Length;
751         Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Subtable,
752             Subtable->Header.Length);
753     }
754 }
755 
756 
757 /*******************************************************************************
758  *
759  * FUNCTION:    AcpiDmDumpCsrt
760  *
761  * PARAMETERS:  Table               - A CSRT table
762  *
763  * RETURN:      None
764  *
765  * DESCRIPTION: Format the contents of a CSRT. This table type consists
766  *              of an open-ended number of subtables.
767  *
768  ******************************************************************************/
769 
770 void
771 AcpiDmDumpCsrt (
772     ACPI_TABLE_HEADER       *Table)
773 {
774     ACPI_STATUS             Status;
775     ACPI_CSRT_GROUP         *Subtable;
776     ACPI_CSRT_SHARED_INFO   *SharedInfoTable;
777     ACPI_CSRT_DESCRIPTOR    *SubSubtable;
778     UINT32                  Length = Table->Length;
779     UINT32                  Offset = sizeof (ACPI_TABLE_CSRT);
780     UINT32                  SubOffset;
781     UINT32                  SubSubOffset;
782     UINT32                  InfoLength;
783 
784 
785     /* The main table only contains the ACPI header, thus already handled */
786 
787     /* Subtables (Resource Groups) */
788 
789     Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset);
790     while (Offset < Table->Length)
791     {
792         /* Resource group subtable */
793 
794         AcpiOsPrintf ("\n");
795         Status = AcpiDmDumpTable (Length, Offset, Subtable,
796             Subtable->Length, AcpiDmTableInfoCsrt0);
797         if (ACPI_FAILURE (Status))
798         {
799             return;
800         }
801 
802         /* Shared info subtable (One per resource group) */
803 
804         SubOffset = sizeof (ACPI_CSRT_GROUP);
805         SharedInfoTable = ACPI_ADD_PTR (ACPI_CSRT_SHARED_INFO, Table,
806             Offset + SubOffset);
807 
808         AcpiOsPrintf ("\n");
809         Status = AcpiDmDumpTable (Length, Offset + SubOffset, SharedInfoTable,
810             sizeof (ACPI_CSRT_SHARED_INFO), AcpiDmTableInfoCsrt1);
811         if (ACPI_FAILURE (Status))
812         {
813             return;
814         }
815 
816         SubOffset += Subtable->SharedInfoLength;
817 
818         /* Sub-Subtables (Resource Descriptors) */
819 
820         SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table,
821             Offset + SubOffset);
822 
823         while ((SubOffset < Subtable->Length) &&
824               ((Offset + SubOffset) < Table->Length))
825         {
826             AcpiOsPrintf ("\n");
827             Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubtable,
828                 SubSubtable->Length, AcpiDmTableInfoCsrt2);
829             if (ACPI_FAILURE (Status))
830             {
831                 return;
832             }
833 
834             SubSubOffset = sizeof (ACPI_CSRT_DESCRIPTOR);
835 
836             /* Resource-specific info buffer */
837 
838             InfoLength = SubSubtable->Length - SubSubOffset;
839             if (InfoLength)
840             {
841                 Status = AcpiDmDumpTable (Length,
842                     Offset + SubOffset + SubSubOffset, Table,
843                     InfoLength, AcpiDmTableInfoCsrt2a);
844                 if (ACPI_FAILURE (Status))
845                 {
846                     return;
847                 }
848             }
849 
850             /* Point to next sub-subtable */
851 
852             SubOffset += SubSubtable->Length;
853             SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubtable,
854                 SubSubtable->Length);
855         }
856 
857         /* Point to next subtable */
858 
859         Offset += Subtable->Length;
860         Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Subtable,
861             Subtable->Length);
862     }
863 }
864 
865 
866 /*******************************************************************************
867  *
868  * FUNCTION:    AcpiDmDumpDbg2
869  *
870  * PARAMETERS:  Table               - A DBG2 table
871  *
872  * RETURN:      None
873  *
874  * DESCRIPTION: Format the contents of a DBG2. This table type consists
875  *              of an open-ended number of subtables.
876  *
877  ******************************************************************************/
878 
879 void
880 AcpiDmDumpDbg2 (
881     ACPI_TABLE_HEADER       *Table)
882 {
883     ACPI_STATUS             Status;
884     ACPI_DBG2_DEVICE        *Subtable;
885     UINT32                  Length = Table->Length;
886     UINT32                  Offset = sizeof (ACPI_TABLE_DBG2);
887     UINT32                  i;
888     UINT32                  ArrayOffset;
889     UINT32                  AbsoluteOffset;
890     UINT8                   *Array;
891 
892 
893     /* Main table */
894 
895     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDbg2);
896     if (ACPI_FAILURE (Status))
897     {
898         return;
899     }
900 
901     /* Subtables */
902 
903     Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
904     while (Offset < Table->Length)
905     {
906         AcpiOsPrintf ("\n");
907         Status = AcpiDmDumpTable (Length, Offset, Subtable,
908             Subtable->Length, AcpiDmTableInfoDbg2Device);
909         if (ACPI_FAILURE (Status))
910         {
911             return;
912         }
913 
914         /* Dump the BaseAddress array */
915 
916         for (i = 0; i < Subtable->RegisterCount; i++)
917         {
918             ArrayOffset = Subtable->BaseAddressOffset +
919                 (sizeof (ACPI_GENERIC_ADDRESS) * i);
920             AbsoluteOffset = Offset + ArrayOffset;
921             Array = (UINT8 *) Subtable + ArrayOffset;
922 
923             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
924                 Subtable->Length, AcpiDmTableInfoDbg2Addr);
925             if (ACPI_FAILURE (Status))
926             {
927                 return;
928             }
929         }
930 
931         /* Dump the AddressSize array */
932 
933         for (i = 0; i < Subtable->RegisterCount; i++)
934         {
935             ArrayOffset = Subtable->AddressSizeOffset +
936                 (sizeof (UINT32) * i);
937             AbsoluteOffset = Offset + ArrayOffset;
938             Array = (UINT8 *) Subtable + ArrayOffset;
939 
940             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
941                 Subtable->Length, AcpiDmTableInfoDbg2Size);
942             if (ACPI_FAILURE (Status))
943             {
944                 return;
945             }
946         }
947 
948         /* Dump the Namestring (required) */
949 
950         AcpiOsPrintf ("\n");
951         ArrayOffset = Subtable->NamepathOffset;
952         AbsoluteOffset = Offset + ArrayOffset;
953         Array = (UINT8 *) Subtable + ArrayOffset;
954 
955         Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
956             Subtable->Length, AcpiDmTableInfoDbg2Name);
957         if (ACPI_FAILURE (Status))
958         {
959             return;
960         }
961 
962         /* Dump the OemData (optional) */
963 
964         if (Subtable->OemDataOffset)
965         {
966             Status = AcpiDmDumpTable (Length, Offset + Subtable->OemDataOffset,
967                 Table, Subtable->OemDataLength,
968                 AcpiDmTableInfoDbg2OemData);
969             if (ACPI_FAILURE (Status))
970             {
971                 return;
972             }
973         }
974 
975         /* Point to next subtable */
976 
977         Offset += Subtable->Length;
978         Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Subtable,
979             Subtable->Length);
980     }
981 }
982 
983 
984 /*******************************************************************************
985  *
986  * FUNCTION:    AcpiDmDumpDmar
987  *
988  * PARAMETERS:  Table               - A DMAR table
989  *
990  * RETURN:      None
991  *
992  * DESCRIPTION: Format the contents of a DMAR. This table type consists
993  *              of an open-ended number of subtables.
994  *
995  ******************************************************************************/
996 
997 void
998 AcpiDmDumpDmar (
999     ACPI_TABLE_HEADER       *Table)
1000 {
1001     ACPI_STATUS             Status;
1002     ACPI_DMAR_HEADER        *Subtable;
1003     UINT32                  Length = Table->Length;
1004     UINT32                  Offset = sizeof (ACPI_TABLE_DMAR);
1005     ACPI_DMTABLE_INFO       *InfoTable;
1006     ACPI_DMAR_DEVICE_SCOPE  *ScopeTable;
1007     UINT32                  ScopeOffset;
1008     UINT8                   *PciPath;
1009     UINT32                  PathOffset;
1010 
1011 
1012     /* Main table */
1013 
1014     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar);
1015     if (ACPI_FAILURE (Status))
1016     {
1017         return;
1018     }
1019 
1020     /* Subtables */
1021 
1022     Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
1023     while (Offset < Table->Length)
1024     {
1025         /* Common subtable header */
1026 
1027         AcpiOsPrintf ("\n");
1028         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1029             Subtable->Length, AcpiDmTableInfoDmarHdr);
1030         if (ACPI_FAILURE (Status))
1031         {
1032             return;
1033         }
1034 
1035         AcpiOsPrintf ("\n");
1036 
1037         switch (Subtable->Type)
1038         {
1039         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1040 
1041             InfoTable = AcpiDmTableInfoDmar0;
1042             ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT);
1043             break;
1044 
1045         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1046 
1047             InfoTable = AcpiDmTableInfoDmar1;
1048             ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY);
1049             break;
1050 
1051         case ACPI_DMAR_TYPE_ROOT_ATS:
1052 
1053             InfoTable = AcpiDmTableInfoDmar2;
1054             ScopeOffset = sizeof (ACPI_DMAR_ATSR);
1055             break;
1056 
1057         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1058 
1059             InfoTable = AcpiDmTableInfoDmar3;
1060             ScopeOffset = sizeof (ACPI_DMAR_RHSA);
1061             break;
1062 
1063         case ACPI_DMAR_TYPE_NAMESPACE:
1064 
1065             InfoTable = AcpiDmTableInfoDmar4;
1066             ScopeOffset = sizeof (ACPI_DMAR_ANDD);
1067             break;
1068 
1069         case ACPI_DMAR_TYPE_SATC:
1070 
1071             InfoTable = AcpiDmTableInfoDmar5;
1072             ScopeOffset = sizeof (ACPI_DMAR_SATC);
1073             break;
1074 
1075         default:
1076 
1077             AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n",
1078                 Subtable->Type);
1079             return;
1080         }
1081 
1082         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1083             Subtable->Length, InfoTable);
1084         if (ACPI_FAILURE (Status))
1085         {
1086             return;
1087         }
1088 
1089         /*
1090          * Dump the optional device scope entries
1091          */
1092         if ((Subtable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
1093             (Subtable->Type == ACPI_DMAR_TYPE_NAMESPACE))
1094         {
1095             /* These types do not support device scopes */
1096 
1097             goto NextSubtable;
1098         }
1099 
1100         ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable, ScopeOffset);
1101         while (ScopeOffset < Subtable->Length)
1102         {
1103             AcpiOsPrintf ("\n");
1104             Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
1105                 ScopeTable->Length, AcpiDmTableInfoDmarScope);
1106             if (ACPI_FAILURE (Status))
1107             {
1108                 return;
1109             }
1110             AcpiOsPrintf ("\n");
1111 
1112             /* Dump the PCI Path entries for this device scope */
1113 
1114             PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */
1115 
1116             PciPath = ACPI_ADD_PTR (UINT8, ScopeTable,
1117                 sizeof (ACPI_DMAR_DEVICE_SCOPE));
1118 
1119             while (PathOffset < ScopeTable->Length)
1120             {
1121                 AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2,
1122                     "PCI Path");
1123                 AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]);
1124 
1125                 /* Point to next PCI Path entry */
1126 
1127                 PathOffset += 2;
1128                 PciPath += 2;
1129                 AcpiOsPrintf ("\n");
1130             }
1131 
1132             /* Point to next device scope entry */
1133 
1134             ScopeOffset += ScopeTable->Length;
1135             ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE,
1136                 ScopeTable, ScopeTable->Length);
1137         }
1138 
1139 NextSubtable:
1140         /* Point to next subtable */
1141 
1142         Offset += Subtable->Length;
1143         Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Subtable,
1144             Subtable->Length);
1145     }
1146 }
1147 
1148 
1149 /*******************************************************************************
1150  *
1151  * FUNCTION:    AcpiDmDumpDrtm
1152  *
1153  * PARAMETERS:  Table               - A DRTM table
1154  *
1155  * RETURN:      None
1156  *
1157  * DESCRIPTION: Format the contents of a DRTM.
1158  *
1159  ******************************************************************************/
1160 
1161 void
1162 AcpiDmDumpDrtm (
1163     ACPI_TABLE_HEADER       *Table)
1164 {
1165     ACPI_STATUS             Status;
1166     UINT32                  Offset;
1167     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
1168     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
1169     ACPI_DRTM_DPS_ID        *DrtmDps;
1170     UINT32                  Count;
1171 
1172 
1173     /* Main table */
1174 
1175     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
1176         AcpiDmTableInfoDrtm);
1177     if (ACPI_FAILURE (Status))
1178     {
1179         return;
1180     }
1181 
1182     Offset = sizeof (ACPI_TABLE_DRTM);
1183 
1184     /* Sub-tables */
1185 
1186     /* Dump ValidatedTable length */
1187 
1188     DrtmVtl = ACPI_ADD_PTR (ACPI_DRTM_VTABLE_LIST, Table, Offset);
1189     AcpiOsPrintf ("\n");
1190     Status = AcpiDmDumpTable (Table->Length, Offset,
1191         DrtmVtl, ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables),
1192         AcpiDmTableInfoDrtm0);
1193     if (ACPI_FAILURE (Status))
1194     {
1195             return;
1196     }
1197 
1198     Offset += ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables);
1199 
1200     /* Dump Validated table addresses */
1201 
1202     Count = 0;
1203     while ((Offset < Table->Length) &&
1204             (DrtmVtl->ValidatedTableCount > Count))
1205     {
1206         Status = AcpiDmDumpTable (Table->Length, Offset,
1207             ACPI_ADD_PTR (void, Table, Offset), sizeof (UINT64),
1208             AcpiDmTableInfoDrtm0a);
1209         if (ACPI_FAILURE (Status))
1210         {
1211             return;
1212         }
1213 
1214         Offset += sizeof (UINT64);
1215         Count++;
1216     }
1217 
1218     /* Dump ResourceList length */
1219 
1220     DrtmRl = ACPI_ADD_PTR (ACPI_DRTM_RESOURCE_LIST, Table, Offset);
1221     AcpiOsPrintf ("\n");
1222     Status = AcpiDmDumpTable (Table->Length, Offset,
1223         DrtmRl, ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources),
1224         AcpiDmTableInfoDrtm1);
1225     if (ACPI_FAILURE (Status))
1226     {
1227         return;
1228     }
1229 
1230     Offset += ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources);
1231 
1232     /* Dump the Resource List */
1233 
1234     Count = 0;
1235     while ((Offset < Table->Length) &&
1236            (DrtmRl->ResourceCount > Count))
1237     {
1238         Status = AcpiDmDumpTable (Table->Length, Offset,
1239             ACPI_ADD_PTR (void, Table, Offset),
1240             sizeof (ACPI_DRTM_RESOURCE), AcpiDmTableInfoDrtm1a);
1241         if (ACPI_FAILURE (Status))
1242         {
1243             return;
1244         }
1245 
1246         Offset += sizeof (ACPI_DRTM_RESOURCE);
1247         Count++;
1248     }
1249 
1250     /* Dump DPS */
1251 
1252     DrtmDps = ACPI_ADD_PTR (ACPI_DRTM_DPS_ID, Table, Offset);
1253     AcpiOsPrintf ("\n");
1254     (void) AcpiDmDumpTable (Table->Length, Offset,
1255         DrtmDps, sizeof (ACPI_DRTM_DPS_ID), AcpiDmTableInfoDrtm2);
1256 }
1257 
1258 
1259 /*******************************************************************************
1260  *
1261  * FUNCTION:    AcpiDmDumpEinj
1262  *
1263  * PARAMETERS:  Table               - A EINJ table
1264  *
1265  * RETURN:      None
1266  *
1267  * DESCRIPTION: Format the contents of a EINJ. This table type consists
1268  *              of an open-ended number of subtables.
1269  *
1270  ******************************************************************************/
1271 
1272 void
1273 AcpiDmDumpEinj (
1274     ACPI_TABLE_HEADER       *Table)
1275 {
1276     ACPI_STATUS             Status;
1277     ACPI_WHEA_HEADER        *Subtable;
1278     UINT32                  Length = Table->Length;
1279     UINT32                  Offset = sizeof (ACPI_TABLE_EINJ);
1280 
1281 
1282     /* Main table */
1283 
1284     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj);
1285     if (ACPI_FAILURE (Status))
1286     {
1287         return;
1288     }
1289 
1290     /* Subtables */
1291 
1292     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
1293     while (Offset < Table->Length)
1294     {
1295         AcpiOsPrintf ("\n");
1296         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1297             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
1298         if (ACPI_FAILURE (Status))
1299         {
1300             return;
1301         }
1302 
1303         /* Point to next subtable (each subtable is of fixed length) */
1304 
1305         Offset += sizeof (ACPI_WHEA_HEADER);
1306         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
1307             sizeof (ACPI_WHEA_HEADER));
1308     }
1309 }
1310 
1311 
1312 /*******************************************************************************
1313  *
1314  * FUNCTION:    AcpiDmDumpErst
1315  *
1316  * PARAMETERS:  Table               - A ERST table
1317  *
1318  * RETURN:      None
1319  *
1320  * DESCRIPTION: Format the contents of a ERST. This table type consists
1321  *              of an open-ended number of subtables.
1322  *
1323  ******************************************************************************/
1324 
1325 void
1326 AcpiDmDumpErst (
1327     ACPI_TABLE_HEADER       *Table)
1328 {
1329     ACPI_STATUS             Status;
1330     ACPI_WHEA_HEADER        *Subtable;
1331     UINT32                  Length = Table->Length;
1332     UINT32                  Offset = sizeof (ACPI_TABLE_ERST);
1333 
1334 
1335     /* Main table */
1336 
1337     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst);
1338     if (ACPI_FAILURE (Status))
1339     {
1340         return;
1341     }
1342 
1343     /* Subtables */
1344 
1345     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
1346     while (Offset < Table->Length)
1347     {
1348         AcpiOsPrintf ("\n");
1349         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1350             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
1351         if (ACPI_FAILURE (Status))
1352         {
1353             return;
1354         }
1355 
1356         /* Point to next subtable (each subtable is of fixed length) */
1357 
1358         Offset += sizeof (ACPI_WHEA_HEADER);
1359         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
1360             sizeof (ACPI_WHEA_HEADER));
1361     }
1362 }
1363 
1364 
1365 /*******************************************************************************
1366  *
1367  * FUNCTION:    AcpiDmDumpFpdt
1368  *
1369  * PARAMETERS:  Table               - A FPDT table
1370  *
1371  * RETURN:      None
1372  *
1373  * DESCRIPTION: Format the contents of a FPDT. This table type consists
1374  *              of an open-ended number of subtables.
1375  *
1376  ******************************************************************************/
1377 
1378 void
1379 AcpiDmDumpFpdt (
1380     ACPI_TABLE_HEADER       *Table)
1381 {
1382     ACPI_STATUS             Status;
1383     ACPI_FPDT_HEADER        *Subtable;
1384     UINT32                  Length = Table->Length;
1385     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
1386     ACPI_DMTABLE_INFO       *InfoTable;
1387 
1388 
1389     /* There is no main table (other than the standard ACPI header) */
1390 
1391     /* Subtables */
1392 
1393     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
1394     while (Offset < Table->Length)
1395     {
1396         /* Common subtable header */
1397 
1398         AcpiOsPrintf ("\n");
1399         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1400             Subtable->Length, AcpiDmTableInfoFpdtHdr);
1401         if (ACPI_FAILURE (Status))
1402         {
1403             return;
1404         }
1405 
1406         switch (Subtable->Type)
1407         {
1408         case ACPI_FPDT_TYPE_BOOT:
1409 
1410             InfoTable = AcpiDmTableInfoFpdt0;
1411             break;
1412 
1413         case ACPI_FPDT_TYPE_S3PERF:
1414 
1415             InfoTable = AcpiDmTableInfoFpdt1;
1416             break;
1417 
1418         default:
1419 
1420             AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n",
1421                 Subtable->Type);
1422 
1423             /* Attempt to continue */
1424 
1425             if (!Subtable->Length)
1426             {
1427                 AcpiOsPrintf ("Invalid zero length subtable\n");
1428                 return;
1429             }
1430             goto NextSubtable;
1431         }
1432 
1433         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1434             Subtable->Length, InfoTable);
1435         if (ACPI_FAILURE (Status))
1436         {
1437             return;
1438         }
1439 
1440 NextSubtable:
1441         /* Point to next subtable */
1442 
1443         Offset += Subtable->Length;
1444         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable,
1445             Subtable->Length);
1446     }
1447 }
1448 
1449 
1450 /*******************************************************************************
1451  *
1452  * FUNCTION:    AcpiDmDumpGtdt
1453  *
1454  * PARAMETERS:  Table               - A GTDT table
1455  *
1456  * RETURN:      None
1457  *
1458  * DESCRIPTION: Format the contents of a GTDT. This table type consists
1459  *              of an open-ended number of subtables.
1460  *
1461  ******************************************************************************/
1462 
1463 void
1464 AcpiDmDumpGtdt (
1465     ACPI_TABLE_HEADER       *Table)
1466 {
1467     ACPI_STATUS             Status;
1468     ACPI_GTDT_HEADER        *Subtable;
1469     UINT32                  Length = Table->Length;
1470     UINT32                  Offset = sizeof (ACPI_TABLE_GTDT);
1471     ACPI_DMTABLE_INFO       *InfoTable;
1472     UINT32                  SubtableLength;
1473     UINT32                  GtCount;
1474     ACPI_GTDT_TIMER_ENTRY   *GtxTable;
1475 
1476 
1477     /* Main table */
1478 
1479     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoGtdt);
1480     if (ACPI_FAILURE (Status))
1481     {
1482         return;
1483     }
1484 
1485     /* Rev 3 fields */
1486 
1487     Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
1488 
1489     if (Table->Revision > 2)
1490     {
1491         SubtableLength = sizeof (ACPI_GTDT_EL2);
1492         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1493             SubtableLength, AcpiDmTableInfoGtdtEl2);
1494         if (ACPI_FAILURE (Status))
1495         {
1496             return;
1497         }
1498         Offset += SubtableLength;
1499     }
1500 
1501     Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
1502 
1503     /* Subtables */
1504 
1505     while (Offset < Table->Length)
1506     {
1507         /* Common subtable header */
1508 
1509         AcpiOsPrintf ("\n");
1510         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1511             Subtable->Length, AcpiDmTableInfoGtdtHdr);
1512         if (ACPI_FAILURE (Status))
1513         {
1514             return;
1515         }
1516 
1517         GtCount = 0;
1518         switch (Subtable->Type)
1519         {
1520         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1521 
1522             SubtableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
1523             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1524                 Subtable))->TimerCount;
1525 
1526             InfoTable = AcpiDmTableInfoGtdt0;
1527             break;
1528 
1529         case ACPI_GTDT_TYPE_WATCHDOG:
1530 
1531             SubtableLength = sizeof (ACPI_GTDT_WATCHDOG);
1532 
1533             InfoTable = AcpiDmTableInfoGtdt1;
1534             break;
1535 
1536         default:
1537 
1538             /* Cannot continue on unknown type - no length */
1539 
1540             AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n",
1541                 Subtable->Type);
1542             return;
1543         }
1544 
1545         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1546             Subtable->Length, InfoTable);
1547         if (ACPI_FAILURE (Status))
1548         {
1549             return;
1550         }
1551 
1552         /* Point to end of current subtable (each subtable above is of fixed length) */
1553 
1554         Offset += SubtableLength;
1555 
1556         /* If there are any Gt Timer Blocks from above, dump them now */
1557 
1558         if (GtCount)
1559         {
1560             GtxTable = ACPI_ADD_PTR (
1561                 ACPI_GTDT_TIMER_ENTRY, Subtable, SubtableLength);
1562             SubtableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
1563 
1564             while (GtCount)
1565             {
1566                 AcpiOsPrintf ("\n");
1567                 Status = AcpiDmDumpTable (Length, Offset, GtxTable,
1568                     sizeof (ACPI_GTDT_TIMER_ENTRY), AcpiDmTableInfoGtdt0a);
1569                 if (ACPI_FAILURE (Status))
1570                 {
1571                     return;
1572                 }
1573                 Offset += sizeof (ACPI_GTDT_TIMER_ENTRY);
1574                 GtxTable++;
1575                 GtCount--;
1576             }
1577         }
1578 
1579         /* Point to next subtable */
1580 
1581         Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Subtable, SubtableLength);
1582     }
1583 }
1584 
1585 
1586 /*******************************************************************************
1587  *
1588  * FUNCTION:    AcpiDmDumpHest
1589  *
1590  * PARAMETERS:  Table               - A HEST table
1591  *
1592  * RETURN:      None
1593  *
1594  * DESCRIPTION: Format the contents of a HEST. This table type consists
1595  *              of an open-ended number of subtables.
1596  *
1597  ******************************************************************************/
1598 
1599 void
1600 AcpiDmDumpHest (
1601     ACPI_TABLE_HEADER       *Table)
1602 {
1603     ACPI_STATUS             Status;
1604     ACPI_HEST_HEADER        *Subtable;
1605     UINT32                  Length = Table->Length;
1606     UINT32                  Offset = sizeof (ACPI_TABLE_HEST);
1607     ACPI_DMTABLE_INFO       *InfoTable;
1608     UINT32                  SubtableLength;
1609     UINT32                  BankCount;
1610     ACPI_HEST_IA_ERROR_BANK *BankTable;
1611 
1612 
1613     /* Main table */
1614 
1615     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest);
1616     if (ACPI_FAILURE (Status))
1617     {
1618         return;
1619     }
1620 
1621     /* Subtables */
1622 
1623     Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
1624     while (Offset < Table->Length)
1625     {
1626         BankCount = 0;
1627         switch (Subtable->Type)
1628         {
1629         case ACPI_HEST_TYPE_IA32_CHECK:
1630 
1631             InfoTable = AcpiDmTableInfoHest0;
1632             SubtableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
1633             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1634                 Subtable))->NumHardwareBanks;
1635             break;
1636 
1637         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1638 
1639             InfoTable = AcpiDmTableInfoHest1;
1640             SubtableLength = sizeof (ACPI_HEST_IA_CORRECTED);
1641             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1642                 Subtable))->NumHardwareBanks;
1643             break;
1644 
1645         case ACPI_HEST_TYPE_IA32_NMI:
1646 
1647             InfoTable = AcpiDmTableInfoHest2;
1648             SubtableLength = sizeof (ACPI_HEST_IA_NMI);
1649             break;
1650 
1651         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1652 
1653             InfoTable = AcpiDmTableInfoHest6;
1654             SubtableLength = sizeof (ACPI_HEST_AER_ROOT);
1655             break;
1656 
1657         case ACPI_HEST_TYPE_AER_ENDPOINT:
1658 
1659             InfoTable = AcpiDmTableInfoHest7;
1660             SubtableLength = sizeof (ACPI_HEST_AER);
1661             break;
1662 
1663         case ACPI_HEST_TYPE_AER_BRIDGE:
1664 
1665             InfoTable = AcpiDmTableInfoHest8;
1666             SubtableLength = sizeof (ACPI_HEST_AER_BRIDGE);
1667             break;
1668 
1669         case ACPI_HEST_TYPE_GENERIC_ERROR:
1670 
1671             InfoTable = AcpiDmTableInfoHest9;
1672             SubtableLength = sizeof (ACPI_HEST_GENERIC);
1673             break;
1674 
1675         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
1676 
1677             InfoTable = AcpiDmTableInfoHest10;
1678             SubtableLength = sizeof (ACPI_HEST_GENERIC_V2);
1679             break;
1680 
1681         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1682 
1683             InfoTable = AcpiDmTableInfoHest11;
1684             SubtableLength = sizeof (ACPI_HEST_IA_DEFERRED_CHECK);
1685             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
1686                 Subtable))->NumHardwareBanks;
1687             break;
1688 
1689         default:
1690 
1691             /* Cannot continue on unknown type - no length */
1692 
1693             AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n",
1694                 Subtable->Type);
1695             return;
1696         }
1697 
1698         AcpiOsPrintf ("\n");
1699         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1700             SubtableLength, InfoTable);
1701         if (ACPI_FAILURE (Status))
1702         {
1703             return;
1704         }
1705 
1706         /* Point to end of current subtable (each subtable above is of fixed length) */
1707 
1708         Offset += SubtableLength;
1709 
1710         /* If there are any (fixed-length) Error Banks from above, dump them now */
1711 
1712         if (BankCount)
1713         {
1714             BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, Subtable,
1715                 SubtableLength);
1716             SubtableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
1717 
1718             while (BankCount)
1719             {
1720                 AcpiOsPrintf ("\n");
1721                 Status = AcpiDmDumpTable (Length, Offset, BankTable,
1722                     sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank);
1723                 if (ACPI_FAILURE (Status))
1724                 {
1725                     return;
1726                 }
1727 
1728                 Offset += sizeof (ACPI_HEST_IA_ERROR_BANK);
1729                 BankTable++;
1730                 BankCount--;
1731             }
1732         }
1733 
1734         /* Point to next subtable */
1735 
1736         Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Subtable, SubtableLength);
1737     }
1738 }
1739 
1740 
1741 /*******************************************************************************
1742  *
1743  * FUNCTION:    AcpiDmDumpHmat
1744  *
1745  * PARAMETERS:  Table               - A HMAT table
1746  *
1747  * RETURN:      None
1748  *
1749  * DESCRIPTION: Format the contents of a HMAT.
1750  *
1751  ******************************************************************************/
1752 
1753 void
1754 AcpiDmDumpHmat (
1755     ACPI_TABLE_HEADER       *Table)
1756 {
1757     ACPI_STATUS             Status;
1758     ACPI_HMAT_STRUCTURE     *HmatStruct;
1759     ACPI_HMAT_LOCALITY      *HmatLocality;
1760     ACPI_HMAT_CACHE         *HmatCache;
1761     UINT32                  Offset;
1762     UINT32                  SubtableOffset;
1763     UINT32                  Length;
1764     ACPI_DMTABLE_INFO       *InfoTable;
1765     UINT32                  i, j;
1766 
1767 
1768     /* Main table */
1769 
1770     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoHmat);
1771     if (ACPI_FAILURE (Status))
1772     {
1773         return;
1774     }
1775     Offset = sizeof (ACPI_TABLE_HMAT);
1776 
1777     while (Offset < Table->Length)
1778     {
1779         AcpiOsPrintf ("\n");
1780 
1781         /* Dump HMAT structure header */
1782 
1783         HmatStruct = ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, Table, Offset);
1784         if (HmatStruct->Length < sizeof (ACPI_HMAT_STRUCTURE))
1785         {
1786             AcpiOsPrintf ("Invalid HMAT structure length\n");
1787             return;
1788         }
1789         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
1790             HmatStruct->Length, AcpiDmTableInfoHmatHdr);
1791         if (ACPI_FAILURE (Status))
1792         {
1793             return;
1794         }
1795 
1796         switch (HmatStruct->Type)
1797         {
1798         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
1799 
1800             InfoTable = AcpiDmTableInfoHmat0;
1801             Length = sizeof (ACPI_HMAT_PROXIMITY_DOMAIN);
1802             break;
1803 
1804         case ACPI_HMAT_TYPE_LOCALITY:
1805 
1806             InfoTable = AcpiDmTableInfoHmat1;
1807             Length = sizeof (ACPI_HMAT_LOCALITY);
1808             break;
1809 
1810         case ACPI_HMAT_TYPE_CACHE:
1811 
1812             InfoTable = AcpiDmTableInfoHmat2;
1813             Length = sizeof (ACPI_HMAT_CACHE);
1814             break;
1815 
1816         default:
1817 
1818             AcpiOsPrintf ("\n**** Unknown HMAT structure type 0x%X\n",
1819                 HmatStruct->Type);
1820 
1821             /* Attempt to continue */
1822 
1823             goto NextSubtable;
1824         }
1825 
1826         /* Dump HMAT structure body */
1827 
1828         if (HmatStruct->Length < Length)
1829         {
1830             AcpiOsPrintf ("Invalid HMAT structure length\n");
1831             return;
1832         }
1833         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
1834             HmatStruct->Length, InfoTable);
1835         if (ACPI_FAILURE (Status))
1836         {
1837             return;
1838         }
1839 
1840         /* Dump HMAT structure additionals */
1841 
1842         switch (HmatStruct->Type)
1843         {
1844         case ACPI_HMAT_TYPE_LOCALITY:
1845 
1846             HmatLocality = ACPI_CAST_PTR (ACPI_HMAT_LOCALITY, HmatStruct);
1847             SubtableOffset = sizeof (ACPI_HMAT_LOCALITY);
1848 
1849             /* Dump initiator proximity domains */
1850 
1851             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1852                 (UINT32)(HmatLocality->NumberOfInitiatorPDs * 4))
1853             {
1854                 AcpiOsPrintf ("Invalid initiator proximity domain number\n");
1855                 return;
1856             }
1857             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
1858             {
1859                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1860                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1861                     4, AcpiDmTableInfoHmat1a);
1862                 if (ACPI_FAILURE (Status))
1863                 {
1864                     return;
1865                 }
1866 
1867                 SubtableOffset += 4;
1868             }
1869 
1870             /* Dump target proximity domains */
1871 
1872             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1873                 (UINT32)(HmatLocality->NumberOfTargetPDs * 4))
1874             {
1875                 AcpiOsPrintf ("Invalid target proximity domain number\n");
1876                 return;
1877             }
1878             for (i = 0; i < HmatLocality->NumberOfTargetPDs; i++)
1879             {
1880                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1881                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1882                     4, AcpiDmTableInfoHmat1b);
1883                 if (ACPI_FAILURE (Status))
1884                 {
1885                     return;
1886                 }
1887 
1888                 SubtableOffset += 4;
1889             }
1890 
1891             /* Dump latency/bandwidth entris */
1892 
1893             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1894                 (UINT32)(HmatLocality->NumberOfInitiatorPDs *
1895                          HmatLocality->NumberOfTargetPDs * 2))
1896             {
1897                 AcpiOsPrintf ("Invalid latency/bandwidth entry number\n");
1898                 return;
1899             }
1900             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
1901             {
1902                 for (j = 0; j < HmatLocality->NumberOfTargetPDs; j++)
1903                 {
1904                     Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1905                         ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1906                         2, AcpiDmTableInfoHmat1c);
1907                     if (ACPI_FAILURE(Status))
1908                     {
1909                         return;
1910                     }
1911 
1912                     SubtableOffset += 2;
1913                 }
1914             }
1915             break;
1916 
1917         case ACPI_HMAT_TYPE_CACHE:
1918 
1919             HmatCache = ACPI_CAST_PTR (ACPI_HMAT_CACHE, HmatStruct);
1920             SubtableOffset = sizeof (ACPI_HMAT_CACHE);
1921 
1922             /* Dump SMBIOS handles */
1923 
1924             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1925                 (UINT32)(HmatCache->NumberOfSMBIOSHandles * 2))
1926             {
1927                 AcpiOsPrintf ("Invalid SMBIOS handle number\n");
1928                 return;
1929             }
1930             for (i = 0; i < HmatCache->NumberOfSMBIOSHandles; i++)
1931             {
1932                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1933                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1934                     2, AcpiDmTableInfoHmat2a);
1935                 if (ACPI_FAILURE (Status))
1936                 {
1937                     return;
1938                 }
1939 
1940                 SubtableOffset += 2;
1941             }
1942             break;
1943 
1944         default:
1945 
1946             break;
1947         }
1948 
1949 NextSubtable:
1950         /* Point to next HMAT structure subtable */
1951 
1952         Offset += (HmatStruct->Length);
1953     }
1954 }
1955