xref: /illumos-gate/usr/src/cmd/acpi/common/dmtbdump1.c (revision 35786f68)
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 - 2018, 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 "acpi.h"
153 #include "accommon.h"
154 #include "acdisasm.h"
155 #include "actables.h"
156 
157 /* This module used for application-level code only */
158 
159 #define _COMPONENT          ACPI_CA_DISASSEMBLER
160         ACPI_MODULE_NAME    ("dmtbdump1")
161 
162 
163 /*******************************************************************************
164  *
165  * FUNCTION:    AcpiDmDumpAsf
166  *
167  * PARAMETERS:  Table               - A ASF table
168  *
169  * RETURN:      None
170  *
171  * DESCRIPTION: Format the contents of a ASF table
172  *
173  ******************************************************************************/
174 
175 void
AcpiDmDumpAsf(ACPI_TABLE_HEADER * Table)176 AcpiDmDumpAsf (
177     ACPI_TABLE_HEADER       *Table)
178 {
179     ACPI_STATUS             Status;
180     UINT32                  Offset = sizeof (ACPI_TABLE_HEADER);
181     ACPI_ASF_INFO           *Subtable;
182     ACPI_DMTABLE_INFO       *InfoTable;
183     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
184     UINT8                   *DataTable = NULL;
185     UINT32                  DataCount = 0;
186     UINT32                  DataLength = 0;
187     UINT32                  DataOffset = 0;
188     UINT32                  i;
189     UINT8                   Type;
190 
191 
192     /* No main table, only subtables */
193 
194     Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
195     while (Offset < Table->Length)
196     {
197         /* Common subtable header */
198 
199         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
200             Subtable->Header.Length, AcpiDmTableInfoAsfHdr);
201         if (ACPI_FAILURE (Status))
202         {
203             return;
204         }
205 
206         /* The actual type is the lower 7 bits of Type */
207 
208         Type = (UINT8) (Subtable->Header.Type & 0x7F);
209 
210         switch (Type)
211         {
212         case ACPI_ASF_TYPE_INFO:
213 
214             InfoTable = AcpiDmTableInfoAsf0;
215             break;
216 
217         case ACPI_ASF_TYPE_ALERT:
218 
219             InfoTable = AcpiDmTableInfoAsf1;
220             DataInfoTable = AcpiDmTableInfoAsf1a;
221             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ALERT));
222             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->Alerts;
223             DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->DataLength;
224             DataOffset = Offset + sizeof (ACPI_ASF_ALERT);
225             break;
226 
227         case ACPI_ASF_TYPE_CONTROL:
228 
229             InfoTable = AcpiDmTableInfoAsf2;
230             DataInfoTable = AcpiDmTableInfoAsf2a;
231             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_REMOTE));
232             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->Controls;
233             DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->DataLength;
234             DataOffset = Offset + sizeof (ACPI_ASF_REMOTE);
235             break;
236 
237         case ACPI_ASF_TYPE_BOOT:
238 
239             InfoTable = AcpiDmTableInfoAsf3;
240             break;
241 
242         case ACPI_ASF_TYPE_ADDRESS:
243 
244             InfoTable = AcpiDmTableInfoAsf4;
245             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ADDRESS));
246             DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, Subtable)->Devices;
247             DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS);
248             break;
249 
250         default:
251 
252             AcpiOsPrintf ("\n**** Unknown ASF subtable type 0x%X\n",
253                 Subtable->Header.Type);
254             return;
255         }
256 
257         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
258             Subtable->Header.Length, InfoTable);
259         if (ACPI_FAILURE (Status))
260         {
261             return;
262         }
263 
264         /* Dump variable-length extra data */
265 
266         switch (Type)
267         {
268         case ACPI_ASF_TYPE_ALERT:
269         case ACPI_ASF_TYPE_CONTROL:
270 
271             for (i = 0; i < DataCount; i++)
272             {
273                 AcpiOsPrintf ("\n");
274                 Status = AcpiDmDumpTable (Table->Length, DataOffset,
275                     DataTable, DataLength, DataInfoTable);
276                 if (ACPI_FAILURE (Status))
277                 {
278                     return;
279                 }
280 
281                 DataTable = ACPI_ADD_PTR (UINT8, DataTable, DataLength);
282                 DataOffset += DataLength;
283             }
284             break;
285 
286         case ACPI_ASF_TYPE_ADDRESS:
287 
288             for (i = 0; i < DataLength; i++)
289             {
290                 if (!(i % 16))
291                 {
292                     AcpiDmLineHeader (DataOffset, 1, "Addresses");
293                 }
294 
295                 AcpiOsPrintf ("%2.2X ", *DataTable);
296                 DataTable++;
297                 DataOffset++;
298 
299                 if (DataOffset > Table->Length)
300                 {
301                     AcpiOsPrintf (
302                         "**** ACPI table terminates in the middle of a "
303                         "data structure! (ASF! table)\n");
304                     return;
305                 }
306             }
307 
308             AcpiOsPrintf ("\n");
309             break;
310 
311         default:
312 
313             break;
314         }
315 
316         AcpiOsPrintf ("\n");
317 
318         /* Point to next subtable */
319 
320         if (!Subtable->Header.Length)
321         {
322             AcpiOsPrintf ("Invalid zero subtable header length\n");
323             return;
324         }
325 
326         Offset += Subtable->Header.Length;
327         Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Subtable,
328             Subtable->Header.Length);
329     }
330 }
331 
332 
333 /*******************************************************************************
334  *
335  * FUNCTION:    AcpiDmDumpCpep
336  *
337  * PARAMETERS:  Table               - A CPEP table
338  *
339  * RETURN:      None
340  *
341  * DESCRIPTION: Format the contents of a CPEP. This table type consists
342  *              of an open-ended number of subtables.
343  *
344  ******************************************************************************/
345 
346 void
AcpiDmDumpCpep(ACPI_TABLE_HEADER * Table)347 AcpiDmDumpCpep (
348     ACPI_TABLE_HEADER       *Table)
349 {
350     ACPI_STATUS             Status;
351     ACPI_CPEP_POLLING       *Subtable;
352     UINT32                  Length = Table->Length;
353     UINT32                  Offset = sizeof (ACPI_TABLE_CPEP);
354 
355 
356     /* Main table */
357 
358     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoCpep);
359     if (ACPI_FAILURE (Status))
360     {
361         return;
362     }
363 
364     /* Subtables */
365 
366     Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
367     while (Offset < Table->Length)
368     {
369         AcpiOsPrintf ("\n");
370         Status = AcpiDmDumpTable (Length, Offset, Subtable,
371             Subtable->Header.Length, AcpiDmTableInfoCpep0);
372         if (ACPI_FAILURE (Status))
373         {
374             return;
375         }
376 
377         /* Point to next subtable */
378 
379         Offset += Subtable->Header.Length;
380         Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Subtable,
381             Subtable->Header.Length);
382     }
383 }
384 
385 
386 /*******************************************************************************
387  *
388  * FUNCTION:    AcpiDmDumpCsrt
389  *
390  * PARAMETERS:  Table               - A CSRT table
391  *
392  * RETURN:      None
393  *
394  * DESCRIPTION: Format the contents of a CSRT. This table type consists
395  *              of an open-ended number of subtables.
396  *
397  ******************************************************************************/
398 
399 void
AcpiDmDumpCsrt(ACPI_TABLE_HEADER * Table)400 AcpiDmDumpCsrt (
401     ACPI_TABLE_HEADER       *Table)
402 {
403     ACPI_STATUS             Status;
404     ACPI_CSRT_GROUP         *Subtable;
405     ACPI_CSRT_SHARED_INFO   *SharedInfoTable;
406     ACPI_CSRT_DESCRIPTOR    *SubSubtable;
407     UINT32                  Length = Table->Length;
408     UINT32                  Offset = sizeof (ACPI_TABLE_CSRT);
409     UINT32                  SubOffset;
410     UINT32                  SubSubOffset;
411     UINT32                  InfoLength;
412 
413 
414     /* The main table only contains the ACPI header, thus already handled */
415 
416     /* Subtables (Resource Groups) */
417 
418     Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset);
419     while (Offset < Table->Length)
420     {
421         /* Resource group subtable */
422 
423         AcpiOsPrintf ("\n");
424         Status = AcpiDmDumpTable (Length, Offset, Subtable,
425             Subtable->Length, AcpiDmTableInfoCsrt0);
426         if (ACPI_FAILURE (Status))
427         {
428             return;
429         }
430 
431         /* Shared info subtable (One per resource group) */
432 
433         SubOffset = sizeof (ACPI_CSRT_GROUP);
434         SharedInfoTable = ACPI_ADD_PTR (ACPI_CSRT_SHARED_INFO, Table,
435             Offset + SubOffset);
436 
437         AcpiOsPrintf ("\n");
438         Status = AcpiDmDumpTable (Length, Offset + SubOffset, SharedInfoTable,
439             sizeof (ACPI_CSRT_SHARED_INFO), AcpiDmTableInfoCsrt1);
440         if (ACPI_FAILURE (Status))
441         {
442             return;
443         }
444 
445         SubOffset += Subtable->SharedInfoLength;
446 
447         /* Sub-Subtables (Resource Descriptors) */
448 
449         SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table,
450             Offset + SubOffset);
451 
452         while ((SubOffset < Subtable->Length) &&
453               ((Offset + SubOffset) < Table->Length))
454         {
455             AcpiOsPrintf ("\n");
456             Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubtable,
457                 SubSubtable->Length, AcpiDmTableInfoCsrt2);
458             if (ACPI_FAILURE (Status))
459             {
460                 return;
461             }
462 
463             SubSubOffset = sizeof (ACPI_CSRT_DESCRIPTOR);
464 
465             /* Resource-specific info buffer */
466 
467             InfoLength = SubSubtable->Length - SubSubOffset;
468             if (InfoLength)
469             {
470                 Status = AcpiDmDumpTable (Length,
471                     Offset + SubOffset + SubSubOffset, Table,
472                     InfoLength, AcpiDmTableInfoCsrt2a);
473                 if (ACPI_FAILURE (Status))
474                 {
475                     return;
476                 }
477                 SubSubOffset += InfoLength;
478             }
479 
480             /* Point to next sub-subtable */
481 
482             SubOffset += SubSubtable->Length;
483             SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubtable,
484                 SubSubtable->Length);
485         }
486 
487         /* Point to next subtable */
488 
489         Offset += Subtable->Length;
490         Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Subtable,
491             Subtable->Length);
492     }
493 }
494 
495 
496 /*******************************************************************************
497  *
498  * FUNCTION:    AcpiDmDumpDbg2
499  *
500  * PARAMETERS:  Table               - A DBG2 table
501  *
502  * RETURN:      None
503  *
504  * DESCRIPTION: Format the contents of a DBG2. This table type consists
505  *              of an open-ended number of subtables.
506  *
507  ******************************************************************************/
508 
509 void
AcpiDmDumpDbg2(ACPI_TABLE_HEADER * Table)510 AcpiDmDumpDbg2 (
511     ACPI_TABLE_HEADER       *Table)
512 {
513     ACPI_STATUS             Status;
514     ACPI_DBG2_DEVICE        *Subtable;
515     UINT32                  Length = Table->Length;
516     UINT32                  Offset = sizeof (ACPI_TABLE_DBG2);
517     UINT32                  i;
518     UINT32                  ArrayOffset;
519     UINT32                  AbsoluteOffset;
520     UINT8                   *Array;
521 
522 
523     /* Main table */
524 
525     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDbg2);
526     if (ACPI_FAILURE (Status))
527     {
528         return;
529     }
530 
531     /* Subtables */
532 
533     Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
534     while (Offset < Table->Length)
535     {
536         AcpiOsPrintf ("\n");
537         Status = AcpiDmDumpTable (Length, Offset, Subtable,
538             Subtable->Length, AcpiDmTableInfoDbg2Device);
539         if (ACPI_FAILURE (Status))
540         {
541             return;
542         }
543 
544         /* Dump the BaseAddress array */
545 
546         for (i = 0; i < Subtable->RegisterCount; i++)
547         {
548             ArrayOffset = Subtable->BaseAddressOffset +
549                 (sizeof (ACPI_GENERIC_ADDRESS) * i);
550             AbsoluteOffset = Offset + ArrayOffset;
551             Array = (UINT8 *) Subtable + ArrayOffset;
552 
553             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
554                 Subtable->Length, AcpiDmTableInfoDbg2Addr);
555             if (ACPI_FAILURE (Status))
556             {
557                 return;
558             }
559         }
560 
561         /* Dump the AddressSize array */
562 
563         for (i = 0; i < Subtable->RegisterCount; i++)
564         {
565             ArrayOffset = Subtable->AddressSizeOffset +
566                 (sizeof (UINT32) * i);
567             AbsoluteOffset = Offset + ArrayOffset;
568             Array = (UINT8 *) Subtable + ArrayOffset;
569 
570             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
571                 Subtable->Length, AcpiDmTableInfoDbg2Size);
572             if (ACPI_FAILURE (Status))
573             {
574                 return;
575             }
576         }
577 
578         /* Dump the Namestring (required) */
579 
580         AcpiOsPrintf ("\n");
581         ArrayOffset = Subtable->NamepathOffset;
582         AbsoluteOffset = Offset + ArrayOffset;
583         Array = (UINT8 *) Subtable + ArrayOffset;
584 
585         Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
586             Subtable->Length, AcpiDmTableInfoDbg2Name);
587         if (ACPI_FAILURE (Status))
588         {
589             return;
590         }
591 
592         /* Dump the OemData (optional) */
593 
594         if (Subtable->OemDataOffset)
595         {
596             Status = AcpiDmDumpTable (Length, Offset + Subtable->OemDataOffset,
597                 Table, Subtable->OemDataLength,
598                 AcpiDmTableInfoDbg2OemData);
599             if (ACPI_FAILURE (Status))
600             {
601                 return;
602             }
603         }
604 
605         /* Point to next subtable */
606 
607         Offset += Subtable->Length;
608         Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Subtable,
609             Subtable->Length);
610     }
611 }
612 
613 
614 /*******************************************************************************
615  *
616  * FUNCTION:    AcpiDmDumpDmar
617  *
618  * PARAMETERS:  Table               - A DMAR table
619  *
620  * RETURN:      None
621  *
622  * DESCRIPTION: Format the contents of a DMAR. This table type consists
623  *              of an open-ended number of subtables.
624  *
625  ******************************************************************************/
626 
627 void
AcpiDmDumpDmar(ACPI_TABLE_HEADER * Table)628 AcpiDmDumpDmar (
629     ACPI_TABLE_HEADER       *Table)
630 {
631     ACPI_STATUS             Status;
632     ACPI_DMAR_HEADER        *Subtable;
633     UINT32                  Length = Table->Length;
634     UINT32                  Offset = sizeof (ACPI_TABLE_DMAR);
635     ACPI_DMTABLE_INFO       *InfoTable;
636     ACPI_DMAR_DEVICE_SCOPE  *ScopeTable;
637     UINT32                  ScopeOffset;
638     UINT8                   *PciPath;
639     UINT32                  PathOffset;
640 
641 
642     /* Main table */
643 
644     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar);
645     if (ACPI_FAILURE (Status))
646     {
647         return;
648     }
649 
650     /* Subtables */
651 
652     Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
653     while (Offset < Table->Length)
654     {
655         /* Common subtable header */
656 
657         AcpiOsPrintf ("\n");
658         Status = AcpiDmDumpTable (Length, Offset, Subtable,
659             Subtable->Length, AcpiDmTableInfoDmarHdr);
660         if (ACPI_FAILURE (Status))
661         {
662             return;
663         }
664 
665         AcpiOsPrintf ("\n");
666 
667         switch (Subtable->Type)
668         {
669         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
670 
671             InfoTable = AcpiDmTableInfoDmar0;
672             ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT);
673             break;
674 
675         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
676 
677             InfoTable = AcpiDmTableInfoDmar1;
678             ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY);
679             break;
680 
681         case ACPI_DMAR_TYPE_ROOT_ATS:
682 
683             InfoTable = AcpiDmTableInfoDmar2;
684             ScopeOffset = sizeof (ACPI_DMAR_ATSR);
685             break;
686 
687         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
688 
689             InfoTable = AcpiDmTableInfoDmar3;
690             ScopeOffset = sizeof (ACPI_DMAR_RHSA);
691             break;
692 
693         case ACPI_DMAR_TYPE_NAMESPACE:
694 
695             InfoTable = AcpiDmTableInfoDmar4;
696             ScopeOffset = sizeof (ACPI_DMAR_ANDD);
697             break;
698 
699         default:
700 
701             AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n",
702                 Subtable->Type);
703             return;
704         }
705 
706         Status = AcpiDmDumpTable (Length, Offset, Subtable,
707             Subtable->Length, InfoTable);
708         if (ACPI_FAILURE (Status))
709         {
710             return;
711         }
712 
713         /*
714          * Dump the optional device scope entries
715          */
716         if ((Subtable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
717             (Subtable->Type == ACPI_DMAR_TYPE_NAMESPACE))
718         {
719             /* These types do not support device scopes */
720 
721             goto NextSubtable;
722         }
723 
724         ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable, ScopeOffset);
725         while (ScopeOffset < Subtable->Length)
726         {
727             AcpiOsPrintf ("\n");
728             Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
729                 ScopeTable->Length, AcpiDmTableInfoDmarScope);
730             if (ACPI_FAILURE (Status))
731             {
732                 return;
733             }
734             AcpiOsPrintf ("\n");
735 
736             /* Dump the PCI Path entries for this device scope */
737 
738             PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */
739 
740             PciPath = ACPI_ADD_PTR (UINT8, ScopeTable,
741                 sizeof (ACPI_DMAR_DEVICE_SCOPE));
742 
743             while (PathOffset < ScopeTable->Length)
744             {
745                 AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2,
746                     "PCI Path");
747                 AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]);
748 
749                 /* Point to next PCI Path entry */
750 
751                 PathOffset += 2;
752                 PciPath += 2;
753                 AcpiOsPrintf ("\n");
754             }
755 
756             /* Point to next device scope entry */
757 
758             ScopeOffset += ScopeTable->Length;
759             ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE,
760                 ScopeTable, ScopeTable->Length);
761         }
762 
763 NextSubtable:
764         /* Point to next subtable */
765 
766         Offset += Subtable->Length;
767         Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Subtable,
768             Subtable->Length);
769     }
770 }
771 
772 
773 /*******************************************************************************
774  *
775  * FUNCTION:    AcpiDmDumpDrtm
776  *
777  * PARAMETERS:  Table               - A DRTM table
778  *
779  * RETURN:      None
780  *
781  * DESCRIPTION: Format the contents of a DRTM.
782  *
783  ******************************************************************************/
784 
785 void
AcpiDmDumpDrtm(ACPI_TABLE_HEADER * Table)786 AcpiDmDumpDrtm (
787     ACPI_TABLE_HEADER       *Table)
788 {
789     ACPI_STATUS             Status;
790     UINT32                  Offset;
791     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
792     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
793     ACPI_DRTM_DPS_ID        *DrtmDps;
794     UINT32                  Count;
795 
796 
797     /* Main table */
798 
799     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
800         AcpiDmTableInfoDrtm);
801     if (ACPI_FAILURE (Status))
802     {
803         return;
804     }
805 
806     Offset = sizeof (ACPI_TABLE_DRTM);
807 
808     /* Sub-tables */
809 
810     /* Dump ValidatedTable length */
811 
812     DrtmVtl = ACPI_ADD_PTR (ACPI_DRTM_VTABLE_LIST, Table, Offset);
813     AcpiOsPrintf ("\n");
814     Status = AcpiDmDumpTable (Table->Length, Offset,
815         DrtmVtl, ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables),
816         AcpiDmTableInfoDrtm0);
817     if (ACPI_FAILURE (Status))
818     {
819             return;
820     }
821 
822     Offset += ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables);
823 
824     /* Dump Validated table addresses */
825 
826     Count = 0;
827     while ((Offset < Table->Length) &&
828             (DrtmVtl->ValidatedTableCount > Count))
829     {
830         Status = AcpiDmDumpTable (Table->Length, Offset,
831             ACPI_ADD_PTR (void, Table, Offset), sizeof (UINT64),
832             AcpiDmTableInfoDrtm0a);
833         if (ACPI_FAILURE (Status))
834         {
835             return;
836         }
837 
838         Offset += sizeof (UINT64);
839         Count++;
840     }
841 
842     /* Dump ResourceList length */
843 
844     DrtmRl = ACPI_ADD_PTR (ACPI_DRTM_RESOURCE_LIST, Table, Offset);
845     AcpiOsPrintf ("\n");
846     Status = AcpiDmDumpTable (Table->Length, Offset,
847         DrtmRl, ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources),
848         AcpiDmTableInfoDrtm1);
849     if (ACPI_FAILURE (Status))
850     {
851         return;
852     }
853 
854     Offset += ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources);
855 
856     /* Dump the Resource List */
857 
858     Count = 0;
859     while ((Offset < Table->Length) &&
860            (DrtmRl->ResourceCount > Count))
861     {
862         Status = AcpiDmDumpTable (Table->Length, Offset,
863             ACPI_ADD_PTR (void, Table, Offset),
864             sizeof (ACPI_DRTM_RESOURCE), AcpiDmTableInfoDrtm1a);
865         if (ACPI_FAILURE (Status))
866         {
867             return;
868         }
869 
870         Offset += sizeof (ACPI_DRTM_RESOURCE);
871         Count++;
872     }
873 
874     /* Dump DPS */
875 
876     DrtmDps = ACPI_ADD_PTR (ACPI_DRTM_DPS_ID, Table, Offset);
877     AcpiOsPrintf ("\n");
878     (void) AcpiDmDumpTable (Table->Length, Offset,
879         DrtmDps, sizeof (ACPI_DRTM_DPS_ID), AcpiDmTableInfoDrtm2);
880 }
881 
882 
883 /*******************************************************************************
884  *
885  * FUNCTION:    AcpiDmDumpEinj
886  *
887  * PARAMETERS:  Table               - A EINJ table
888  *
889  * RETURN:      None
890  *
891  * DESCRIPTION: Format the contents of a EINJ. This table type consists
892  *              of an open-ended number of subtables.
893  *
894  ******************************************************************************/
895 
896 void
AcpiDmDumpEinj(ACPI_TABLE_HEADER * Table)897 AcpiDmDumpEinj (
898     ACPI_TABLE_HEADER       *Table)
899 {
900     ACPI_STATUS             Status;
901     ACPI_WHEA_HEADER        *Subtable;
902     UINT32                  Length = Table->Length;
903     UINT32                  Offset = sizeof (ACPI_TABLE_EINJ);
904 
905 
906     /* Main table */
907 
908     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj);
909     if (ACPI_FAILURE (Status))
910     {
911         return;
912     }
913 
914     /* Subtables */
915 
916     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
917     while (Offset < Table->Length)
918     {
919         AcpiOsPrintf ("\n");
920         Status = AcpiDmDumpTable (Length, Offset, Subtable,
921             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
922         if (ACPI_FAILURE (Status))
923         {
924             return;
925         }
926 
927         /* Point to next subtable (each subtable is of fixed length) */
928 
929         Offset += sizeof (ACPI_WHEA_HEADER);
930         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
931             sizeof (ACPI_WHEA_HEADER));
932     }
933 }
934 
935 
936 /*******************************************************************************
937  *
938  * FUNCTION:    AcpiDmDumpErst
939  *
940  * PARAMETERS:  Table               - A ERST table
941  *
942  * RETURN:      None
943  *
944  * DESCRIPTION: Format the contents of a ERST. This table type consists
945  *              of an open-ended number of subtables.
946  *
947  ******************************************************************************/
948 
949 void
AcpiDmDumpErst(ACPI_TABLE_HEADER * Table)950 AcpiDmDumpErst (
951     ACPI_TABLE_HEADER       *Table)
952 {
953     ACPI_STATUS             Status;
954     ACPI_WHEA_HEADER        *Subtable;
955     UINT32                  Length = Table->Length;
956     UINT32                  Offset = sizeof (ACPI_TABLE_ERST);
957 
958 
959     /* Main table */
960 
961     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst);
962     if (ACPI_FAILURE (Status))
963     {
964         return;
965     }
966 
967     /* Subtables */
968 
969     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
970     while (Offset < Table->Length)
971     {
972         AcpiOsPrintf ("\n");
973         Status = AcpiDmDumpTable (Length, Offset, Subtable,
974             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
975         if (ACPI_FAILURE (Status))
976         {
977             return;
978         }
979 
980         /* Point to next subtable (each subtable is of fixed length) */
981 
982         Offset += sizeof (ACPI_WHEA_HEADER);
983         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
984             sizeof (ACPI_WHEA_HEADER));
985     }
986 }
987 
988 
989 /*******************************************************************************
990  *
991  * FUNCTION:    AcpiDmDumpFpdt
992  *
993  * PARAMETERS:  Table               - A FPDT table
994  *
995  * RETURN:      None
996  *
997  * DESCRIPTION: Format the contents of a FPDT. This table type consists
998  *              of an open-ended number of subtables.
999  *
1000  ******************************************************************************/
1001 
1002 void
AcpiDmDumpFpdt(ACPI_TABLE_HEADER * Table)1003 AcpiDmDumpFpdt (
1004     ACPI_TABLE_HEADER       *Table)
1005 {
1006     ACPI_STATUS             Status;
1007     ACPI_FPDT_HEADER        *Subtable;
1008     UINT32                  Length = Table->Length;
1009     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
1010     ACPI_DMTABLE_INFO       *InfoTable;
1011 
1012 
1013     /* There is no main table (other than the standard ACPI header) */
1014 
1015     /* Subtables */
1016 
1017     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
1018     while (Offset < Table->Length)
1019     {
1020         /* Common subtable header */
1021 
1022         AcpiOsPrintf ("\n");
1023         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1024             Subtable->Length, AcpiDmTableInfoFpdtHdr);
1025         if (ACPI_FAILURE (Status))
1026         {
1027             return;
1028         }
1029 
1030         switch (Subtable->Type)
1031         {
1032         case ACPI_FPDT_TYPE_BOOT:
1033 
1034             InfoTable = AcpiDmTableInfoFpdt0;
1035             break;
1036 
1037         case ACPI_FPDT_TYPE_S3PERF:
1038 
1039             InfoTable = AcpiDmTableInfoFpdt1;
1040             break;
1041 
1042         default:
1043 
1044             AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n",
1045                 Subtable->Type);
1046 
1047             /* Attempt to continue */
1048 
1049             if (!Subtable->Length)
1050             {
1051                 AcpiOsPrintf ("Invalid zero length subtable\n");
1052                 return;
1053             }
1054             goto NextSubtable;
1055         }
1056 
1057         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1058             Subtable->Length, InfoTable);
1059         if (ACPI_FAILURE (Status))
1060         {
1061             return;
1062         }
1063 
1064 NextSubtable:
1065         /* Point to next subtable */
1066 
1067         Offset += Subtable->Length;
1068         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable,
1069             Subtable->Length);
1070     }
1071 }
1072 
1073 
1074 /*******************************************************************************
1075  *
1076  * FUNCTION:    AcpiDmDumpGtdt
1077  *
1078  * PARAMETERS:  Table               - A GTDT table
1079  *
1080  * RETURN:      None
1081  *
1082  * DESCRIPTION: Format the contents of a GTDT. This table type consists
1083  *              of an open-ended number of subtables.
1084  *
1085  ******************************************************************************/
1086 
1087 void
AcpiDmDumpGtdt(ACPI_TABLE_HEADER * Table)1088 AcpiDmDumpGtdt (
1089     ACPI_TABLE_HEADER       *Table)
1090 {
1091     ACPI_STATUS             Status;
1092     ACPI_GTDT_HEADER        *Subtable;
1093     UINT32                  Length = Table->Length;
1094     UINT32                  Offset = sizeof (ACPI_TABLE_GTDT);
1095     ACPI_DMTABLE_INFO       *InfoTable;
1096     UINT32                  SubtableLength;
1097     UINT32                  GtCount;
1098     ACPI_GTDT_TIMER_ENTRY   *GtxTable;
1099 
1100 
1101     /* Main table */
1102 
1103     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoGtdt);
1104     if (ACPI_FAILURE (Status))
1105     {
1106         return;
1107     }
1108 
1109     /* Subtables */
1110 
1111     Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
1112     while (Offset < Table->Length)
1113     {
1114         /* Common subtable header */
1115 
1116         AcpiOsPrintf ("\n");
1117         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1118             Subtable->Length, AcpiDmTableInfoGtdtHdr);
1119         if (ACPI_FAILURE (Status))
1120         {
1121             return;
1122         }
1123 
1124         GtCount = 0;
1125         switch (Subtable->Type)
1126         {
1127         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1128 
1129             SubtableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
1130             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1131                 Subtable))->TimerCount;
1132 
1133             InfoTable = AcpiDmTableInfoGtdt0;
1134             break;
1135 
1136         case ACPI_GTDT_TYPE_WATCHDOG:
1137 
1138             SubtableLength = sizeof (ACPI_GTDT_WATCHDOG);
1139 
1140             InfoTable = AcpiDmTableInfoGtdt1;
1141             break;
1142 
1143         default:
1144 
1145             /* Cannot continue on unknown type - no length */
1146 
1147             AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n",
1148                 Subtable->Type);
1149             return;
1150         }
1151 
1152         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1153             Subtable->Length, InfoTable);
1154         if (ACPI_FAILURE (Status))
1155         {
1156             return;
1157         }
1158 
1159         /* Point to end of current subtable (each subtable above is of fixed length) */
1160 
1161         Offset += SubtableLength;
1162 
1163         /* If there are any Gt Timer Blocks from above, dump them now */
1164 
1165         if (GtCount)
1166         {
1167             GtxTable = ACPI_ADD_PTR (
1168                 ACPI_GTDT_TIMER_ENTRY, Subtable, SubtableLength);
1169             SubtableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
1170 
1171             while (GtCount)
1172             {
1173                 AcpiOsPrintf ("\n");
1174                 Status = AcpiDmDumpTable (Length, Offset, GtxTable,
1175                     sizeof (ACPI_GTDT_TIMER_ENTRY), AcpiDmTableInfoGtdt0a);
1176                 if (ACPI_FAILURE (Status))
1177                 {
1178                     return;
1179                 }
1180                 Offset += sizeof (ACPI_GTDT_TIMER_ENTRY);
1181                 GtxTable++;
1182                 GtCount--;
1183             }
1184         }
1185 
1186         /* Point to next subtable */
1187 
1188         Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Subtable, SubtableLength);
1189     }
1190 }
1191 
1192 
1193 /*******************************************************************************
1194  *
1195  * FUNCTION:    AcpiDmDumpHest
1196  *
1197  * PARAMETERS:  Table               - A HEST table
1198  *
1199  * RETURN:      None
1200  *
1201  * DESCRIPTION: Format the contents of a HEST. This table type consists
1202  *              of an open-ended number of subtables.
1203  *
1204  ******************************************************************************/
1205 
1206 void
AcpiDmDumpHest(ACPI_TABLE_HEADER * Table)1207 AcpiDmDumpHest (
1208     ACPI_TABLE_HEADER       *Table)
1209 {
1210     ACPI_STATUS             Status;
1211     ACPI_HEST_HEADER        *Subtable;
1212     UINT32                  Length = Table->Length;
1213     UINT32                  Offset = sizeof (ACPI_TABLE_HEST);
1214     ACPI_DMTABLE_INFO       *InfoTable;
1215     UINT32                  SubtableLength;
1216     UINT32                  BankCount;
1217     ACPI_HEST_IA_ERROR_BANK *BankTable;
1218 
1219 
1220     /* Main table */
1221 
1222     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest);
1223     if (ACPI_FAILURE (Status))
1224     {
1225         return;
1226     }
1227 
1228     /* Subtables */
1229 
1230     Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
1231     while (Offset < Table->Length)
1232     {
1233         BankCount = 0;
1234         switch (Subtable->Type)
1235         {
1236         case ACPI_HEST_TYPE_IA32_CHECK:
1237 
1238             InfoTable = AcpiDmTableInfoHest0;
1239             SubtableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
1240             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1241                 Subtable))->NumHardwareBanks;
1242             break;
1243 
1244         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1245 
1246             InfoTable = AcpiDmTableInfoHest1;
1247             SubtableLength = sizeof (ACPI_HEST_IA_CORRECTED);
1248             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1249                 Subtable))->NumHardwareBanks;
1250             break;
1251 
1252         case ACPI_HEST_TYPE_IA32_NMI:
1253 
1254             InfoTable = AcpiDmTableInfoHest2;
1255             SubtableLength = sizeof (ACPI_HEST_IA_NMI);
1256             break;
1257 
1258         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1259 
1260             InfoTable = AcpiDmTableInfoHest6;
1261             SubtableLength = sizeof (ACPI_HEST_AER_ROOT);
1262             break;
1263 
1264         case ACPI_HEST_TYPE_AER_ENDPOINT:
1265 
1266             InfoTable = AcpiDmTableInfoHest7;
1267             SubtableLength = sizeof (ACPI_HEST_AER);
1268             break;
1269 
1270         case ACPI_HEST_TYPE_AER_BRIDGE:
1271 
1272             InfoTable = AcpiDmTableInfoHest8;
1273             SubtableLength = sizeof (ACPI_HEST_AER_BRIDGE);
1274             break;
1275 
1276         case ACPI_HEST_TYPE_GENERIC_ERROR:
1277 
1278             InfoTable = AcpiDmTableInfoHest9;
1279             SubtableLength = sizeof (ACPI_HEST_GENERIC);
1280             break;
1281 
1282         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
1283 
1284             InfoTable = AcpiDmTableInfoHest10;
1285             SubtableLength = sizeof (ACPI_HEST_GENERIC_V2);
1286             break;
1287 
1288         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1289 
1290             InfoTable = AcpiDmTableInfoHest11;
1291             SubtableLength = sizeof (ACPI_HEST_IA_DEFERRED_CHECK);
1292             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
1293                 Subtable))->NumHardwareBanks;
1294             break;
1295 
1296         default:
1297 
1298             /* Cannot continue on unknown type - no length */
1299 
1300             AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n",
1301                 Subtable->Type);
1302             return;
1303         }
1304 
1305         AcpiOsPrintf ("\n");
1306         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1307             SubtableLength, InfoTable);
1308         if (ACPI_FAILURE (Status))
1309         {
1310             return;
1311         }
1312 
1313         /* Point to end of current subtable (each subtable above is of fixed length) */
1314 
1315         Offset += SubtableLength;
1316 
1317         /* If there are any (fixed-length) Error Banks from above, dump them now */
1318 
1319         if (BankCount)
1320         {
1321             BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, Subtable,
1322                 SubtableLength);
1323             SubtableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
1324 
1325             while (BankCount)
1326             {
1327                 AcpiOsPrintf ("\n");
1328                 Status = AcpiDmDumpTable (Length, Offset, BankTable,
1329                     sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank);
1330                 if (ACPI_FAILURE (Status))
1331                 {
1332                     return;
1333                 }
1334 
1335                 Offset += sizeof (ACPI_HEST_IA_ERROR_BANK);
1336                 BankTable++;
1337                 BankCount--;
1338             }
1339         }
1340 
1341         /* Point to next subtable */
1342 
1343         Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Subtable, SubtableLength);
1344     }
1345 }
1346 
1347 
1348 /*******************************************************************************
1349  *
1350  * FUNCTION:    AcpiDmDumpHmat
1351  *
1352  * PARAMETERS:  Table               - A HMAT table
1353  *
1354  * RETURN:      None
1355  *
1356  * DESCRIPTION: Format the contents of a HMAT.
1357  *
1358  ******************************************************************************/
1359 
1360 void
AcpiDmDumpHmat(ACPI_TABLE_HEADER * Table)1361 AcpiDmDumpHmat (
1362     ACPI_TABLE_HEADER       *Table)
1363 {
1364     ACPI_STATUS             Status;
1365     ACPI_HMAT_STRUCTURE     *HmatStruct;
1366     ACPI_HMAT_LOCALITY      *HmatLocality;
1367     ACPI_HMAT_CACHE         *HmatCache;
1368     UINT32                  Offset;
1369     UINT32                  SubtableOffset;
1370     UINT32                  Length;
1371     ACPI_DMTABLE_INFO       *InfoTable;
1372     UINT32                  i, j;
1373 
1374 
1375     /* Main table */
1376 
1377     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoHmat);
1378     if (ACPI_FAILURE (Status))
1379     {
1380         return;
1381     }
1382     Offset = sizeof (ACPI_TABLE_HMAT);
1383 
1384     while (Offset < Table->Length)
1385     {
1386         AcpiOsPrintf ("\n");
1387         SubtableOffset = 0;
1388 
1389         /* Dump HMAT structure header */
1390 
1391         HmatStruct = ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, Table, Offset);
1392         if (HmatStruct->Length < sizeof (ACPI_HMAT_STRUCTURE))
1393         {
1394             AcpiOsPrintf ("Invalid HMAT structure length\n");
1395             return;
1396         }
1397         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
1398             HmatStruct->Length, AcpiDmTableInfoHmatHdr);
1399         if (ACPI_FAILURE (Status))
1400         {
1401             return;
1402         }
1403 
1404         switch (HmatStruct->Type)
1405         {
1406         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
1407 
1408             InfoTable = AcpiDmTableInfoHmat0;
1409             Length = sizeof (ACPI_HMAT_ADDRESS_RANGE);
1410             break;
1411 
1412         case ACPI_HMAT_TYPE_LOCALITY:
1413 
1414             InfoTable = AcpiDmTableInfoHmat1;
1415             Length = sizeof (ACPI_HMAT_LOCALITY);
1416             break;
1417 
1418         case ACPI_HMAT_TYPE_CACHE:
1419 
1420             InfoTable = AcpiDmTableInfoHmat2;
1421             Length = sizeof (ACPI_HMAT_CACHE);
1422             break;
1423 
1424         default:
1425 
1426             AcpiOsPrintf ("\n**** Unknown HMAT structure type 0x%X\n",
1427                 HmatStruct->Type);
1428 
1429             /* Attempt to continue */
1430 
1431             goto NextSubtable;
1432         }
1433 
1434         /* Dump HMAT structure body */
1435 
1436         if (HmatStruct->Length < Length)
1437         {
1438             AcpiOsPrintf ("Invalid HMAT structure length\n");
1439             return;
1440         }
1441         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
1442             HmatStruct->Length, InfoTable);
1443         if (ACPI_FAILURE (Status))
1444         {
1445             return;
1446         }
1447 
1448         /* Dump HMAT structure additionals */
1449 
1450         switch (HmatStruct->Type)
1451         {
1452         case ACPI_HMAT_TYPE_LOCALITY:
1453 
1454             HmatLocality = ACPI_CAST_PTR (ACPI_HMAT_LOCALITY, HmatStruct);
1455             SubtableOffset = sizeof (ACPI_HMAT_LOCALITY);
1456 
1457             /* Dump initiator proximity domains */
1458 
1459             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1460                 (UINT32)(HmatLocality->NumberOfInitiatorPDs * 4))
1461             {
1462                 AcpiOsPrintf ("Invalid initiator proximity domain number\n");
1463                 return;
1464             }
1465             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
1466             {
1467                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1468                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1469                     4, AcpiDmTableInfoHmat1a);
1470                 SubtableOffset += 4;
1471             }
1472 
1473             /* Dump target proximity domains */
1474 
1475             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1476                 (UINT32)(HmatLocality->NumberOfTargetPDs * 4))
1477             {
1478                 AcpiOsPrintf ("Invalid target proximity domain number\n");
1479                 return;
1480             }
1481             for (i = 0; i < HmatLocality->NumberOfTargetPDs; i++)
1482             {
1483                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1484                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1485                     4, AcpiDmTableInfoHmat1b);
1486                 SubtableOffset += 4;
1487             }
1488 
1489             /* Dump latency/bandwidth entris */
1490 
1491             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1492                 (UINT32)(HmatLocality->NumberOfInitiatorPDs *
1493                          HmatLocality->NumberOfTargetPDs * 2))
1494             {
1495                 AcpiOsPrintf ("Invalid latency/bandwidth entry number\n");
1496                 return;
1497             }
1498             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
1499             {
1500                 for (j = 0; j < HmatLocality->NumberOfTargetPDs; j++)
1501                 {
1502                     Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1503                         ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1504                         2, AcpiDmTableInfoHmat1c);
1505                     SubtableOffset += 2;
1506                 }
1507             }
1508             break;
1509 
1510         case ACPI_HMAT_TYPE_CACHE:
1511 
1512             HmatCache = ACPI_CAST_PTR (ACPI_HMAT_CACHE, HmatStruct);
1513             SubtableOffset = sizeof (ACPI_HMAT_CACHE);
1514 
1515             /* Dump SMBIOS handles */
1516 
1517             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1518                 (UINT32)(HmatCache->NumberOfSMBIOSHandles * 2))
1519             {
1520                 AcpiOsPrintf ("Invalid SMBIOS handle number\n");
1521                 return;
1522             }
1523             for (i = 0; i < HmatCache->NumberOfSMBIOSHandles; i++)
1524             {
1525                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1526                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1527                     2, AcpiDmTableInfoHmat2a);
1528                 SubtableOffset += 2;
1529             }
1530             break;
1531 
1532         default:
1533 
1534             break;
1535         }
1536 
1537 NextSubtable:
1538         /* Point to next HMAT structure subtable */
1539 
1540         Offset += (HmatStruct->Length);
1541     }
1542 }
1543