xref: /freebsd/sys/contrib/dev/acpica/common/dmtbdump1.c (revision 7697e6c4df7188ee3a2aa66f73c572c27479bdf2)
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 - 2026, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/include/acpi.h>
153 #include <contrib/dev/acpica/include/accommon.h>
154 #include <contrib/dev/acpica/include/acdisasm.h>
155 #include <contrib/dev/acpica/include/actables.h>
156 #include <contrib/dev/acpica/compiler/aslcompiler.h>
157 
158 /* This module used for application-level code only */
159 
160 #define _COMPONENT          ACPI_CA_DISASSEMBLER
161         ACPI_MODULE_NAME    ("dmtbdump1")
162 
163 
164 /*******************************************************************************
165  *
166  * FUNCTION:    AcpiDmDumpAest
167  *
168  * PARAMETERS:  Table               - A AEST table
169  *
170  * RETURN:      None
171  *
172  * DESCRIPTION: Format the contents of a AEST table
173  *
174  * NOTE: Assumes the following table structure:
175  *      For all AEST Error Nodes:
176  *          1) An AEST Error Node, followed immediately by:
177  *          2) Any node-specific data
178  *          3) An Interface Structure (one)
179  *          4) A list (array) of Interrupt Structures
180  *
181  * AEST - ARM Error Source table. Conforms to:
182  * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020
183  *
184  ******************************************************************************/
185 
186 void
AcpiDmDumpAest(ACPI_TABLE_HEADER * Table)187 AcpiDmDumpAest (
188     ACPI_TABLE_HEADER       *Table)
189 {
190     ACPI_STATUS             Status;
191     UINT32                  Offset = sizeof (ACPI_TABLE_HEADER);
192     ACPI_AEST_HEADER        *Subtable;
193     ACPI_AEST_HEADER        *NodeHeader;
194     ACPI_AEST_PROCESSOR     *ProcessorSubtable;
195     ACPI_DMTABLE_INFO       *InfoTable;
196     ACPI_SIZE               Length;
197     UINT8                   Type;
198     UINT8                   Revision = Table->Revision;
199     UINT32                  Count;
200     ACPI_AEST_NODE_INTERFACE_HEADER *InterfaceHeader;
201 
202 
203     /* Very small, generic main table. AEST consists of mostly subtables */
204 
205     while (Offset < Table->Length)
206     {
207         NodeHeader = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
208 
209         /* Dump the common error node (subtable) header */
210 
211         Status = AcpiDmDumpTable (Table->Length, Offset, NodeHeader,
212             NodeHeader->Length, AcpiDmTableInfoAestHdr);
213         if (ACPI_FAILURE (Status))
214         {
215             return;
216         }
217 
218         Type = NodeHeader->Type;
219 
220         /* Setup the node-specific subtable based on the header Type field */
221 
222         switch (Type)
223         {
224         case ACPI_AEST_PROCESSOR_ERROR_NODE:
225             InfoTable = AcpiDmTableInfoAestProcError;
226             Length = sizeof (ACPI_AEST_PROCESSOR);
227             break;
228 
229         case ACPI_AEST_MEMORY_ERROR_NODE:
230             InfoTable = AcpiDmTableInfoAestMemError;
231             Length = sizeof (ACPI_AEST_MEMORY);
232             break;
233 
234         case ACPI_AEST_SMMU_ERROR_NODE:
235             InfoTable = AcpiDmTableInfoAestSmmuError;
236             Length = sizeof (ACPI_AEST_SMMU);
237             break;
238 
239         case ACPI_AEST_VENDOR_ERROR_NODE:
240             switch (Revision)
241             {
242             case 1:
243                 InfoTable = AcpiDmTableInfoAestVendorError;
244                 Length = sizeof (ACPI_AEST_VENDOR);
245                 break;
246 
247             case 2:
248                 InfoTable = AcpiDmTableInfoAestVendorV2Error;
249                 Length = sizeof (ACPI_AEST_VENDOR_V2);
250                 break;
251 
252             default:
253                 AcpiOsPrintf ("\n**** Unknown AEST revision 0x%X\n", Revision);
254                 return;
255             }
256             break;
257 
258         case ACPI_AEST_GIC_ERROR_NODE:
259             InfoTable = AcpiDmTableInfoAestGicError;
260             Length = sizeof (ACPI_AEST_GIC);
261             break;
262 
263         case ACPI_AEST_PCIE_ERROR_NODE:
264             InfoTable = AcpiDmTableInfoAestPCIeError;
265             Length = sizeof (ACPI_AEST_PCIE);
266             break;
267 
268         case ACPI_AEST_PROXY_ERROR_NODE:
269             InfoTable = AcpiDmTableInfoAestProxyError;
270             Length = sizeof (ACPI_AEST_PROXY);
271             break;
272 
273         /* Error case below */
274         default:
275 
276             AcpiOsPrintf ("\n**** Unknown AEST Error Subtable type 0x%X\n",
277                 Type);
278             return;
279         }
280 
281         /* Point past the common header (to the node-specific data) */
282 
283         Offset += sizeof (ACPI_AEST_HEADER);
284         Subtable = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
285         AcpiOsPrintf ("\n");
286 
287         /* Dump the node-specific subtable */
288 
289         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, Length,
290             InfoTable);
291         if (ACPI_FAILURE (Status))
292         {
293             return;
294         }
295         AcpiOsPrintf ("\n");
296 
297         if (Type == ACPI_AEST_PROCESSOR_ERROR_NODE)
298         {
299             /*
300              * Special handling for PROCESSOR_ERROR_NODE subtables
301              * (to handle the Resource Substructure via the ResourceType
302              * field).
303              */
304 
305             /* Point past the node-specific data */
306 
307             Offset += Length;
308             ProcessorSubtable = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR, Subtable);
309 
310             switch (ProcessorSubtable->ResourceType)
311             {
312             /* Setup the Resource Substructure subtable */
313 
314             case ACPI_AEST_CACHE_RESOURCE:
315                 InfoTable = AcpiDmTableInfoAestCacheRsrc;
316                 Length = sizeof (ACPI_AEST_PROCESSOR_CACHE);
317                 break;
318 
319             case ACPI_AEST_TLB_RESOURCE:
320                 InfoTable = AcpiDmTableInfoAestTlbRsrc;
321                 Length = sizeof (ACPI_AEST_PROCESSOR_TLB);
322                 break;
323 
324             case ACPI_AEST_GENERIC_RESOURCE:
325                 InfoTable = AcpiDmTableInfoAestGenRsrc;
326                 Length = sizeof (ACPI_AEST_PROCESSOR_GENERIC);
327                 break;
328 
329             /* Error case below */
330             default:
331                 AcpiOsPrintf ("\n**** Unknown AEST Processor Resource type 0x%X\n",
332                     ProcessorSubtable->ResourceType);
333                 return;
334             }
335 
336             ProcessorSubtable = ACPI_ADD_PTR (ACPI_AEST_PROCESSOR, Table,
337                 Offset);
338 
339             /* Dump the resource substructure subtable */
340 
341             Status = AcpiDmDumpTable (Table->Length, Offset, ProcessorSubtable,
342                 Length, InfoTable);
343             if (ACPI_FAILURE (Status))
344             {
345                 return;
346             }
347 
348             AcpiOsPrintf ("\n");
349         }
350 
351         /* Point past the resource substructure or the node-specific data */
352 
353         Offset += Length;
354 
355         /* Dump the interface structure, required to be present */
356 
357         Subtable = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
358         if (Subtable->Type >= ACPI_AEST_XFACE_RESERVED)
359         {
360             AcpiOsPrintf ("\n**** Unknown AEST Node Interface type 0x%X\n",
361                 Subtable->Type);
362             return;
363         }
364 
365         if (Revision == 1)
366         {
367             InfoTable = AcpiDmTableInfoAestXface;
368             Length = sizeof (ACPI_AEST_NODE_INTERFACE);
369         }
370         else if (Revision == 2)
371         {
372             InfoTable = AcpiDmTableInfoAestXfaceHeader;
373             Length = sizeof (ACPI_AEST_NODE_INTERFACE_HEADER);
374 
375             Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, Length, InfoTable);
376             if (ACPI_FAILURE (Status))
377             {
378                 return;
379             }
380 
381             Offset += Length;
382 
383             InterfaceHeader = ACPI_CAST_PTR (ACPI_AEST_NODE_INTERFACE_HEADER, Subtable);
384             switch (InterfaceHeader->GroupFormat)
385 	        {
386             case ACPI_AEST_NODE_GROUP_FORMAT_4K:
387                 InfoTable = AcpiDmTableInfoAestXface4k;
388                 Length = sizeof (ACPI_AEST_NODE_INTERFACE_4K);
389                 break;
390 
391             case ACPI_AEST_NODE_GROUP_FORMAT_16K:
392                 InfoTable = AcpiDmTableInfoAestXface16k;
393                 Length = sizeof (ACPI_AEST_NODE_INTERFACE_16K);
394                 break;
395 
396             case ACPI_AEST_NODE_GROUP_FORMAT_64K:
397                 InfoTable = AcpiDmTableInfoAestXface64k;
398                 Length = sizeof (ACPI_AEST_NODE_INTERFACE_64K);
399                 break;
400 
401             default:
402                 AcpiOsPrintf ("\n**** Unknown AEST Interface Group Format 0x%X\n",
403                     InterfaceHeader->GroupFormat);
404                 return;
405             }
406 
407             Subtable = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
408         }
409         else
410         {
411             AcpiOsPrintf ("\n**** Unknown AEST revision 0x%X\n", Revision);
412             return;
413         }
414 
415         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, Length, InfoTable);
416         if (ACPI_FAILURE (Status))
417         {
418             return;
419         }
420 
421         /* Point past the interface structure */
422 
423         AcpiOsPrintf ("\n");
424         Offset += Length;
425 
426         /* Dump the entire interrupt structure array, if present */
427 
428         if (NodeHeader->NodeInterruptOffset)
429         {
430             Count = NodeHeader->NodeInterruptCount;
431             Subtable = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
432 
433             while (Count)
434             {
435                 /* Dump the interrupt structure */
436 
437                 switch (Revision) {
438                 case 1:
439                     InfoTable = AcpiDmTableInfoAestXrupt;
440                     Length = sizeof (ACPI_AEST_NODE_INTERRUPT);
441                     break;
442 
443                 case 2:
444                     InfoTable = AcpiDmTableInfoAestXruptV2;
445                     Length = sizeof (ACPI_AEST_NODE_INTERRUPT_V2);
446                     break;
447                 default:
448                     AcpiOsPrintf ("\n**** Unknown AEST revision 0x%X\n",
449                         Revision);
450                     return;
451                 }
452                 Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
453                     Length, InfoTable);
454                 if (ACPI_FAILURE (Status))
455                 {
456                     return;
457                 }
458 
459                 /* Point to the next interrupt structure */
460 
461                 Offset += Length;
462                 Subtable = ACPI_ADD_PTR (ACPI_AEST_HEADER, Table, Offset);
463                 Count--;
464                 AcpiOsPrintf ("\n");
465             }
466         }
467     }
468 }
469 
470 /*******************************************************************************
471  *
472  * FUNCTION:    AcpiDmDumpApmt
473  *
474  * PARAMETERS:  Table               - A APMT table
475  *
476  * RETURN:      None
477  *
478  * DESCRIPTION: Format the contents of a APMT. This table type consists
479  *              of an open-ended number of subtables.
480  *
481  *
482  * APMT - ARM Performance Monitoring Unit table. Conforms to:
483  * ARM Performance Monitoring Unit Architecture 1.0 Platform Design Document
484  * ARM DEN0117 v1.0 November 25, 2021
485  *
486  ******************************************************************************/
487 
488 void
AcpiDmDumpApmt(ACPI_TABLE_HEADER * Table)489 AcpiDmDumpApmt (
490     ACPI_TABLE_HEADER       *Table)
491 {
492     ACPI_STATUS              Status;
493     ACPI_APMT_NODE           *Subtable;
494     UINT32                   Length = Table->Length;
495     UINT32                   Offset = sizeof (ACPI_TABLE_APMT);
496     UINT32                   NodeNum = 0;
497 
498     /* There is no main table (other than the standard ACPI header) */
499 
500     /* Subtables */
501 
502     Subtable = ACPI_ADD_PTR (ACPI_APMT_NODE, Table, Offset);
503     while (Offset < Table->Length)
504     {
505         AcpiOsPrintf ("\n");
506 
507         if (Subtable->Type >= ACPI_APMT_NODE_TYPE_COUNT)
508         {
509             AcpiOsPrintf ("\n**** Unknown APMT subtable type 0x%X\n",
510                 Subtable->Type);
511             return;
512         }
513 
514         AcpiOsPrintf ("/* APMT Node-%u */\n", NodeNum++);
515 
516         Status = AcpiDmDumpTable (Length, Offset, Subtable,
517             Subtable->Length, AcpiDmTableInfoApmtNode);
518         if (ACPI_FAILURE (Status))
519         {
520             return;
521         }
522 
523         /* Point to next subtable */
524 
525         Offset += Subtable->Length;
526         Subtable = ACPI_ADD_PTR (ACPI_APMT_NODE, Subtable,
527             Subtable->Length);
528         AcpiOsPrintf ("\n");
529     }
530 }
531 
532 
533 /*******************************************************************************
534  *
535  * FUNCTION:    AcpiDmDumpAsf
536  *
537  * PARAMETERS:  Table               - A ASF table
538  *
539  * RETURN:      None
540  *
541  * DESCRIPTION: Format the contents of a ASF table
542  *
543  ******************************************************************************/
544 
545 void
AcpiDmDumpAsf(ACPI_TABLE_HEADER * Table)546 AcpiDmDumpAsf (
547     ACPI_TABLE_HEADER       *Table)
548 {
549     ACPI_STATUS             Status;
550     UINT32                  Offset = sizeof (ACPI_TABLE_HEADER);
551     ACPI_ASF_INFO           *Subtable;
552     ACPI_DMTABLE_INFO       *InfoTable;
553     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
554     UINT8                   *DataTable = NULL;
555     UINT32                  DataCount = 0;
556     UINT32                  DataLength = 0;
557     UINT32                  DataOffset = 0;
558     UINT32                  i;
559     UINT8                   Type;
560 
561 
562     /* No main table, only subtables */
563 
564     Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
565     while (Offset < Table->Length)
566     {
567         /* Common subtable header */
568 
569         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
570             Subtable->Header.Length, AcpiDmTableInfoAsfHdr);
571         if (ACPI_FAILURE (Status))
572         {
573             return;
574         }
575 
576         /* The actual type is the lower 7 bits of Type */
577 
578         Type = (UINT8) (Subtable->Header.Type & 0x7F);
579 
580         switch (Type)
581         {
582         case ACPI_ASF_TYPE_INFO:
583 
584             InfoTable = AcpiDmTableInfoAsf0;
585             break;
586 
587         case ACPI_ASF_TYPE_ALERT:
588 
589             InfoTable = AcpiDmTableInfoAsf1;
590             DataInfoTable = AcpiDmTableInfoAsf1a;
591             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ALERT));
592             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->Alerts;
593             DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->DataLength;
594             DataOffset = Offset + sizeof (ACPI_ASF_ALERT);
595             break;
596 
597         case ACPI_ASF_TYPE_CONTROL:
598 
599             InfoTable = AcpiDmTableInfoAsf2;
600             DataInfoTable = AcpiDmTableInfoAsf2a;
601             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_REMOTE));
602             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->Controls;
603             DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->DataLength;
604             DataOffset = Offset + sizeof (ACPI_ASF_REMOTE);
605             break;
606 
607         case ACPI_ASF_TYPE_BOOT:
608 
609             InfoTable = AcpiDmTableInfoAsf3;
610             break;
611 
612         case ACPI_ASF_TYPE_ADDRESS:
613 
614             InfoTable = AcpiDmTableInfoAsf4;
615             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ADDRESS));
616             DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, Subtable)->Devices;
617             DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS);
618             break;
619 
620         default:
621 
622             AcpiOsPrintf ("\n**** Unknown ASF subtable type 0x%X\n",
623                 Subtable->Header.Type);
624             return;
625         }
626 
627         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
628             Subtable->Header.Length, InfoTable);
629         if (ACPI_FAILURE (Status))
630         {
631             return;
632         }
633 
634         /* Dump variable-length extra data */
635 
636         switch (Type)
637         {
638         case ACPI_ASF_TYPE_ALERT:
639         case ACPI_ASF_TYPE_CONTROL:
640 
641             for (i = 0; i < DataCount; i++)
642             {
643                 AcpiOsPrintf ("\n");
644                 Status = AcpiDmDumpTable (Table->Length, DataOffset,
645                     DataTable, DataLength, DataInfoTable);
646                 if (ACPI_FAILURE (Status))
647                 {
648                     return;
649                 }
650 
651                 DataTable = ACPI_ADD_PTR (UINT8, DataTable, DataLength);
652                 DataOffset += DataLength;
653             }
654             break;
655 
656         case ACPI_ASF_TYPE_ADDRESS:
657 
658             for (i = 0; i < DataLength; i++)
659             {
660                 if (!(i % 16))
661                 {
662                     AcpiDmLineHeader (DataOffset, 1, "Addresses");
663                 }
664 
665                 AcpiOsPrintf ("%2.2X ", *DataTable);
666                 DataTable++;
667                 DataOffset++;
668 
669                 if (DataOffset > Table->Length)
670                 {
671                     AcpiOsPrintf (
672                         "**** ACPI table terminates in the middle of a "
673                         "data structure! (ASF! table)\n");
674                     return;
675                 }
676             }
677 
678             AcpiOsPrintf ("\n");
679             break;
680 
681         default:
682 
683             break;
684         }
685 
686         AcpiOsPrintf ("\n");
687 
688         /* Point to next subtable */
689 
690         if (!Subtable->Header.Length)
691         {
692             AcpiOsPrintf ("Invalid zero subtable header length\n");
693             return;
694         }
695 
696         Offset += Subtable->Header.Length;
697         Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Subtable,
698             Subtable->Header.Length);
699     }
700 }
701 
702 /*******************************************************************************
703  *
704  * FUNCTION:    AcpiDmDumpAspt
705  *
706  * PARAMETERS:  Table               - A ASPT table
707  *
708  * RETURN:      None
709  *
710  * DESCRIPTION: Format the contents of a ASPT table
711  *
712  ******************************************************************************/
713 
714 void
AcpiDmDumpAspt(ACPI_TABLE_HEADER * Table)715 AcpiDmDumpAspt (
716     ACPI_TABLE_HEADER       *Table)
717 {
718     ACPI_STATUS             Status;
719     UINT32                  Offset = sizeof (ACPI_TABLE_ASPT);
720     UINT32                  Length = Table->Length;
721     ACPI_ASPT_HEADER        *Subtable;
722     ACPI_DMTABLE_INFO       *InfoTable;
723     UINT16                   Type;
724 
725     /* Main table */
726     Status = AcpiDmDumpTable(Length, 0, Table, 0, AcpiDmTableInfoAspt);
727 
728     /* Subtables */
729 
730     Subtable = ACPI_ADD_PTR (ACPI_ASPT_HEADER, Table, Offset);
731     while (Offset < Table->Length)
732     {
733         AcpiOsPrintf ("\n");
734 
735         /* Common subtable header */
736         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
737             Subtable->Length, AcpiDmTableInfoAsptHdr);
738         if (ACPI_FAILURE (Status))
739         {
740             return;
741         }
742 
743         Type = Subtable->Type;
744 
745         switch (Type)
746         {
747         case ACPI_ASPT_TYPE_GLOBAL_REGS:
748 
749             InfoTable = AcpiDmTableInfoAspt0;
750             break;
751 
752         case ACPI_ASPT_TYPE_SEV_MBOX_REGS:
753 
754             InfoTable = AcpiDmTableInfoAspt1;
755             break;
756 
757         case ACPI_ASPT_TYPE_ACPI_MBOX_REGS:
758 
759             InfoTable = AcpiDmTableInfoAspt2;
760             break;
761 
762         default:
763 
764             AcpiOsPrintf ("\n**** Unknown ASPT subtable type 0x%X\n",
765                 Subtable->Type);
766             return;
767         }
768 
769         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
770             Subtable->Length, InfoTable);
771         if (ACPI_FAILURE (Status))
772         {
773             return;
774         }
775 
776         AcpiOsPrintf ("\n");
777 
778         /* Point to next subtable */
779         if (!Subtable->Length)
780         {
781             AcpiOsPrintf ("Invalid zero subtable header length\n");
782             return;
783         }
784 
785         Offset += Subtable->Length;
786         Subtable = ACPI_ADD_PTR (ACPI_ASPT_HEADER, Subtable,
787             Subtable->Length);
788     }
789 }
790 
791 
792 /*******************************************************************************
793  *
794  * FUNCTION:    AcpiDmDumpCdat
795  *
796  * PARAMETERS:  InTable             - A CDAT table
797  *
798  * RETURN:      None
799  *
800  * DESCRIPTION: Format the contents of a CDAT. This table type consists
801  *              of an open-ended number of subtables.
802  *
803  ******************************************************************************/
804 
805 void
AcpiDmDumpCdat(ACPI_TABLE_HEADER * InTable)806 AcpiDmDumpCdat (
807     ACPI_TABLE_HEADER       *InTable)
808 {
809     ACPI_TABLE_CDAT         *Table = ACPI_CAST_PTR (ACPI_TABLE_CDAT, InTable);
810     ACPI_STATUS             Status;
811     ACPI_CDAT_HEADER        *Subtable;
812     ACPI_TABLE_CDAT         *CdatTable = ACPI_CAST_PTR (ACPI_TABLE_CDAT, Table);
813     ACPI_DMTABLE_INFO       *InfoTable;
814     UINT32                  Length = CdatTable->Length;
815     UINT32                  Offset = sizeof (ACPI_TABLE_CDAT);
816     UINT32                  SubtableLength;
817     UINT32                  SubtableType;
818     INT32                   EntriesLength;
819 
820 
821     /* Main table */
822 
823     Status = AcpiDmDumpTable (Offset, 0, CdatTable, 0,
824         AcpiDmTableInfoCdatTableHdr);
825     if (ACPI_FAILURE (Status))
826     {
827         return;
828     }
829 
830     Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table, sizeof (ACPI_TABLE_CDAT));
831     while (Offset < Table->Length)
832     {
833         /* Dump the common subtable header */
834 
835         DbgPrint (ASL_DEBUG_OUTPUT, "0) HeaderOffset: %X\n", Offset);
836         AcpiOsPrintf ("\n");
837         Status = AcpiDmDumpTable (Length, Offset, Subtable,
838             sizeof (ACPI_CDAT_HEADER), AcpiDmTableInfoCdatHeader);
839         if (ACPI_FAILURE (Status))
840         {
841             return;
842         }
843 
844         /* Point past the common subtable header, decode the subtable type */
845 
846         Offset += sizeof (ACPI_CDAT_HEADER);
847         SubtableType = Subtable->Type;
848 
849         switch (Subtable->Type)
850         {
851         case ACPI_CDAT_TYPE_DSMAS:
852             Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table, Offset);
853             SubtableLength = sizeof (ACPI_CDAT_DSMAS);
854 
855             InfoTable = AcpiDmTableInfoCdat0;
856             break;
857 
858         case ACPI_CDAT_TYPE_DSLBIS:
859             Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table, Offset);
860             SubtableLength = sizeof (ACPI_CDAT_DSLBIS);
861             DbgPrint (ASL_DEBUG_OUTPUT, "1) Offset: %X\n", Offset);
862 
863             InfoTable = AcpiDmTableInfoCdat1;
864             break;
865 
866         case ACPI_CDAT_TYPE_DSMSCIS:
867             Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table, Offset);
868             SubtableLength = sizeof (ACPI_CDAT_DSMSCIS);
869 
870             InfoTable = AcpiDmTableInfoCdat2;
871             break;
872 
873         case ACPI_CDAT_TYPE_DSIS:
874             DbgPrint (ASL_DEBUG_OUTPUT, "2) Offset: %X ", Offset);
875             SubtableLength = sizeof (ACPI_CDAT_DSIS);
876             DbgPrint (ASL_DEBUG_OUTPUT, "1) input pointer: %p\n", Table);
877             Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table, Offset);
878             DbgPrint (ASL_DEBUG_OUTPUT, "1) output pointers: %p, %p, Offset: %X\n",
879                 Table, Subtable, Offset);
880             DbgPrint (ASL_DEBUG_OUTPUT, "3) Offset: %X\n", Offset);
881 
882             InfoTable = AcpiDmTableInfoCdat3;
883             break;
884 
885         case ACPI_CDAT_TYPE_DSEMTS:
886             Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table, Offset);
887             SubtableLength = sizeof (ACPI_CDAT_DSEMTS);
888 
889             InfoTable = AcpiDmTableInfoCdat4;
890             break;
891 
892         case ACPI_CDAT_TYPE_SSLBIS:
893             SubtableLength = Subtable->Length;
894 
895             InfoTable = AcpiDmTableInfoCdat5;
896             Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table, Offset);
897             break;
898 
899         default:
900             fprintf (stderr, "ERROR: Unknown SubtableType: %X\n", Subtable->Type);
901             return;
902         }
903 
904         DbgPrint (ASL_DEBUG_OUTPUT, "SubtableType: %X, Length: %X Actual "
905             "Length: %X Offset: %X tableptr: %p\n", SubtableType,
906             Subtable->Length, SubtableLength, Offset, Table);
907 
908         /*
909          * Do the subtable-specific fields
910          */
911         Status = AcpiDmDumpTable (Length, Offset, Subtable, Offset, InfoTable);
912         if (ACPI_FAILURE (Status))
913         {
914             return;
915         }
916 
917         DbgPrint (ASL_DEBUG_OUTPUT, "Subtable Type: %X, Offset: %X, SubtableLength: %X\n",
918             SubtableType, Offset, SubtableLength);
919 
920         /* Additional sub-subtables, dependent on the main subtable type */
921 
922         switch (SubtableType)
923         {
924         case ACPI_CDAT_TYPE_SSLBIS:
925             Offset += sizeof (ACPI_CDAT_SSLBIS);
926             Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table,
927                 Offset);
928 
929             DbgPrint (ASL_DEBUG_OUTPUT, "Case SSLBIS, Offset: %X, SubtableLength: %X "
930                 "Subtable->Length %X\n", Offset, SubtableLength, Subtable->Length);
931 
932             /* Generate the total length of all the SSLBE entries */
933 
934             EntriesLength = SubtableLength - sizeof (ACPI_CDAT_HEADER) -
935                 sizeof (ACPI_CDAT_SSLBIS);
936             DbgPrint (ASL_DEBUG_OUTPUT, "EntriesLength: %X, Offset: %X, Table->Length: %X\n",
937                 EntriesLength, Offset, Table->Length);
938 
939             /* Do each of the SSLBE Entries */
940 
941             while ((EntriesLength > 0) && (Offset < Table->Length))
942             {
943                 AcpiOsPrintf ("\n");
944 
945                 Status = AcpiDmDumpTable (Length, Offset, Subtable, Offset,
946                     AcpiDmTableInfoCdatEntries);
947                 if (ACPI_FAILURE (Status))
948                 {
949                     return;
950                 }
951 
952                 EntriesLength -= sizeof (ACPI_CDAT_SSLBE);
953                 Offset += sizeof (ACPI_CDAT_SSLBE);
954                 Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table, Offset);
955             }
956 
957             SubtableLength = 0;
958             break;
959 
960         default:
961             break;
962         }
963 
964         DbgPrint (ASL_DEBUG_OUTPUT, "Offset: %X, Subtable Length: %X\n",
965             Offset, SubtableLength);
966 
967         /* Point to next subtable */
968 
969         Offset += SubtableLength;
970         Subtable = ACPI_ADD_PTR (ACPI_CDAT_HEADER, Table, Offset);
971     }
972 
973     return;
974 }
975 
976 
977 /*******************************************************************************
978  *
979  * FUNCTION:    AcpiDmDumpCedt
980  *
981  * PARAMETERS:  Table               - A CEDT table
982  *
983  * RETURN:      None
984  *
985  * DESCRIPTION: Format the contents of a CEDT. This table type consists
986  *              of an open-ended number of subtables.
987  *
988  ******************************************************************************/
989 
990 void
AcpiDmDumpCedt(ACPI_TABLE_HEADER * Table)991 AcpiDmDumpCedt (
992     ACPI_TABLE_HEADER       *Table)
993 {
994     ACPI_STATUS             Status;
995     ACPI_CEDT_HEADER        *Subtable;
996     UINT32                  Length = Table->Length;
997     UINT32                  Offset = sizeof (ACPI_TABLE_CEDT);
998 
999 
1000     /* There is no main table (other than the standard ACPI header) */
1001 
1002     Subtable = ACPI_ADD_PTR (ACPI_CEDT_HEADER, Table, Offset);
1003     while (Offset < Table->Length)
1004     {
1005         /* Common subtable header */
1006 
1007         AcpiOsPrintf ("\n");
1008         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1009             Subtable->Length, AcpiDmTableInfoCedtHdr);
1010         if (ACPI_FAILURE (Status))
1011         {
1012             return;
1013         }
1014 
1015         switch (Subtable->Type)
1016         {
1017         case ACPI_CEDT_TYPE_CHBS:
1018             Status = AcpiDmDumpTable (Length, Offset, Subtable,
1019                 Subtable->Length, AcpiDmTableInfoCedt0);
1020             if (ACPI_FAILURE (Status))
1021             {
1022                 return;
1023             }
1024             break;
1025 
1026         case ACPI_CEDT_TYPE_CFMWS:
1027         {
1028             ACPI_CEDT_CFMWS *ptr = (ACPI_CEDT_CFMWS *) Subtable;
1029             unsigned int i, max;
1030 
1031             if (ptr->InterleaveWays < 8)
1032                 max = 1 << (ptr->InterleaveWays);
1033             else
1034                 max = 3 << (ptr->InterleaveWays - 8);
1035 
1036 	    /* print out table with first "Interleave target" */
1037 
1038             Status = AcpiDmDumpTable (Length, Offset, Subtable,
1039                 Subtable->Length, AcpiDmTableInfoCedt1);
1040             if (ACPI_FAILURE (Status))
1041             {
1042                 return;
1043             }
1044 
1045             /* Now, print out any interleave targets beyond the first. */
1046 
1047             for (i = 1; i < max; i++)
1048             {
1049                 unsigned int loc_offset = Offset + (i * 4) + ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveTargets);
1050                 unsigned int *trg = &(ptr->InterleaveTargets[i]);
1051 
1052                 Status = AcpiDmDumpTable (Length, loc_offset, trg,
1053                         Subtable->Length, AcpiDmTableInfoCedt1_te);
1054                 if (ACPI_FAILURE (Status))
1055                 {
1056                     return;
1057                 }
1058             }
1059             break;
1060         }
1061 
1062         case ACPI_CEDT_TYPE_CXIMS:
1063         {
1064             ACPI_CEDT_CXIMS *ptr = (ACPI_CEDT_CXIMS *) Subtable;
1065             unsigned int i, max = ptr->NrXormaps;
1066 
1067             /* print out table with first "XOR Map" */
1068 
1069             Status = AcpiDmDumpTable (Length, Offset, Subtable,
1070                 Subtable->Length, AcpiDmTableInfoCedt2);
1071             if (ACPI_FAILURE (Status))
1072             {
1073                 return;
1074             }
1075 
1076             /* Now, print out any XOR Map beyond the first. */
1077 
1078             for (i = 1; i < max; i++)
1079             {
1080                 unsigned int loc_offset = Offset + (i * 1) + ACPI_OFFSET (ACPI_CEDT_CXIMS, XormapList);
1081                 UINT64 *trg = &(ptr->XormapList[i]);
1082 
1083                 Status = AcpiDmDumpTable (Length, loc_offset, trg,
1084                         Subtable->Length, AcpiDmTableInfoCedt2_te);
1085                 if (ACPI_FAILURE (Status))
1086                 {
1087                     return;
1088                 }
1089             }
1090             break;
1091         }
1092 
1093         default:
1094             AcpiOsPrintf ("\n**** Unknown CEDT subtable type 0x%X\n\n",
1095                 Subtable->Type);
1096 
1097             /* Attempt to continue */
1098             if (!Subtable->Length)
1099             {
1100                 AcpiOsPrintf ("Invalid zero length subtable\n");
1101                 return;
1102             }
1103         }
1104 
1105         /* Point to next subtable */
1106         Offset += Subtable->Length;
1107         Subtable = ACPI_ADD_PTR (ACPI_CEDT_HEADER, Subtable,
1108             Subtable->Length);
1109     }
1110 }
1111 
1112 /*******************************************************************************
1113  *
1114  * FUNCTION:    AcpiDmDumpCpep
1115  *
1116  * PARAMETERS:  Table               - A CPEP table
1117  *
1118  * RETURN:      None
1119  *
1120  * DESCRIPTION: Format the contents of a CPEP. This table type consists
1121  *              of an open-ended number of subtables.
1122  *
1123  ******************************************************************************/
1124 
1125 void
AcpiDmDumpCpep(ACPI_TABLE_HEADER * Table)1126 AcpiDmDumpCpep (
1127     ACPI_TABLE_HEADER       *Table)
1128 {
1129     ACPI_STATUS             Status;
1130     ACPI_CPEP_POLLING       *Subtable;
1131     UINT32                  Length = Table->Length;
1132     UINT32                  Offset = sizeof (ACPI_TABLE_CPEP);
1133 
1134 
1135     /* Main table */
1136 
1137     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoCpep);
1138     if (ACPI_FAILURE (Status))
1139     {
1140         return;
1141     }
1142 
1143     /* Subtables */
1144 
1145     Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
1146     while (Offset < Table->Length)
1147     {
1148         AcpiOsPrintf ("\n");
1149         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1150             Subtable->Header.Length, AcpiDmTableInfoCpep0);
1151         if (ACPI_FAILURE (Status))
1152         {
1153             return;
1154         }
1155 
1156         /* Point to next subtable */
1157 
1158         Offset += Subtable->Header.Length;
1159         Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Subtable,
1160             Subtable->Header.Length);
1161     }
1162 }
1163 
1164 
1165 /*******************************************************************************
1166  *
1167  * FUNCTION:    AcpiDmDumpCsrt
1168  *
1169  * PARAMETERS:  Table               - A CSRT table
1170  *
1171  * RETURN:      None
1172  *
1173  * DESCRIPTION: Format the contents of a CSRT. This table type consists
1174  *              of an open-ended number of subtables.
1175  *
1176  ******************************************************************************/
1177 
1178 void
AcpiDmDumpCsrt(ACPI_TABLE_HEADER * Table)1179 AcpiDmDumpCsrt (
1180     ACPI_TABLE_HEADER       *Table)
1181 {
1182     ACPI_STATUS             Status;
1183     ACPI_CSRT_GROUP         *Subtable;
1184     ACPI_CSRT_SHARED_INFO   *SharedInfoTable;
1185     ACPI_CSRT_DESCRIPTOR    *SubSubtable;
1186     UINT32                  Length = Table->Length;
1187     UINT32                  Offset = sizeof (ACPI_TABLE_CSRT);
1188     UINT32                  SubOffset;
1189     UINT32                  SubSubOffset;
1190     UINT32                  InfoLength;
1191 
1192 
1193     /* The main table only contains the ACPI header, thus already handled */
1194 
1195     /* Subtables (Resource Groups) */
1196 
1197     Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset);
1198     while (Offset < Table->Length)
1199     {
1200         /* Resource group subtable */
1201 
1202         AcpiOsPrintf ("\n");
1203         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1204             Subtable->Length, AcpiDmTableInfoCsrt0);
1205         if (ACPI_FAILURE (Status))
1206         {
1207             return;
1208         }
1209 
1210         /* Shared info subtable (One per resource group) */
1211 
1212         SubOffset = sizeof (ACPI_CSRT_GROUP);
1213         SharedInfoTable = ACPI_ADD_PTR (ACPI_CSRT_SHARED_INFO, Table,
1214             Offset + SubOffset);
1215 
1216         AcpiOsPrintf ("\n");
1217         Status = AcpiDmDumpTable (Length, Offset + SubOffset, SharedInfoTable,
1218             sizeof (ACPI_CSRT_SHARED_INFO), AcpiDmTableInfoCsrt1);
1219         if (ACPI_FAILURE (Status))
1220         {
1221             return;
1222         }
1223 
1224         SubOffset += Subtable->SharedInfoLength;
1225 
1226         /* Sub-Subtables (Resource Descriptors) */
1227 
1228         SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table,
1229             Offset + SubOffset);
1230 
1231         while ((SubOffset < Subtable->Length) &&
1232               ((Offset + SubOffset) < Table->Length))
1233         {
1234             AcpiOsPrintf ("\n");
1235             Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubtable,
1236                 SubSubtable->Length, AcpiDmTableInfoCsrt2);
1237             if (ACPI_FAILURE (Status))
1238             {
1239                 return;
1240             }
1241 
1242             SubSubOffset = sizeof (ACPI_CSRT_DESCRIPTOR);
1243 
1244             /* Resource-specific info buffer */
1245 
1246             InfoLength = SubSubtable->Length - SubSubOffset;
1247             if (InfoLength)
1248             {
1249                 Status = AcpiDmDumpTable (Length,
1250                     Offset + SubOffset + SubSubOffset, Table,
1251                     InfoLength, AcpiDmTableInfoCsrt2a);
1252                 if (ACPI_FAILURE (Status))
1253                 {
1254                     return;
1255                 }
1256             }
1257 
1258             /* Point to next sub-subtable */
1259 
1260             SubOffset += SubSubtable->Length;
1261             SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubtable,
1262                 SubSubtable->Length);
1263         }
1264 
1265         /* Point to next subtable */
1266 
1267         Offset += Subtable->Length;
1268         Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Subtable,
1269             Subtable->Length);
1270     }
1271 }
1272 
1273 
1274 /*******************************************************************************
1275  *
1276  * FUNCTION:    AcpiDmDumpDbg2
1277  *
1278  * PARAMETERS:  Table               - A DBG2 table
1279  *
1280  * RETURN:      None
1281  *
1282  * DESCRIPTION: Format the contents of a DBG2. This table type consists
1283  *              of an open-ended number of subtables.
1284  *
1285  ******************************************************************************/
1286 
1287 void
AcpiDmDumpDbg2(ACPI_TABLE_HEADER * Table)1288 AcpiDmDumpDbg2 (
1289     ACPI_TABLE_HEADER       *Table)
1290 {
1291     ACPI_STATUS             Status;
1292     ACPI_DBG2_DEVICE        *Subtable;
1293     UINT32                  Length = Table->Length;
1294     UINT32                  Offset = sizeof (ACPI_TABLE_DBG2);
1295     UINT32                  i;
1296     UINT32                  ArrayOffset;
1297     UINT32                  AbsoluteOffset;
1298     UINT8                   *Array;
1299 
1300 
1301     /* Main table */
1302 
1303     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDbg2);
1304     if (ACPI_FAILURE (Status))
1305     {
1306         return;
1307     }
1308 
1309     /* Subtables */
1310 
1311     Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
1312     while (Offset < Table->Length)
1313     {
1314         AcpiOsPrintf ("\n");
1315         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1316             Subtable->Length, AcpiDmTableInfoDbg2Device);
1317         if (ACPI_FAILURE (Status))
1318         {
1319             return;
1320         }
1321 
1322         /* Dump the BaseAddress array */
1323 
1324         for (i = 0; i < Subtable->RegisterCount; i++)
1325         {
1326             ArrayOffset = Subtable->BaseAddressOffset +
1327                 (sizeof (ACPI_GENERIC_ADDRESS) * i);
1328             AbsoluteOffset = Offset + ArrayOffset;
1329             Array = (UINT8 *) Subtable + ArrayOffset;
1330 
1331             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
1332                 Subtable->Length, AcpiDmTableInfoDbg2Addr);
1333             if (ACPI_FAILURE (Status))
1334             {
1335                 return;
1336             }
1337         }
1338 
1339         /* Dump the AddressSize array */
1340 
1341         for (i = 0; i < Subtable->RegisterCount; i++)
1342         {
1343             ArrayOffset = Subtable->AddressSizeOffset +
1344                 (sizeof (UINT32) * i);
1345             AbsoluteOffset = Offset + ArrayOffset;
1346             Array = (UINT8 *) Subtable + ArrayOffset;
1347 
1348             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
1349                 Subtable->Length, AcpiDmTableInfoDbg2Size);
1350             if (ACPI_FAILURE (Status))
1351             {
1352                 return;
1353             }
1354         }
1355 
1356         /* Dump the Namestring (required) */
1357 
1358         AcpiOsPrintf ("\n");
1359         ArrayOffset = Subtable->NamepathOffset;
1360         AbsoluteOffset = Offset + ArrayOffset;
1361         Array = (UINT8 *) Subtable + ArrayOffset;
1362 
1363         Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
1364             Subtable->Length, AcpiDmTableInfoDbg2Name);
1365         if (ACPI_FAILURE (Status))
1366         {
1367             return;
1368         }
1369 
1370         /* Dump the OemData (optional) */
1371 
1372         if (Subtable->OemDataOffset)
1373         {
1374             Status = AcpiDmDumpTable (Length, Subtable->OemDataOffset,
1375                 Subtable, Subtable->OemDataLength,
1376                 AcpiDmTableInfoDbg2OemData);
1377             if (ACPI_FAILURE (Status))
1378             {
1379                 return;
1380             }
1381         }
1382 
1383         /* Point to next subtable */
1384 
1385         Offset += Subtable->Length;
1386         Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Subtable,
1387             Subtable->Length);
1388     }
1389 }
1390 
1391 
1392 /*******************************************************************************
1393  *
1394  * FUNCTION:    AcpiDmDumpDmar
1395  *
1396  * PARAMETERS:  Table               - A DMAR table
1397  *
1398  * RETURN:      None
1399  *
1400  * DESCRIPTION: Format the contents of a DMAR. This table type consists
1401  *              of an open-ended number of subtables.
1402  *
1403  ******************************************************************************/
1404 
1405 void
AcpiDmDumpDmar(ACPI_TABLE_HEADER * Table)1406 AcpiDmDumpDmar (
1407     ACPI_TABLE_HEADER       *Table)
1408 {
1409     ACPI_STATUS             Status;
1410     ACPI_DMAR_HEADER        *Subtable;
1411     UINT32                  Length = Table->Length;
1412     UINT32                  Offset = sizeof (ACPI_TABLE_DMAR);
1413     ACPI_DMTABLE_INFO       *InfoTable;
1414     ACPI_DMAR_DEVICE_SCOPE  *ScopeTable;
1415     UINT32                  ScopeOffset;
1416     UINT8                   *PciPath;
1417     UINT32                  PathOffset;
1418 
1419 
1420     /* Main table */
1421 
1422     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar);
1423     if (ACPI_FAILURE (Status))
1424     {
1425         return;
1426     }
1427 
1428     /* Subtables */
1429 
1430     Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
1431     while (Offset < Table->Length)
1432     {
1433         /* Common subtable header */
1434 
1435         AcpiOsPrintf ("\n");
1436         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1437             Subtable->Length, AcpiDmTableInfoDmarHdr);
1438         if (ACPI_FAILURE (Status))
1439         {
1440             return;
1441         }
1442 
1443         AcpiOsPrintf ("\n");
1444 
1445         switch (Subtable->Type)
1446         {
1447         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1448 
1449             InfoTable = AcpiDmTableInfoDmar0;
1450             ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT);
1451             break;
1452 
1453         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1454 
1455             InfoTable = AcpiDmTableInfoDmar1;
1456             ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY);
1457             break;
1458 
1459         case ACPI_DMAR_TYPE_ROOT_ATS:
1460 
1461             InfoTable = AcpiDmTableInfoDmar2;
1462             ScopeOffset = sizeof (ACPI_DMAR_ATSR);
1463             break;
1464 
1465         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1466 
1467             InfoTable = AcpiDmTableInfoDmar3;
1468             ScopeOffset = sizeof (ACPI_DMAR_RHSA);
1469             break;
1470 
1471         case ACPI_DMAR_TYPE_NAMESPACE:
1472 
1473             InfoTable = AcpiDmTableInfoDmar4;
1474             ScopeOffset = sizeof (ACPI_DMAR_ANDD);
1475             break;
1476 
1477         case ACPI_DMAR_TYPE_SATC:
1478 
1479             InfoTable = AcpiDmTableInfoDmar5;
1480             ScopeOffset = sizeof (ACPI_DMAR_SATC);
1481             break;
1482 
1483         case ACPI_DMAR_TYPE_SIDP:
1484 
1485             InfoTable = AcpiDmTableInfoDmar6;
1486             ScopeOffset = sizeof (ACPI_DMAR_SIDP);
1487             break;
1488 
1489         default:
1490 
1491             AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n",
1492                 Subtable->Type);
1493             return;
1494         }
1495 
1496         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1497             Subtable->Length, InfoTable);
1498         if (ACPI_FAILURE (Status))
1499         {
1500             return;
1501         }
1502 
1503         /*
1504          * Dump the optional device scope entries
1505          */
1506         if ((Subtable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
1507             (Subtable->Type == ACPI_DMAR_TYPE_NAMESPACE))
1508         {
1509             /* These types do not support device scopes */
1510 
1511             goto NextSubtable;
1512         }
1513 
1514         ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable, ScopeOffset);
1515         while (ScopeOffset < Subtable->Length)
1516         {
1517             AcpiOsPrintf ("\n");
1518             Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
1519                 ScopeTable->Length, AcpiDmTableInfoDmarScope);
1520             if (ACPI_FAILURE (Status))
1521             {
1522                 return;
1523             }
1524             AcpiOsPrintf ("\n");
1525 
1526             /* Dump the PCI Path entries for this device scope */
1527 
1528             PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */
1529 
1530             PciPath = ACPI_ADD_PTR (UINT8, ScopeTable,
1531                 sizeof (ACPI_DMAR_DEVICE_SCOPE));
1532 
1533             while (PathOffset < ScopeTable->Length)
1534             {
1535                 AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2,
1536                     "PCI Path");
1537                 AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]);
1538 
1539                 /* Point to next PCI Path entry */
1540 
1541                 PathOffset += 2;
1542                 PciPath += 2;
1543                 AcpiOsPrintf ("\n");
1544             }
1545 
1546             /* Point to next device scope entry */
1547 
1548             ScopeOffset += ScopeTable->Length;
1549             ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE,
1550                 ScopeTable, ScopeTable->Length);
1551         }
1552 
1553 NextSubtable:
1554         /* Point to next subtable */
1555 
1556         Offset += Subtable->Length;
1557         Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Subtable,
1558             Subtable->Length);
1559     }
1560 }
1561 
1562 
1563 /*******************************************************************************
1564  *
1565  * FUNCTION:    AcpiDmDumpDrtm
1566  *
1567  * PARAMETERS:  Table               - A DRTM table
1568  *
1569  * RETURN:      None
1570  *
1571  * DESCRIPTION: Format the contents of a DRTM.
1572  *
1573  ******************************************************************************/
1574 
1575 void
AcpiDmDumpDrtm(ACPI_TABLE_HEADER * Table)1576 AcpiDmDumpDrtm (
1577     ACPI_TABLE_HEADER       *Table)
1578 {
1579     ACPI_STATUS             Status;
1580     UINT32                  Offset;
1581     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
1582     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
1583     ACPI_DRTM_DPS_ID        *DrtmDps;
1584     UINT32                  Count;
1585 
1586 
1587     /* Main table */
1588 
1589     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
1590         AcpiDmTableInfoDrtm);
1591     if (ACPI_FAILURE (Status))
1592     {
1593         return;
1594     }
1595 
1596     Offset = sizeof (ACPI_TABLE_DRTM);
1597 
1598     /* Sub-tables */
1599 
1600     /* Dump ValidatedTable length */
1601 
1602     DrtmVtl = ACPI_ADD_PTR (ACPI_DRTM_VTABLE_LIST, Table, Offset);
1603     AcpiOsPrintf ("\n");
1604     Status = AcpiDmDumpTable (Table->Length, Offset,
1605         DrtmVtl, ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables),
1606         AcpiDmTableInfoDrtm0);
1607     if (ACPI_FAILURE (Status))
1608     {
1609             return;
1610     }
1611 
1612     Offset += ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables);
1613 
1614     /* Dump Validated table addresses */
1615 
1616     Count = 0;
1617     while ((Offset < Table->Length) &&
1618             (DrtmVtl->ValidatedTableCount > Count))
1619     {
1620         Status = AcpiDmDumpTable (Table->Length, Offset,
1621             ACPI_ADD_PTR (void, Table, Offset), sizeof (UINT64),
1622             AcpiDmTableInfoDrtm0a);
1623         if (ACPI_FAILURE (Status))
1624         {
1625             return;
1626         }
1627 
1628         Offset += sizeof (UINT64);
1629         Count++;
1630     }
1631 
1632     /* Dump ResourceList length */
1633 
1634     DrtmRl = ACPI_ADD_PTR (ACPI_DRTM_RESOURCE_LIST, Table, Offset);
1635     AcpiOsPrintf ("\n");
1636     Status = AcpiDmDumpTable (Table->Length, Offset,
1637         DrtmRl, ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources),
1638         AcpiDmTableInfoDrtm1);
1639     if (ACPI_FAILURE (Status))
1640     {
1641         return;
1642     }
1643 
1644     Offset += ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources);
1645 
1646     /* Dump the Resource List */
1647 
1648     Count = 0;
1649     while ((Offset < Table->Length) &&
1650            (DrtmRl->ResourceCount > Count))
1651     {
1652         Status = AcpiDmDumpTable (Table->Length, Offset,
1653             ACPI_ADD_PTR (void, Table, Offset),
1654             sizeof (ACPI_DRTM_RESOURCE), AcpiDmTableInfoDrtm1a);
1655         if (ACPI_FAILURE (Status))
1656         {
1657             return;
1658         }
1659 
1660         Offset += sizeof (ACPI_DRTM_RESOURCE);
1661         Count++;
1662     }
1663 
1664     /* Dump DPS */
1665 
1666     DrtmDps = ACPI_ADD_PTR (ACPI_DRTM_DPS_ID, Table, Offset);
1667     AcpiOsPrintf ("\n");
1668     (void) AcpiDmDumpTable (Table->Length, Offset,
1669         DrtmDps, sizeof (ACPI_DRTM_DPS_ID), AcpiDmTableInfoDrtm2);
1670 }
1671 
1672 
1673 /*******************************************************************************
1674  *
1675  * FUNCTION:    AcpiDmDumpDtpr
1676  *
1677  * PARAMETERS:  Table               - A DTPR table
1678  *
1679  * RETURN:      None
1680  *
1681  * DESCRIPTION: Format the contents of a DTPR.
1682  *
1683  ******************************************************************************/
1684 
1685 void
AcpiDmDumpDtpr(ACPI_TABLE_HEADER * Table)1686 AcpiDmDumpDtpr (
1687     ACPI_TABLE_HEADER       *Table)
1688 {
1689     ACPI_STATUS                Status;
1690     ACPI_TPR_ARRAY             *TprArr;
1691     ACPI_TPR_INSTANCE          *TprInstance;
1692     ACPI_TPR_AUX_SR            *TprAuxSr;
1693     ACPI_TPR_SERIALIZE_REQUEST *TprSerializeRequest;
1694     UINT32                     i = 0, j, InsCnt, TprRefCnt;
1695     UINT32                     Offset = sizeof(ACPI_TABLE_DTPR);
1696 
1697     /* Main table */
1698 
1699     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoDtpr);
1700     if (ACPI_FAILURE (Status))
1701     {
1702         return;
1703     }
1704 
1705     /* Subtables */
1706 
1707     while (Offset < Table->Length)
1708     {
1709         InsCnt = ((ACPI_TABLE_DTPR*) Table)->InsCnt;
1710 
1711         for (i = 0; i < InsCnt; i++)
1712         {
1713             TprInstance = ACPI_ADD_PTR(ACPI_TPR_INSTANCE, Table, Offset);
1714             Status = AcpiDmDumpTable(Table->Length, Offset, TprInstance,
1715                                      sizeof(ACPI_TPR_INSTANCE), AcpiDmTableInfoDtprInstance);
1716             if (ACPI_FAILURE (Status))
1717             {
1718                 return;
1719             }
1720 
1721                 /* Each of the TPR instances must have the same number of TPRs*/
1722             TprRefCnt = TprInstance->TprCnt;
1723 
1724             Offset += sizeof(ACPI_TPR_INSTANCE);
1725 
1726             if (TprInstance->TprCnt < 2)
1727             {
1728                 AcpiOsPrintf("TPR Instance No.%d has invalid number of TPRs.\n"
1729                              "There should be at least 2 of them, but there is %d.",
1730                              i, TprInstance->TprCnt);
1731                 return;
1732             }
1733             else
1734             {
1735                 if (TprInstance->TprCnt != TprRefCnt)
1736                 {
1737                     AcpiOsPrintf("Each of TPR instances should have equal\n"
1738                                  "number of TPRs. TprInstance No.%d has %d TPRs"
1739                                  ", while the reference TPR instance has %d.\n",
1740                                  i, TprInstance->TprCnt, TprRefCnt);
1741                     return;
1742                 }
1743             }
1744 
1745             for (j = 0; j < TprInstance->TprCnt; j++)
1746             {
1747                 TprArr = ACPI_ADD_PTR(ACPI_TPR_ARRAY, Table, Offset);
1748                 Status = AcpiDmDumpTable(Table->Length, Offset, TprArr,
1749                                          sizeof(ACPI_TPR_ARRAY), AcpiDmTableInfoDtprArr);
1750                 if (ACPI_FAILURE (Status))
1751                 {
1752                     return;
1753                 }
1754 
1755                 Offset += sizeof(ACPI_TPR_ARRAY);
1756             }
1757         }
1758 
1759         TprAuxSr = ACPI_ADD_PTR(ACPI_TPR_AUX_SR, Table, Offset);
1760         Status = AcpiDmDumpTable(Table->Length, Offset, TprAuxSr,
1761                                  sizeof(ACPI_TPR_AUX_SR), AcpiDmTableInfoDtprSerializeReq0);
1762 
1763         Offset += sizeof(ACPI_TPR_AUX_SR);
1764 
1765         for (i = 0; i < TprAuxSr->SrlCnt; i++)
1766         {
1767             TprSerializeRequest = ACPI_ADD_PTR(ACPI_TPR_SERIALIZE_REQUEST,
1768                                                Table, Offset);
1769             Status = AcpiDmDumpTable(Table->Length, Offset, TprSerializeRequest,
1770                                      sizeof(ACPI_TPR_SERIALIZE_REQUEST), AcpiDmTableInfoDtprSerializeReq1);
1771             if (ACPI_FAILURE (Status))
1772             {
1773                 return;
1774             }
1775 
1776             Offset += sizeof(ACPI_TPR_SERIALIZE_REQUEST);
1777         }
1778     }
1779 }
1780 
1781 
1782 /*******************************************************************************
1783  *
1784  * FUNCTION:    AcpiDmDumpEinj
1785  *
1786  * PARAMETERS:  Table               - A EINJ table
1787  *
1788  * RETURN:      None
1789  *
1790  * DESCRIPTION: Format the contents of a EINJ. This table type consists
1791  *              of an open-ended number of subtables.
1792  *
1793  ******************************************************************************/
1794 
1795 void
AcpiDmDumpEinj(ACPI_TABLE_HEADER * Table)1796 AcpiDmDumpEinj (
1797     ACPI_TABLE_HEADER       *Table)
1798 {
1799     ACPI_STATUS             Status;
1800     ACPI_WHEA_HEADER        *Subtable;
1801     UINT32                  Length = Table->Length;
1802     UINT32                  Offset = sizeof (ACPI_TABLE_EINJ);
1803 
1804 
1805     /* Main table */
1806 
1807     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj);
1808     if (ACPI_FAILURE (Status))
1809     {
1810         return;
1811     }
1812 
1813     /* Subtables */
1814 
1815     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
1816     while (Offset < Table->Length)
1817     {
1818         AcpiOsPrintf ("\n");
1819         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1820             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
1821         if (ACPI_FAILURE (Status))
1822         {
1823             return;
1824         }
1825 
1826         /* Point to next subtable (each subtable is of fixed length) */
1827 
1828         Offset += sizeof (ACPI_WHEA_HEADER);
1829         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
1830             sizeof (ACPI_WHEA_HEADER));
1831     }
1832 }
1833 
1834 
1835 /*******************************************************************************
1836  *
1837  * FUNCTION:    AcpiDmDumpErdt
1838  *
1839  * PARAMETERS:  Table               - A ERDT table
1840  *
1841  * RETURN:      None
1842  *
1843  * DESCRIPTION: Format the contents of a ERDT. This table type consists
1844  *              of an open-ended number of subtables.
1845  *
1846  ******************************************************************************/
1847 
1848 void
AcpiDmDumpErdt(ACPI_TABLE_HEADER * Table)1849 AcpiDmDumpErdt (
1850     ACPI_TABLE_HEADER       *Table)
1851 {
1852     ACPI_STATUS             Status;
1853     ACPI_SUBTBL_HDR_16      *Subtable, *Subsubtable;
1854     ACPI_ERDT_DACD_PATHS    *ScopeTable;
1855     UINT32                  Offset = sizeof (ACPI_TABLE_ERDT);
1856     UINT32                  Suboffset;
1857     UINT32                  ScopeOffset;
1858     UINT32                  SubsubtableLength = 0;
1859     ACPI_DMTABLE_INFO       *InfoTable, *TrailEntries, *DacdEntries;
1860     UINT32                  NumTrailers = 0;
1861 
1862     /* Main table */
1863 
1864     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoErdt);
1865     if (ACPI_FAILURE (Status))
1866     {
1867         return;
1868     }
1869 
1870     /* Subtables */
1871     Subtable = ACPI_ADD_PTR (ACPI_SUBTBL_HDR_16, Table, Offset);
1872     while (Offset < Table->Length)
1873     {
1874 
1875         /* Dump common header */
1876 
1877         AcpiOsPrintf ("\n");
1878         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1879             Subtable->Length, AcpiDmTableInfoErdtHdr);
1880         if (ACPI_FAILURE (Status))
1881         {
1882             return;
1883         }
1884 
1885         AcpiOsPrintf ("\n");
1886         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1887             Subtable->Length, AcpiDmTableInfoErdtRmdd);
1888         if (ACPI_FAILURE (Status))
1889         {
1890             return;
1891         }
1892 
1893         /* Subtables of this RMDD table */
1894 
1895         Suboffset = Offset + sizeof(ACPI_ERDT_RMDD);
1896         Subsubtable = ACPI_ADD_PTR (ACPI_SUBTBL_HDR_16, Table, Suboffset);
1897         while (Suboffset < Offset + Subtable->Length)
1898         {
1899             AcpiOsPrintf ("\n");
1900 
1901             TrailEntries = NULL;
1902             DacdEntries = NULL;
1903             switch (Subsubtable->Type)
1904             {
1905             case ACPI_ERDT_TYPE_CACD:
1906                  InfoTable = AcpiDmTableInfoErdtCacd;
1907                  TrailEntries = AcpiDmTableInfoErdtCacdX2apic;
1908                  SubsubtableLength = sizeof(ACPI_ERDT_CACD);
1909                  break;
1910 
1911             case ACPI_ERDT_TYPE_DACD:
1912                  InfoTable = AcpiDmTableInfoErdtDacd;
1913                  DacdEntries = AcpiDmTableInfoErdtDacdScope;
1914                  SubsubtableLength = sizeof(ACPI_ERDT_DACD);
1915                  break;
1916 
1917             case ACPI_ERDT_TYPE_CMRC:
1918                  InfoTable = AcpiDmTableInfoErdtCmrc;
1919                  break;
1920 
1921             case ACPI_ERDT_TYPE_MMRC:
1922                  InfoTable = AcpiDmTableInfoErdtMmrc;
1923                  TrailEntries = AcpiDmTableInfoErdtMmrcCorrFactor;
1924                  SubsubtableLength = sizeof(ACPI_ERDT_MMRC);
1925                  break;
1926 
1927             case ACPI_ERDT_TYPE_MARC:
1928                  InfoTable = AcpiDmTableInfoErdtMarc;
1929                  break;
1930 
1931             case ACPI_ERDT_TYPE_CARC:
1932                  InfoTable = AcpiDmTableInfoErdtCarc;
1933                  break;
1934 
1935             case ACPI_ERDT_TYPE_CMRD:
1936                  InfoTable = AcpiDmTableInfoErdtCmrd;
1937                  break;
1938 
1939             case ACPI_ERDT_TYPE_IBRD:
1940                  InfoTable = AcpiDmTableInfoErdtIbrd;
1941                  TrailEntries = AcpiDmTableInfoErdtIbrdCorrFactor;
1942                  SubsubtableLength = sizeof(ACPI_ERDT_IBRD);
1943                  break;
1944 
1945             case ACPI_ERDT_TYPE_IBAD:
1946                  InfoTable = AcpiDmTableInfoErdtIbad;
1947                  break;
1948 
1949             case ACPI_ERDT_TYPE_CARD:
1950                  InfoTable = AcpiDmTableInfoErdtCard;
1951                  break;
1952 
1953             default:
1954                 AcpiOsPrintf ("\n**** Unknown RMDD subtable type 0x%X\n",
1955                     Subsubtable->Type);
1956 
1957                 /* Attempt to continue */
1958 
1959                 if (!Subsubtable->Length)
1960                 {
1961                     AcpiOsPrintf ("Invalid zero length subtable\n");
1962                     return;
1963                 }
1964                 goto NextSubsubtable;
1965             }
1966 
1967             /* Dump subtable header */
1968 
1969             Status = AcpiDmDumpTable (Table->Length, Suboffset, Subsubtable,
1970                 Subsubtable->Length, AcpiDmTableInfoErdtHdr);
1971             if (ACPI_FAILURE (Status))
1972             {
1973                 return;
1974             }
1975 
1976             /* Dump subtable body */
1977 
1978             Status = AcpiDmDumpTable (Table->Length, Suboffset, Subsubtable,
1979                 Subsubtable->Length, InfoTable);
1980             if (ACPI_FAILURE (Status))
1981             {
1982                 return;
1983             }
1984 
1985             /* CACD, MMRC, and IBRD subtables have simple flex array at end */
1986 
1987             if (TrailEntries)
1988             {
1989                 NumTrailers = 0;
1990                 while (NumTrailers < Subsubtable->Length - SubsubtableLength)
1991                 {
1992 
1993                     /* Dump one flex array element */
1994 
1995                     Status = AcpiDmDumpTable (Table->Length, Suboffset +
1996                         SubsubtableLength + NumTrailers,
1997                         ACPI_ADD_PTR (ACPI_SUBTBL_HDR_16, Subsubtable,
1998                             SubsubtableLength + NumTrailers),
1999                         sizeof(UINT32), TrailEntries);
2000                     if (ACPI_FAILURE (Status))
2001                     {
2002                         return;
2003                     }
2004                     NumTrailers += sizeof(UINT32);
2005                 }
2006             }
2007 
2008             /* DACD subtable has flex array of device agent structures */
2009 
2010             if (DacdEntries) {
2011                  ScopeOffset = Suboffset + SubsubtableLength;
2012                  ScopeTable = ACPI_ADD_PTR (ACPI_ERDT_DACD_PATHS,
2013                      Subsubtable, SubsubtableLength);
2014                  while (ScopeOffset < Suboffset + Subsubtable->Length)
2015                  {
2016                      /* Dump one device agent structure */
2017 
2018                      AcpiOsPrintf ("\n");
2019                      Status = AcpiDmDumpTable (Table->Length, ScopeOffset,
2020                          ScopeTable, ScopeTable->Header.Length, DacdEntries);
2021                      if (ACPI_FAILURE (Status))
2022                      {
2023                          return;
2024                      }
2025 
2026                      /* Flex array of UINT8 for device path */
2027 
2028                      NumTrailers = 0;
2029                      while (NumTrailers < ScopeTable->Header.Length - sizeof(ACPI_ERDT_DACD_PATHS))
2030                      {
2031                          /* Dump one UINT8 of the device path */
2032 
2033                          Status = AcpiDmDumpTable (Table->Length, ScopeOffset +
2034                              sizeof(ACPI_ERDT_DACD_PATHS) + NumTrailers,
2035                              ACPI_ADD_PTR (ACPI_SUBTBL_HDR_16, ScopeTable,
2036                                  sizeof(*ScopeTable) + NumTrailers),
2037                              sizeof(UINT32), AcpiDmTableInfoErdtDacdPath);
2038                          if (ACPI_FAILURE (Status))
2039                          {
2040                              return;
2041                          }
2042                          NumTrailers++;
2043                      }
2044 
2045                      ScopeOffset += ScopeTable->Header.Length;
2046                      ScopeTable = ACPI_ADD_PTR (ACPI_ERDT_DACD_PATHS,
2047                          ScopeTable, ScopeTable->Header.Length);
2048                  }
2049             }
2050 NextSubsubtable:
2051             Suboffset += Subsubtable->Length;
2052             Subsubtable = ACPI_ADD_PTR (ACPI_SUBTBL_HDR_16, Table, Suboffset);
2053         }
2054 
2055         Offset += Subtable->Length;
2056         Subtable = ACPI_ADD_PTR (ACPI_SUBTBL_HDR_16, Subtable,
2057             Subtable->Length);
2058     }
2059 }
2060 
2061 
2062 /*******************************************************************************
2063  *
2064  * FUNCTION:    AcpiDmDumpErst
2065  *
2066  * PARAMETERS:  Table               - A ERST table
2067  *
2068  * RETURN:      None
2069  *
2070  * DESCRIPTION: Format the contents of a ERST. This table type consists
2071  *              of an open-ended number of subtables.
2072  *
2073  ******************************************************************************/
2074 
2075 void
AcpiDmDumpErst(ACPI_TABLE_HEADER * Table)2076 AcpiDmDumpErst (
2077     ACPI_TABLE_HEADER       *Table)
2078 {
2079     ACPI_STATUS             Status;
2080     ACPI_WHEA_HEADER        *Subtable;
2081     UINT32                  Length = Table->Length;
2082     UINT32                  Offset = sizeof (ACPI_TABLE_ERST);
2083 
2084 
2085     /* Main table */
2086 
2087     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst);
2088     if (ACPI_FAILURE (Status))
2089     {
2090         return;
2091     }
2092 
2093     /* Subtables */
2094 
2095     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
2096     while (Offset < Table->Length)
2097     {
2098         AcpiOsPrintf ("\n");
2099         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2100             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
2101         if (ACPI_FAILURE (Status))
2102         {
2103             return;
2104         }
2105 
2106         /* Point to next subtable (each subtable is of fixed length) */
2107 
2108         Offset += sizeof (ACPI_WHEA_HEADER);
2109         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
2110             sizeof (ACPI_WHEA_HEADER));
2111     }
2112 }
2113 
2114 
2115 /*******************************************************************************
2116  *
2117  * FUNCTION:    AcpiDmDumpFpdt
2118  *
2119  * PARAMETERS:  Table               - A FPDT table
2120  *
2121  * RETURN:      None
2122  *
2123  * DESCRIPTION: Format the contents of a FPDT. This table type consists
2124  *              of an open-ended number of subtables.
2125  *
2126  ******************************************************************************/
2127 
2128 void
AcpiDmDumpFpdt(ACPI_TABLE_HEADER * Table)2129 AcpiDmDumpFpdt (
2130     ACPI_TABLE_HEADER       *Table)
2131 {
2132     ACPI_STATUS             Status;
2133     ACPI_FPDT_HEADER        *Subtable;
2134     UINT32                  Length = Table->Length;
2135     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
2136     ACPI_DMTABLE_INFO       *InfoTable;
2137 
2138 
2139     /* There is no main table (other than the standard ACPI header) */
2140 
2141     /* Subtables */
2142 
2143     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
2144     while (Offset < Table->Length)
2145     {
2146         /* Common subtable header */
2147 
2148         AcpiOsPrintf ("\n");
2149         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2150             Subtable->Length, AcpiDmTableInfoFpdtHdr);
2151         if (ACPI_FAILURE (Status))
2152         {
2153             return;
2154         }
2155 
2156         switch (Subtable->Type)
2157         {
2158         case ACPI_FPDT_TYPE_BOOT:
2159 
2160             InfoTable = AcpiDmTableInfoFpdt0;
2161             break;
2162 
2163         case ACPI_FPDT_TYPE_S3PERF:
2164 
2165             InfoTable = AcpiDmTableInfoFpdt1;
2166             break;
2167 
2168         default:
2169 
2170             AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n",
2171                 Subtable->Type);
2172 
2173             /* Attempt to continue */
2174 
2175             if (!Subtable->Length)
2176             {
2177                 AcpiOsPrintf ("Invalid zero length subtable\n");
2178                 return;
2179             }
2180             goto NextSubtable;
2181         }
2182 
2183         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2184             Subtable->Length, InfoTable);
2185         if (ACPI_FAILURE (Status))
2186         {
2187             return;
2188         }
2189 
2190 NextSubtable:
2191         /* Point to next subtable */
2192 
2193         Offset += Subtable->Length;
2194         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable,
2195             Subtable->Length);
2196     }
2197 }
2198 
2199 
2200 /*******************************************************************************
2201  *
2202  * FUNCTION:    AcpiDmDumpGtdt
2203  *
2204  * PARAMETERS:  Table               - A GTDT table
2205  *
2206  * RETURN:      None
2207  *
2208  * DESCRIPTION: Format the contents of a GTDT. This table type consists
2209  *              of an open-ended number of subtables.
2210  *
2211  ******************************************************************************/
2212 
2213 void
AcpiDmDumpGtdt(ACPI_TABLE_HEADER * Table)2214 AcpiDmDumpGtdt (
2215     ACPI_TABLE_HEADER       *Table)
2216 {
2217     ACPI_STATUS             Status;
2218     ACPI_GTDT_HEADER        *Subtable;
2219     UINT32                  Length = Table->Length;
2220     UINT32                  Offset = sizeof (ACPI_TABLE_GTDT);
2221     ACPI_DMTABLE_INFO       *InfoTable;
2222     UINT32                  SubtableLength;
2223     UINT32                  GtCount;
2224     ACPI_GTDT_TIMER_ENTRY   *GtxTable;
2225 
2226 
2227     /* Main table */
2228 
2229     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoGtdt);
2230     if (ACPI_FAILURE (Status))
2231     {
2232         return;
2233     }
2234 
2235     /* Rev 3 fields */
2236 
2237     Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
2238 
2239     if (Table->Revision > 2)
2240     {
2241         SubtableLength = sizeof (ACPI_GTDT_EL2);
2242         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2243             SubtableLength, AcpiDmTableInfoGtdtEl2);
2244         if (ACPI_FAILURE (Status))
2245         {
2246             return;
2247         }
2248         Offset += SubtableLength;
2249     }
2250 
2251     Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
2252 
2253     /* Subtables */
2254 
2255     while (Offset < Table->Length)
2256     {
2257         /* Common subtable header */
2258 
2259         AcpiOsPrintf ("\n");
2260         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2261             Subtable->Length, AcpiDmTableInfoGtdtHdr);
2262         if (ACPI_FAILURE (Status))
2263         {
2264             return;
2265         }
2266 
2267         GtCount = 0;
2268         switch (Subtable->Type)
2269         {
2270         case ACPI_GTDT_TYPE_TIMER_BLOCK:
2271 
2272             SubtableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
2273             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
2274                 Subtable))->TimerCount;
2275 
2276             InfoTable = AcpiDmTableInfoGtdt0;
2277             break;
2278 
2279         case ACPI_GTDT_TYPE_WATCHDOG:
2280 
2281             SubtableLength = sizeof (ACPI_GTDT_WATCHDOG);
2282 
2283             InfoTable = AcpiDmTableInfoGtdt1;
2284             break;
2285 
2286         default:
2287 
2288             /* Cannot continue on unknown type - no length */
2289 
2290             AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n",
2291                 Subtable->Type);
2292             return;
2293         }
2294 
2295         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2296             Subtable->Length, InfoTable);
2297         if (ACPI_FAILURE (Status))
2298         {
2299             return;
2300         }
2301 
2302         /* Point to end of current subtable (each subtable above is of fixed length) */
2303 
2304         Offset += SubtableLength;
2305 
2306         /* If there are any Gt Timer Blocks from above, dump them now */
2307 
2308         if (GtCount)
2309         {
2310             GtxTable = ACPI_ADD_PTR (
2311                 ACPI_GTDT_TIMER_ENTRY, Subtable, SubtableLength);
2312             SubtableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
2313 
2314             while (GtCount)
2315             {
2316                 AcpiOsPrintf ("\n");
2317                 Status = AcpiDmDumpTable (Length, Offset, GtxTable,
2318                     sizeof (ACPI_GTDT_TIMER_ENTRY), AcpiDmTableInfoGtdt0a);
2319                 if (ACPI_FAILURE (Status))
2320                 {
2321                     return;
2322                 }
2323                 Offset += sizeof (ACPI_GTDT_TIMER_ENTRY);
2324                 GtxTable++;
2325                 GtCount--;
2326             }
2327         }
2328 
2329         /* Point to next subtable */
2330 
2331         Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Subtable, SubtableLength);
2332     }
2333 }
2334 
2335 
2336 /*******************************************************************************
2337  *
2338  * FUNCTION:    AcpiDmDumpHest
2339  *
2340  * PARAMETERS:  Table               - A HEST table
2341  *
2342  * RETURN:      None
2343  *
2344  * DESCRIPTION: Format the contents of a HEST. This table type consists
2345  *              of an open-ended number of subtables.
2346  *
2347  ******************************************************************************/
2348 
2349 void
AcpiDmDumpHest(ACPI_TABLE_HEADER * Table)2350 AcpiDmDumpHest (
2351     ACPI_TABLE_HEADER       *Table)
2352 {
2353     ACPI_STATUS             Status;
2354     ACPI_HEST_HEADER        *Subtable;
2355     UINT32                  Length = Table->Length;
2356     UINT32                  Offset = sizeof (ACPI_TABLE_HEST);
2357     ACPI_DMTABLE_INFO       *InfoTable;
2358     UINT32                  SubtableLength;
2359     UINT32                  BankCount;
2360     ACPI_HEST_IA_ERROR_BANK *BankTable;
2361 
2362 
2363     /* Main table */
2364 
2365     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest);
2366     if (ACPI_FAILURE (Status))
2367     {
2368         return;
2369     }
2370 
2371     /* Subtables */
2372 
2373     Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
2374     while (Offset < Table->Length)
2375     {
2376         BankCount = 0;
2377         switch (Subtable->Type)
2378         {
2379         case ACPI_HEST_TYPE_IA32_CHECK:
2380 
2381             InfoTable = AcpiDmTableInfoHest0;
2382             SubtableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
2383             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
2384                 Subtable))->NumHardwareBanks;
2385             break;
2386 
2387         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
2388 
2389             InfoTable = AcpiDmTableInfoHest1;
2390             SubtableLength = sizeof (ACPI_HEST_IA_CORRECTED);
2391             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
2392                 Subtable))->NumHardwareBanks;
2393             break;
2394 
2395         case ACPI_HEST_TYPE_IA32_NMI:
2396 
2397             InfoTable = AcpiDmTableInfoHest2;
2398             SubtableLength = sizeof (ACPI_HEST_IA_NMI);
2399             break;
2400 
2401         case ACPI_HEST_TYPE_AER_ROOT_PORT:
2402 
2403             InfoTable = AcpiDmTableInfoHest6;
2404             SubtableLength = sizeof (ACPI_HEST_AER_ROOT);
2405             break;
2406 
2407         case ACPI_HEST_TYPE_AER_ENDPOINT:
2408 
2409             InfoTable = AcpiDmTableInfoHest7;
2410             SubtableLength = sizeof (ACPI_HEST_AER);
2411             break;
2412 
2413         case ACPI_HEST_TYPE_AER_BRIDGE:
2414 
2415             InfoTable = AcpiDmTableInfoHest8;
2416             SubtableLength = sizeof (ACPI_HEST_AER_BRIDGE);
2417             break;
2418 
2419         case ACPI_HEST_TYPE_GENERIC_ERROR:
2420 
2421             InfoTable = AcpiDmTableInfoHest9;
2422             SubtableLength = sizeof (ACPI_HEST_GENERIC);
2423             break;
2424 
2425         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
2426 
2427             InfoTable = AcpiDmTableInfoHest10;
2428             SubtableLength = sizeof (ACPI_HEST_GENERIC_V2);
2429             break;
2430 
2431         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
2432 
2433             InfoTable = AcpiDmTableInfoHest11;
2434             SubtableLength = sizeof (ACPI_HEST_IA_DEFERRED_CHECK);
2435             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
2436                 Subtable))->NumHardwareBanks;
2437             break;
2438 
2439         default:
2440 
2441             /* Cannot continue on unknown type - no length */
2442 
2443             AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n",
2444                 Subtable->Type);
2445             return;
2446         }
2447 
2448         AcpiOsPrintf ("\n");
2449         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2450             SubtableLength, InfoTable);
2451         if (ACPI_FAILURE (Status))
2452         {
2453             return;
2454         }
2455 
2456         /* Point to end of current subtable (each subtable above is of fixed length) */
2457 
2458         Offset += SubtableLength;
2459 
2460         /* If there are any (fixed-length) Error Banks from above, dump them now */
2461 
2462         if (BankCount)
2463         {
2464             BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, Subtable,
2465                 SubtableLength);
2466             SubtableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
2467 
2468             while (BankCount)
2469             {
2470                 AcpiOsPrintf ("\n");
2471                 Status = AcpiDmDumpTable (Length, Offset, BankTable,
2472                     sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank);
2473                 if (ACPI_FAILURE (Status))
2474                 {
2475                     return;
2476                 }
2477 
2478                 Offset += sizeof (ACPI_HEST_IA_ERROR_BANK);
2479                 BankTable++;
2480                 BankCount--;
2481             }
2482         }
2483 
2484         /* Point to next subtable */
2485 
2486         Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Subtable, SubtableLength);
2487     }
2488 }
2489 
2490 
2491 /*******************************************************************************
2492  *
2493  * FUNCTION:    AcpiDmDumpHmat
2494  *
2495  * PARAMETERS:  Table               - A HMAT table
2496  *
2497  * RETURN:      None
2498  *
2499  * DESCRIPTION: Format the contents of a HMAT.
2500  *
2501  ******************************************************************************/
2502 
2503 void
AcpiDmDumpHmat(ACPI_TABLE_HEADER * Table)2504 AcpiDmDumpHmat (
2505     ACPI_TABLE_HEADER       *Table)
2506 {
2507     ACPI_STATUS             Status;
2508     ACPI_HMAT_STRUCTURE     *HmatStruct;
2509     ACPI_HMAT_LOCALITY      *HmatLocality;
2510     ACPI_HMAT_CACHE         *HmatCache;
2511     UINT32                  Offset;
2512     UINT32                  SubtableOffset;
2513     UINT32                  Length;
2514     ACPI_DMTABLE_INFO       *InfoTable;
2515     UINT32                  i, j;
2516 
2517 
2518     /* Main table */
2519 
2520     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoHmat);
2521     if (ACPI_FAILURE (Status))
2522     {
2523         return;
2524     }
2525     Offset = sizeof (ACPI_TABLE_HMAT);
2526 
2527     while (Offset < Table->Length)
2528     {
2529         AcpiOsPrintf ("\n");
2530 
2531         /* Dump HMAT structure header */
2532 
2533         HmatStruct = ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, Table, Offset);
2534         if (HmatStruct->Length < sizeof (ACPI_HMAT_STRUCTURE))
2535         {
2536             AcpiOsPrintf ("Invalid HMAT structure length\n");
2537             return;
2538         }
2539         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
2540             HmatStruct->Length, AcpiDmTableInfoHmatHdr);
2541         if (ACPI_FAILURE (Status))
2542         {
2543             return;
2544         }
2545 
2546         switch (HmatStruct->Type)
2547         {
2548         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
2549 
2550             InfoTable = AcpiDmTableInfoHmat0;
2551             Length = sizeof (ACPI_HMAT_PROXIMITY_DOMAIN);
2552             break;
2553 
2554         case ACPI_HMAT_TYPE_LOCALITY:
2555 
2556             InfoTable = AcpiDmTableInfoHmat1;
2557             Length = sizeof (ACPI_HMAT_LOCALITY);
2558             break;
2559 
2560         case ACPI_HMAT_TYPE_CACHE:
2561 
2562             InfoTable = AcpiDmTableInfoHmat2;
2563             Length = sizeof (ACPI_HMAT_CACHE);
2564             break;
2565 
2566         default:
2567 
2568             AcpiOsPrintf ("\n**** Unknown HMAT structure type 0x%X\n",
2569                 HmatStruct->Type);
2570 
2571             /* Attempt to continue */
2572 
2573             goto NextSubtable;
2574         }
2575 
2576         /* Dump HMAT structure body */
2577 
2578         if (HmatStruct->Length < Length)
2579         {
2580             AcpiOsPrintf ("Invalid HMAT structure length\n");
2581             return;
2582         }
2583         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
2584             HmatStruct->Length, InfoTable);
2585         if (ACPI_FAILURE (Status))
2586         {
2587             return;
2588         }
2589 
2590         /* Dump HMAT structure additional */
2591 
2592         switch (HmatStruct->Type)
2593         {
2594         case ACPI_HMAT_TYPE_LOCALITY:
2595 
2596             HmatLocality = ACPI_CAST_PTR (ACPI_HMAT_LOCALITY, HmatStruct);
2597             SubtableOffset = sizeof (ACPI_HMAT_LOCALITY);
2598 
2599             /* Dump initiator proximity domains */
2600 
2601             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
2602                 (UINT32)(HmatLocality->NumberOfInitiatorPDs * 4))
2603             {
2604                 AcpiOsPrintf ("Invalid initiator proximity domain number\n");
2605                 return;
2606             }
2607             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
2608             {
2609                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2610                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
2611                     4, AcpiDmTableInfoHmat1a);
2612                 if (ACPI_FAILURE (Status))
2613                 {
2614                     return;
2615                 }
2616 
2617                 SubtableOffset += 4;
2618             }
2619 
2620             /* Dump target proximity domains */
2621 
2622             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
2623                 (UINT32)(HmatLocality->NumberOfTargetPDs * 4))
2624             {
2625                 AcpiOsPrintf ("Invalid target proximity domain number\n");
2626                 return;
2627             }
2628             for (i = 0; i < HmatLocality->NumberOfTargetPDs; i++)
2629             {
2630                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2631                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
2632                     4, AcpiDmTableInfoHmat1b);
2633                 if (ACPI_FAILURE (Status))
2634                 {
2635                     return;
2636                 }
2637 
2638                 SubtableOffset += 4;
2639             }
2640 
2641             /* Dump latency/bandwidth entris */
2642 
2643             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
2644                 (UINT32)(HmatLocality->NumberOfInitiatorPDs *
2645                          HmatLocality->NumberOfTargetPDs * 2))
2646             {
2647                 AcpiOsPrintf ("Invalid latency/bandwidth entry number\n");
2648                 return;
2649             }
2650             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
2651             {
2652                 for (j = 0; j < HmatLocality->NumberOfTargetPDs; j++)
2653                 {
2654                     Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2655                         ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
2656                         2, AcpiDmTableInfoHmat1c);
2657                     if (ACPI_FAILURE(Status))
2658                     {
2659                         return;
2660                     }
2661 
2662                     SubtableOffset += 2;
2663                 }
2664             }
2665             break;
2666 
2667         case ACPI_HMAT_TYPE_CACHE:
2668 
2669             HmatCache = ACPI_CAST_PTR (ACPI_HMAT_CACHE, HmatStruct);
2670             SubtableOffset = sizeof (ACPI_HMAT_CACHE);
2671 
2672             /* Dump SMBIOS handles */
2673 
2674             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
2675                 (UINT32)(HmatCache->NumberOfSMBIOSHandles * 2))
2676             {
2677                 AcpiOsPrintf ("Invalid SMBIOS handle number\n");
2678                 return;
2679             }
2680             for (i = 0; i < HmatCache->NumberOfSMBIOSHandles; i++)
2681             {
2682                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2683                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
2684                     2, AcpiDmTableInfoHmat2a);
2685                 if (ACPI_FAILURE (Status))
2686                 {
2687                     return;
2688                 }
2689 
2690                 SubtableOffset += 2;
2691             }
2692             break;
2693 
2694         default:
2695 
2696             break;
2697         }
2698 
2699 NextSubtable:
2700         /* Point to next HMAT structure subtable */
2701 
2702         Offset += (HmatStruct->Length);
2703     }
2704 }
2705