dmtbdump.c revision 284460
1/******************************************************************************
2 *
3 * Module Name: dmtbdump - Dump ACPI data tables that contain no AML code
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acdisasm.h>
47#include <contrib/dev/acpica/include/actables.h>
48
49/* This module used for application-level code only */
50
51#define _COMPONENT          ACPI_CA_DISASSEMBLER
52        ACPI_MODULE_NAME    ("dmtbdump")
53
54
55/* Local prototypes */
56
57static void
58AcpiDmValidateFadtLength (
59    UINT32                  Revision,
60    UINT32                  Length);
61
62
63/*******************************************************************************
64 *
65 * FUNCTION:    AcpiDmDumpBuffer
66 *
67 * PARAMETERS:  Table               - ACPI Table or subtable
68 *              BufferOffset        - Offset of buffer from Table above
69 *              Length              - Length of the buffer
70 *              AbsoluteOffset      - Offset of buffer in the main ACPI table
71 *              Header              - Name of the buffer field (printed on the
72 *                                    first line only.)
73 *
74 * RETURN:      None
75 *
76 * DESCRIPTION: Format the contents of an arbitrary length data buffer (in the
77 *              disassembler output format.)
78 *
79 ******************************************************************************/
80
81void
82AcpiDmDumpBuffer (
83    void                    *Table,
84    UINT32                  BufferOffset,
85    UINT32                  Length,
86    UINT32                  AbsoluteOffset,
87    char                    *Header)
88{
89    UINT8                   *Buffer;
90    UINT32                  i;
91
92
93    if (!Length)
94    {
95        return;
96    }
97
98    Buffer = ACPI_CAST_PTR (UINT8, Table) + BufferOffset;
99    i = 0;
100
101    while (i < Length)
102    {
103        if (!(i % 16))
104        {
105            /* Insert a backslash - line continuation character */
106
107            if (Length > 16)
108            {
109                AcpiOsPrintf ("\\\n    ");
110            }
111        }
112
113        AcpiOsPrintf ("%.02X ", *Buffer);
114        i++;
115        Buffer++;
116        AbsoluteOffset++;
117    }
118
119    AcpiOsPrintf ("\n");
120}
121
122
123/*******************************************************************************
124 *
125 * FUNCTION:    AcpiDmDumpUnicode
126 *
127 * PARAMETERS:  Table               - ACPI Table or subtable
128 *              BufferOffset        - Offset of buffer from Table above
129 *              ByteLength          - Length of the buffer
130 *
131 * RETURN:      None
132 *
133 * DESCRIPTION: Validate and dump the contents of a buffer that contains
134 *              unicode data. The output is a standard ASCII string. If it
135 *              appears that the data is not unicode, the buffer is dumped
136 *              as hex characters.
137 *
138 ******************************************************************************/
139
140void
141AcpiDmDumpUnicode (
142    void                    *Table,
143    UINT32                  BufferOffset,
144    UINT32                  ByteLength)
145{
146    UINT8                   *Buffer;
147    UINT32                  Length;
148    UINT32                  i;
149
150
151    Buffer = ((UINT8 *) Table) + BufferOffset;
152    Length = ByteLength - 2; /* Last two bytes are the null terminator */
153
154    /* Ensure all low bytes are entirely printable ASCII */
155
156    for (i = 0; i < Length; i += 2)
157    {
158        if (!ACPI_IS_PRINT (Buffer[i]))
159        {
160            goto DumpRawBuffer;
161        }
162    }
163
164    /* Ensure all high bytes are zero */
165
166    for (i = 1; i < Length; i += 2)
167    {
168        if (Buffer[i])
169        {
170            goto DumpRawBuffer;
171        }
172    }
173
174    /* Dump the buffer as a normal string */
175
176    AcpiOsPrintf ("\"");
177    for (i = 0; i < Length; i += 2)
178    {
179        AcpiOsPrintf ("%c", Buffer[i]);
180    }
181    AcpiOsPrintf ("\"\n");
182    return;
183
184DumpRawBuffer:
185    AcpiDmDumpBuffer (Table, BufferOffset, ByteLength,
186        BufferOffset, NULL);
187    AcpiOsPrintf ("\n");
188}
189
190
191/*******************************************************************************
192 *
193 * FUNCTION:    AcpiDmDumpRsdp
194 *
195 * PARAMETERS:  Table               - A RSDP
196 *
197 * RETURN:      Length of the table (there is not always a length field,
198 *              use revision or length if available (ACPI 2.0+))
199 *
200 * DESCRIPTION: Format the contents of a RSDP
201 *
202 ******************************************************************************/
203
204UINT32
205AcpiDmDumpRsdp (
206    ACPI_TABLE_HEADER       *Table)
207{
208    ACPI_TABLE_RSDP         *Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table);
209    UINT32                  Length = sizeof (ACPI_RSDP_COMMON);
210    UINT8                   Checksum;
211
212
213    /* Dump the common ACPI 1.0 portion */
214
215    AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp1);
216
217    /* Validate the first checksum */
218
219    Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_RSDP_COMMON),
220                Rsdp->Checksum);
221    if (Checksum != Rsdp->Checksum)
222    {
223        AcpiOsPrintf ("/* Incorrect Checksum above, should be 0x%2.2X */\n",
224            Checksum);
225    }
226
227    /* The RSDP for ACPI 2.0+ contains more data and has a Length field */
228
229    if (Rsdp->Revision > 0)
230    {
231        Length = Rsdp->Length;
232        AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp2);
233
234        /* Validate the extended checksum over entire RSDP */
235
236        Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_TABLE_RSDP),
237                    Rsdp->ExtendedChecksum);
238        if (Checksum != Rsdp->ExtendedChecksum)
239        {
240            AcpiOsPrintf (
241                "/* Incorrect Extended Checksum above, should be 0x%2.2X */\n",
242                Checksum);
243        }
244    }
245
246    return (Length);
247}
248
249
250/*******************************************************************************
251 *
252 * FUNCTION:    AcpiDmDumpRsdt
253 *
254 * PARAMETERS:  Table               - A RSDT
255 *
256 * RETURN:      None
257 *
258 * DESCRIPTION: Format the contents of a RSDT
259 *
260 ******************************************************************************/
261
262void
263AcpiDmDumpRsdt (
264    ACPI_TABLE_HEADER       *Table)
265{
266    UINT32                  *Array;
267    UINT32                  Entries;
268    UINT32                  Offset;
269    UINT32                  i;
270
271
272    /* Point to start of table pointer array */
273
274    Array = ACPI_CAST_PTR (ACPI_TABLE_RSDT, Table)->TableOffsetEntry;
275    Offset = sizeof (ACPI_TABLE_HEADER);
276
277    /* RSDT uses 32-bit pointers */
278
279    Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT32);
280
281    for (i = 0; i < Entries; i++)
282    {
283        AcpiDmLineHeader2 (Offset, sizeof (UINT32), "ACPI Table Address", i);
284        AcpiOsPrintf ("%8.8X\n", Array[i]);
285        Offset += sizeof (UINT32);
286    }
287}
288
289
290/*******************************************************************************
291 *
292 * FUNCTION:    AcpiDmDumpXsdt
293 *
294 * PARAMETERS:  Table               - A XSDT
295 *
296 * RETURN:      None
297 *
298 * DESCRIPTION: Format the contents of a XSDT
299 *
300 ******************************************************************************/
301
302void
303AcpiDmDumpXsdt (
304    ACPI_TABLE_HEADER       *Table)
305{
306    UINT64                  *Array;
307    UINT32                  Entries;
308    UINT32                  Offset;
309    UINT32                  i;
310
311
312    /* Point to start of table pointer array */
313
314    Array = ACPI_CAST_PTR (ACPI_TABLE_XSDT, Table)->TableOffsetEntry;
315    Offset = sizeof (ACPI_TABLE_HEADER);
316
317    /* XSDT uses 64-bit pointers */
318
319    Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT64);
320
321    for (i = 0; i < Entries; i++)
322    {
323        AcpiDmLineHeader2 (Offset, sizeof (UINT64), "ACPI Table Address", i);
324        AcpiOsPrintf ("%8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Array[i]));
325        Offset += sizeof (UINT64);
326    }
327}
328
329
330/*******************************************************************************
331 *
332 * FUNCTION:    AcpiDmDumpFadt
333 *
334 * PARAMETERS:  Table               - A FADT
335 *
336 * RETURN:      None
337 *
338 * DESCRIPTION: Format the contents of a FADT
339 *
340 * NOTE:        We cannot depend on the FADT version to indicate the actual
341 *              contents of the FADT because of BIOS bugs. The table length
342 *              is the only reliable indicator.
343 *
344 ******************************************************************************/
345
346void
347AcpiDmDumpFadt (
348    ACPI_TABLE_HEADER       *Table)
349{
350
351    /* Always dump the minimum FADT revision 1 fields (ACPI 1.0) */
352
353    AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt1);
354
355    /* Check for FADT revision 2 fields (ACPI 1.0B MS extensions) */
356
357    if ((Table->Length > ACPI_FADT_V1_SIZE) &&
358        (Table->Length <= ACPI_FADT_V2_SIZE))
359    {
360        AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt2);
361    }
362
363    /* Check for FADT revision 3/4 fields and up (ACPI 2.0+ extended data) */
364
365    else if (Table->Length > ACPI_FADT_V2_SIZE)
366    {
367        AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt3);
368
369        /* Check for FADT revision 5 fields and up (ACPI 5.0+) */
370
371        if (Table->Length > ACPI_FADT_V3_SIZE)
372        {
373            AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt5);
374        }
375
376        /* Check for FADT revision 6 fields and up (ACPI 6.0+) */
377
378        if (Table->Length > ACPI_FADT_V3_SIZE)
379        {
380            AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt6);
381        }
382    }
383
384    /* Validate various fields in the FADT, including length */
385
386    AcpiTbCreateLocalFadt (Table, Table->Length);
387
388    /* Validate FADT length against the revision */
389
390    AcpiDmValidateFadtLength (Table->Revision, Table->Length);
391}
392
393
394/*******************************************************************************
395 *
396 * FUNCTION:    AcpiDmValidateFadtLength
397 *
398 * PARAMETERS:  Revision            - FADT revision (Header->Revision)
399 *              Length              - FADT length (Header->Length
400 *
401 * RETURN:      None
402 *
403 * DESCRIPTION: Check the FADT revision against the expected table length for
404 *              that revision. Issue a warning if the length is not what was
405 *              expected. This seems to be such a common BIOS bug that the
406 *              FADT revision has been rendered virtually meaningless.
407 *
408 ******************************************************************************/
409
410static void
411AcpiDmValidateFadtLength (
412    UINT32                  Revision,
413    UINT32                  Length)
414{
415    UINT32                  ExpectedLength;
416
417
418    switch (Revision)
419    {
420    case 0:
421
422        AcpiOsPrintf ("// ACPI Warning: Invalid FADT revision: 0\n");
423        return;
424
425    case 1:
426
427        ExpectedLength = ACPI_FADT_V1_SIZE;
428        break;
429
430    case 2:
431
432        ExpectedLength = ACPI_FADT_V2_SIZE;
433        break;
434
435    case 3:
436    case 4:
437
438        ExpectedLength = ACPI_FADT_V3_SIZE;
439        break;
440
441    case 5:
442
443        ExpectedLength = ACPI_FADT_V5_SIZE;
444        break;
445
446    default:
447
448        return;
449    }
450
451    if (Length == ExpectedLength)
452    {
453        return;
454    }
455
456    AcpiOsPrintf (
457        "\n// ACPI Warning: FADT revision %X does not match length: found %X expected %X\n",
458        Revision, Length, ExpectedLength);
459}
460
461
462/*******************************************************************************
463 *
464 * FUNCTION:    AcpiDmDumpAsf
465 *
466 * PARAMETERS:  Table               - A ASF table
467 *
468 * RETURN:      None
469 *
470 * DESCRIPTION: Format the contents of a ASF table
471 *
472 ******************************************************************************/
473
474void
475AcpiDmDumpAsf (
476    ACPI_TABLE_HEADER       *Table)
477{
478    ACPI_STATUS             Status;
479    UINT32                  Offset = sizeof (ACPI_TABLE_HEADER);
480    ACPI_ASF_INFO           *SubTable;
481    ACPI_DMTABLE_INFO       *InfoTable;
482    ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
483    UINT8                   *DataTable = NULL;
484    UINT32                  DataCount = 0;
485    UINT32                  DataLength = 0;
486    UINT32                  DataOffset = 0;
487    UINT32                  i;
488    UINT8                   Type;
489
490
491    /* No main table, only subtables */
492
493    SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
494    while (Offset < Table->Length)
495    {
496        /* Common subtable header */
497
498        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
499                    SubTable->Header.Length, AcpiDmTableInfoAsfHdr);
500        if (ACPI_FAILURE (Status))
501        {
502            return;
503        }
504
505        /* The actual type is the lower 7 bits of Type */
506
507        Type = (UINT8) (SubTable->Header.Type & 0x7F);
508
509        switch (Type)
510        {
511        case ACPI_ASF_TYPE_INFO:
512
513            InfoTable = AcpiDmTableInfoAsf0;
514            break;
515
516        case ACPI_ASF_TYPE_ALERT:
517
518            InfoTable = AcpiDmTableInfoAsf1;
519            DataInfoTable = AcpiDmTableInfoAsf1a;
520            DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ALERT));
521            DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->Alerts;
522            DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->DataLength;
523            DataOffset = Offset + sizeof (ACPI_ASF_ALERT);
524            break;
525
526        case ACPI_ASF_TYPE_CONTROL:
527
528            InfoTable = AcpiDmTableInfoAsf2;
529            DataInfoTable = AcpiDmTableInfoAsf2a;
530            DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_REMOTE));
531            DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->Controls;
532            DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->DataLength;
533            DataOffset = Offset + sizeof (ACPI_ASF_REMOTE);
534            break;
535
536        case ACPI_ASF_TYPE_BOOT:
537
538            InfoTable = AcpiDmTableInfoAsf3;
539            break;
540
541        case ACPI_ASF_TYPE_ADDRESS:
542
543            InfoTable = AcpiDmTableInfoAsf4;
544            DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ADDRESS));
545            DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, SubTable)->Devices;
546            DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS);
547            break;
548
549        default:
550
551            AcpiOsPrintf ("\n**** Unknown ASF subtable type 0x%X\n", SubTable->Header.Type);
552            return;
553        }
554
555        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
556                    SubTable->Header.Length, InfoTable);
557        if (ACPI_FAILURE (Status))
558        {
559            return;
560        }
561
562        /* Dump variable-length extra data */
563
564        switch (Type)
565        {
566        case ACPI_ASF_TYPE_ALERT:
567        case ACPI_ASF_TYPE_CONTROL:
568
569            for (i = 0; i < DataCount; i++)
570            {
571                AcpiOsPrintf ("\n");
572                Status = AcpiDmDumpTable (Table->Length, DataOffset,
573                            DataTable, DataLength, DataInfoTable);
574                if (ACPI_FAILURE (Status))
575                {
576                    return;
577                }
578
579                DataTable = ACPI_ADD_PTR (UINT8, DataTable, DataLength);
580                DataOffset += DataLength;
581            }
582            break;
583
584        case ACPI_ASF_TYPE_ADDRESS:
585
586            for (i = 0; i < DataLength; i++)
587            {
588                if (!(i % 16))
589                {
590                    AcpiDmLineHeader (DataOffset, 1, "Addresses");
591                }
592
593                AcpiOsPrintf ("%2.2X ", *DataTable);
594                DataTable++;
595                DataOffset++;
596                if (DataOffset > Table->Length)
597                {
598                    AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure! (ASF! table)\n");
599                    return;
600                }
601            }
602
603            AcpiOsPrintf ("\n");
604            break;
605
606        default:
607
608            break;
609        }
610
611        AcpiOsPrintf ("\n");
612
613        /* Point to next subtable */
614
615        if (!SubTable->Header.Length)
616        {
617            AcpiOsPrintf ("Invalid zero subtable header length\n");
618            return;
619        }
620
621        Offset += SubTable->Header.Length;
622        SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, SubTable, SubTable->Header.Length);
623    }
624}
625
626
627/*******************************************************************************
628 *
629 * FUNCTION:    AcpiDmDumpCpep
630 *
631 * PARAMETERS:  Table               - A CPEP table
632 *
633 * RETURN:      None
634 *
635 * DESCRIPTION: Format the contents of a CPEP. This table type consists
636 *              of an open-ended number of subtables.
637 *
638 ******************************************************************************/
639
640void
641AcpiDmDumpCpep (
642    ACPI_TABLE_HEADER       *Table)
643{
644    ACPI_STATUS             Status;
645    ACPI_CPEP_POLLING       *SubTable;
646    UINT32                  Length = Table->Length;
647    UINT32                  Offset = sizeof (ACPI_TABLE_CPEP);
648
649
650    /* Main table */
651
652    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoCpep);
653    if (ACPI_FAILURE (Status))
654    {
655        return;
656    }
657
658    /* Subtables */
659
660    SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
661    while (Offset < Table->Length)
662    {
663        AcpiOsPrintf ("\n");
664        Status = AcpiDmDumpTable (Length, Offset, SubTable,
665                    SubTable->Header.Length, AcpiDmTableInfoCpep0);
666        if (ACPI_FAILURE (Status))
667        {
668            return;
669        }
670
671        /* Point to next subtable */
672
673        Offset += SubTable->Header.Length;
674        SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, SubTable,
675                    SubTable->Header.Length);
676    }
677}
678
679
680/*******************************************************************************
681 *
682 * FUNCTION:    AcpiDmDumpCsrt
683 *
684 * PARAMETERS:  Table               - A CSRT table
685 *
686 * RETURN:      None
687 *
688 * DESCRIPTION: Format the contents of a CSRT. This table type consists
689 *              of an open-ended number of subtables.
690 *
691 ******************************************************************************/
692
693void
694AcpiDmDumpCsrt (
695    ACPI_TABLE_HEADER       *Table)
696{
697    ACPI_STATUS             Status;
698    ACPI_CSRT_GROUP         *SubTable;
699    ACPI_CSRT_SHARED_INFO   *SharedInfoTable;
700    ACPI_CSRT_DESCRIPTOR    *SubSubTable;
701    UINT32                  Length = Table->Length;
702    UINT32                  Offset = sizeof (ACPI_TABLE_CSRT);
703    UINT32                  SubOffset;
704    UINT32                  SubSubOffset;
705    UINT32                  InfoLength;
706
707
708    /* The main table only contains the ACPI header, thus already handled */
709
710    /* Subtables (Resource Groups) */
711
712    SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset);
713    while (Offset < Table->Length)
714    {
715        /* Resource group subtable */
716
717        AcpiOsPrintf ("\n");
718        Status = AcpiDmDumpTable (Length, Offset, SubTable,
719                    SubTable->Length, AcpiDmTableInfoCsrt0);
720        if (ACPI_FAILURE (Status))
721        {
722            return;
723        }
724
725        /* Shared info subtable (One per resource group) */
726
727        SubOffset = sizeof (ACPI_CSRT_GROUP);
728        SharedInfoTable = ACPI_ADD_PTR (ACPI_CSRT_SHARED_INFO, Table,
729            Offset + SubOffset);
730
731        AcpiOsPrintf ("\n");
732        Status = AcpiDmDumpTable (Length, Offset + SubOffset, SharedInfoTable,
733                    sizeof (ACPI_CSRT_SHARED_INFO), AcpiDmTableInfoCsrt1);
734        if (ACPI_FAILURE (Status))
735        {
736            return;
737        }
738
739        SubOffset += SubTable->SharedInfoLength;
740
741        /* Sub-Subtables (Resource Descriptors) */
742
743        SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table,
744            Offset + SubOffset);
745
746        while ((SubOffset < SubTable->Length) &&
747              ((Offset + SubOffset) < Table->Length))
748        {
749            AcpiOsPrintf ("\n");
750            Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubTable,
751                        SubSubTable->Length, AcpiDmTableInfoCsrt2);
752            if (ACPI_FAILURE (Status))
753            {
754                return;
755            }
756
757            SubSubOffset = sizeof (ACPI_CSRT_DESCRIPTOR);
758
759            /* Resource-specific info buffer */
760
761            InfoLength = SubSubTable->Length - SubSubOffset;
762            if (InfoLength)
763            {
764                Status = AcpiDmDumpTable (Length,
765                            Offset + SubOffset + SubSubOffset, Table,
766                            InfoLength, AcpiDmTableInfoCsrt2a);
767                if (ACPI_FAILURE (Status))
768                {
769                    return;
770                }
771                SubSubOffset += InfoLength;
772            }
773
774            /* Point to next sub-subtable */
775
776            SubOffset += SubSubTable->Length;
777            SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubTable,
778                        SubSubTable->Length);
779        }
780
781        /* Point to next subtable */
782
783        Offset += SubTable->Length;
784        SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, SubTable,
785                    SubTable->Length);
786    }
787}
788
789
790/*******************************************************************************
791 *
792 * FUNCTION:    AcpiDmDumpDbg2
793 *
794 * PARAMETERS:  Table               - A DBG2 table
795 *
796 * RETURN:      None
797 *
798 * DESCRIPTION: Format the contents of a DBG2. This table type consists
799 *              of an open-ended number of subtables.
800 *
801 ******************************************************************************/
802
803void
804AcpiDmDumpDbg2 (
805    ACPI_TABLE_HEADER       *Table)
806{
807    ACPI_STATUS             Status;
808    ACPI_DBG2_DEVICE        *SubTable;
809    UINT32                  Length = Table->Length;
810    UINT32                  Offset = sizeof (ACPI_TABLE_DBG2);
811    UINT32                  i;
812    UINT32                  ArrayOffset;
813    UINT32                  AbsoluteOffset;
814    UINT8                   *Array;
815
816
817    /* Main table */
818
819    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDbg2);
820    if (ACPI_FAILURE (Status))
821    {
822        return;
823    }
824
825    /* Subtables */
826
827    SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
828    while (Offset < Table->Length)
829    {
830        AcpiOsPrintf ("\n");
831        Status = AcpiDmDumpTable (Length, Offset, SubTable,
832                    SubTable->Length, AcpiDmTableInfoDbg2Device);
833        if (ACPI_FAILURE (Status))
834        {
835            return;
836        }
837
838        /* Dump the BaseAddress array */
839
840        for (i = 0; i < SubTable->RegisterCount; i++)
841        {
842            ArrayOffset = SubTable->BaseAddressOffset +
843                (sizeof (ACPI_GENERIC_ADDRESS) * i);
844            AbsoluteOffset = Offset + ArrayOffset;
845            Array = (UINT8 *) SubTable + ArrayOffset;
846
847            Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
848                        SubTable->Length, AcpiDmTableInfoDbg2Addr);
849            if (ACPI_FAILURE (Status))
850            {
851                return;
852            }
853        }
854
855        /* Dump the AddressSize array */
856
857        for (i = 0; i < SubTable->RegisterCount; i++)
858        {
859            ArrayOffset = SubTable->AddressSizeOffset +
860                (sizeof (UINT32) * i);
861            AbsoluteOffset = Offset + ArrayOffset;
862            Array = (UINT8 *) SubTable + ArrayOffset;
863
864            Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
865                        SubTable->Length, AcpiDmTableInfoDbg2Size);
866            if (ACPI_FAILURE (Status))
867            {
868                return;
869            }
870        }
871
872        /* Dump the Namestring (required) */
873
874        AcpiOsPrintf ("\n");
875        ArrayOffset = SubTable->NamepathOffset;
876        AbsoluteOffset = Offset + ArrayOffset;
877        Array = (UINT8 *) SubTable + ArrayOffset;
878
879        Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
880                    SubTable->Length, AcpiDmTableInfoDbg2Name);
881        if (ACPI_FAILURE (Status))
882        {
883            return;
884        }
885
886        /* Dump the OemData (optional) */
887
888        if (SubTable->OemDataOffset)
889        {
890            Status = AcpiDmDumpTable (Length, Offset + SubTable->OemDataOffset,
891                        Table, SubTable->OemDataLength,
892                        AcpiDmTableInfoDbg2OemData);
893            if (ACPI_FAILURE (Status))
894            {
895                return;
896            }
897        }
898
899        /* Point to next subtable */
900
901        Offset += SubTable->Length;
902        SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, SubTable,
903                    SubTable->Length);
904    }
905}
906
907
908/*******************************************************************************
909 *
910 * FUNCTION:    AcpiDmDumpDmar
911 *
912 * PARAMETERS:  Table               - A DMAR table
913 *
914 * RETURN:      None
915 *
916 * DESCRIPTION: Format the contents of a DMAR. This table type consists
917 *              of an open-ended number of subtables.
918 *
919 ******************************************************************************/
920
921void
922AcpiDmDumpDmar (
923    ACPI_TABLE_HEADER       *Table)
924{
925    ACPI_STATUS             Status;
926    ACPI_DMAR_HEADER        *SubTable;
927    UINT32                  Length = Table->Length;
928    UINT32                  Offset = sizeof (ACPI_TABLE_DMAR);
929    ACPI_DMTABLE_INFO       *InfoTable;
930    ACPI_DMAR_DEVICE_SCOPE  *ScopeTable;
931    UINT32                  ScopeOffset;
932    UINT8                   *PciPath;
933    UINT32                  PathOffset;
934
935
936    /* Main table */
937
938    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar);
939    if (ACPI_FAILURE (Status))
940    {
941        return;
942    }
943
944    /* Subtables */
945
946    SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
947    while (Offset < Table->Length)
948    {
949        /* Common subtable header */
950
951        AcpiOsPrintf ("\n");
952        Status = AcpiDmDumpTable (Length, Offset, SubTable,
953                    SubTable->Length, AcpiDmTableInfoDmarHdr);
954        if (ACPI_FAILURE (Status))
955        {
956            return;
957        }
958        AcpiOsPrintf ("\n");
959
960        switch (SubTable->Type)
961        {
962        case ACPI_DMAR_TYPE_HARDWARE_UNIT:
963
964            InfoTable = AcpiDmTableInfoDmar0;
965            ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT);
966            break;
967
968        case ACPI_DMAR_TYPE_RESERVED_MEMORY:
969
970            InfoTable = AcpiDmTableInfoDmar1;
971            ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY);
972            break;
973
974        case ACPI_DMAR_TYPE_ROOT_ATS:
975
976            InfoTable = AcpiDmTableInfoDmar2;
977            ScopeOffset = sizeof (ACPI_DMAR_ATSR);
978            break;
979
980        case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
981
982            InfoTable = AcpiDmTableInfoDmar3;
983            ScopeOffset = sizeof (ACPI_DMAR_RHSA);
984            break;
985
986        case ACPI_DMAR_TYPE_NAMESPACE:
987
988            InfoTable = AcpiDmTableInfoDmar4;
989            ScopeOffset = sizeof (ACPI_DMAR_ANDD);
990            break;
991
992        default:
993
994            AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n", SubTable->Type);
995            return;
996        }
997
998        Status = AcpiDmDumpTable (Length, Offset, SubTable,
999                    SubTable->Length, InfoTable);
1000        if (ACPI_FAILURE (Status))
1001        {
1002            return;
1003        }
1004
1005        /*
1006         * Dump the optional device scope entries
1007         */
1008        if ((SubTable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
1009            (SubTable->Type == ACPI_DMAR_TYPE_NAMESPACE))
1010        {
1011            /* These types do not support device scopes */
1012
1013            goto NextSubtable;
1014        }
1015
1016        ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, SubTable, ScopeOffset);
1017        while (ScopeOffset < SubTable->Length)
1018        {
1019            AcpiOsPrintf ("\n");
1020            Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
1021                        ScopeTable->Length, AcpiDmTableInfoDmarScope);
1022            if (ACPI_FAILURE (Status))
1023            {
1024                return;
1025            }
1026            AcpiOsPrintf ("\n");
1027
1028            /* Dump the PCI Path entries for this device scope */
1029
1030            PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */
1031
1032            PciPath = ACPI_ADD_PTR (UINT8, ScopeTable,
1033                sizeof (ACPI_DMAR_DEVICE_SCOPE));
1034
1035            while (PathOffset < ScopeTable->Length)
1036            {
1037                AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2, "PCI Path");
1038                AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]);
1039
1040                /* Point to next PCI Path entry */
1041
1042                PathOffset += 2;
1043                PciPath += 2;
1044                AcpiOsPrintf ("\n");
1045            }
1046
1047            /* Point to next device scope entry */
1048
1049            ScopeOffset += ScopeTable->Length;
1050            ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE,
1051                ScopeTable, ScopeTable->Length);
1052        }
1053
1054NextSubtable:
1055        /* Point to next subtable */
1056
1057        Offset += SubTable->Length;
1058        SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, SubTable, SubTable->Length);
1059    }
1060}
1061
1062
1063/*******************************************************************************
1064 *
1065 * FUNCTION:    AcpiDmDumpDrtm
1066 *
1067 * PARAMETERS:  Table               - A DRTM table
1068 *
1069 * RETURN:      None
1070 *
1071 * DESCRIPTION: Format the contents of a DRTM.
1072 *
1073 ******************************************************************************/
1074
1075void
1076AcpiDmDumpDrtm (
1077    ACPI_TABLE_HEADER       *Table)
1078{
1079    ACPI_STATUS             Status;
1080    UINT32                  Offset;
1081    ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
1082    ACPI_DRTM_RESOURCE_LIST *DrtmRl;
1083    ACPI_DRTM_DPS_ID        *DrtmDps;
1084    UINT32                  Count;
1085
1086
1087    /* Main table */
1088
1089    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
1090                AcpiDmTableInfoDrtm);
1091    if (ACPI_FAILURE (Status))
1092    {
1093        return;
1094    }
1095
1096    Offset = sizeof (ACPI_TABLE_DRTM);
1097
1098    /* Sub-tables */
1099
1100    /* Dump ValidatedTable length */
1101
1102    DrtmVtl = ACPI_ADD_PTR (ACPI_DRTM_VTABLE_LIST, Table, Offset);
1103    AcpiOsPrintf ("\n");
1104    Status = AcpiDmDumpTable (Table->Length, Offset,
1105                DrtmVtl, ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables),
1106                AcpiDmTableInfoDrtm0);
1107    if (ACPI_FAILURE (Status))
1108    {
1109            return;
1110    }
1111    Offset += ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables);
1112
1113    /* Dump Validated table addresses */
1114
1115    Count = 0;
1116    while ((Offset < Table->Length) &&
1117            (DrtmVtl->ValidatedTableCount > Count))
1118    {
1119        Status = AcpiDmDumpTable (Table->Length, Offset,
1120                    ACPI_ADD_PTR (void, Table, Offset), sizeof (UINT64),
1121                    AcpiDmTableInfoDrtm0a);
1122        if (ACPI_FAILURE (Status))
1123        {
1124            return;
1125        }
1126        Offset += sizeof (UINT64);
1127        Count++;
1128    }
1129
1130    /* Dump ResourceList length */
1131
1132    DrtmRl = ACPI_ADD_PTR (ACPI_DRTM_RESOURCE_LIST, Table, Offset);
1133    AcpiOsPrintf ("\n");
1134    Status = AcpiDmDumpTable (Table->Length, Offset,
1135                DrtmRl, ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources),
1136                AcpiDmTableInfoDrtm1);
1137    if (ACPI_FAILURE (Status))
1138    {
1139            return;
1140    }
1141
1142    Offset += ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources);
1143
1144    /* Dump the Resource List */
1145
1146    Count = 0;
1147    while ((Offset < Table->Length) &&
1148           (DrtmRl->ResourceCount > Count))
1149    {
1150        Status = AcpiDmDumpTable (Table->Length, Offset,
1151                    ACPI_ADD_PTR (void, Table, Offset),
1152                    sizeof (ACPI_DRTM_RESOURCE),
1153                    AcpiDmTableInfoDrtm1a);
1154        if (ACPI_FAILURE (Status))
1155        {
1156            return;
1157        }
1158
1159        Offset += sizeof (ACPI_DRTM_RESOURCE);
1160        Count++;
1161    }
1162
1163    /* Dump DPS */
1164
1165    DrtmDps = ACPI_ADD_PTR (ACPI_DRTM_DPS_ID, Table, Offset);
1166    AcpiOsPrintf ("\n");
1167    Status = AcpiDmDumpTable (Table->Length, Offset,
1168                DrtmDps, sizeof (ACPI_DRTM_DPS_ID),
1169                AcpiDmTableInfoDrtm2);
1170    if (ACPI_FAILURE (Status))
1171    {
1172        return;
1173    }
1174}
1175
1176
1177/*******************************************************************************
1178 *
1179 * FUNCTION:    AcpiDmDumpEinj
1180 *
1181 * PARAMETERS:  Table               - A EINJ table
1182 *
1183 * RETURN:      None
1184 *
1185 * DESCRIPTION: Format the contents of a EINJ. This table type consists
1186 *              of an open-ended number of subtables.
1187 *
1188 ******************************************************************************/
1189
1190void
1191AcpiDmDumpEinj (
1192    ACPI_TABLE_HEADER       *Table)
1193{
1194    ACPI_STATUS             Status;
1195    ACPI_WHEA_HEADER        *SubTable;
1196    UINT32                  Length = Table->Length;
1197    UINT32                  Offset = sizeof (ACPI_TABLE_EINJ);
1198
1199
1200    /* Main table */
1201
1202    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj);
1203    if (ACPI_FAILURE (Status))
1204    {
1205        return;
1206    }
1207
1208    /* Subtables */
1209
1210    SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
1211    while (Offset < Table->Length)
1212    {
1213        AcpiOsPrintf ("\n");
1214        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1215                    sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
1216        if (ACPI_FAILURE (Status))
1217        {
1218            return;
1219        }
1220
1221        /* Point to next subtable (each subtable is of fixed length) */
1222
1223        Offset += sizeof (ACPI_WHEA_HEADER);
1224        SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
1225                        sizeof (ACPI_WHEA_HEADER));
1226    }
1227}
1228
1229
1230/*******************************************************************************
1231 *
1232 * FUNCTION:    AcpiDmDumpErst
1233 *
1234 * PARAMETERS:  Table               - A ERST table
1235 *
1236 * RETURN:      None
1237 *
1238 * DESCRIPTION: Format the contents of a ERST. This table type consists
1239 *              of an open-ended number of subtables.
1240 *
1241 ******************************************************************************/
1242
1243void
1244AcpiDmDumpErst (
1245    ACPI_TABLE_HEADER       *Table)
1246{
1247    ACPI_STATUS             Status;
1248    ACPI_WHEA_HEADER        *SubTable;
1249    UINT32                  Length = Table->Length;
1250    UINT32                  Offset = sizeof (ACPI_TABLE_ERST);
1251
1252
1253    /* Main table */
1254
1255    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst);
1256    if (ACPI_FAILURE (Status))
1257    {
1258        return;
1259    }
1260
1261    /* Subtables */
1262
1263    SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
1264    while (Offset < Table->Length)
1265    {
1266        AcpiOsPrintf ("\n");
1267        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1268                    sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
1269        if (ACPI_FAILURE (Status))
1270        {
1271            return;
1272        }
1273
1274        /* Point to next subtable (each subtable is of fixed length) */
1275
1276        Offset += sizeof (ACPI_WHEA_HEADER);
1277        SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
1278                        sizeof (ACPI_WHEA_HEADER));
1279    }
1280}
1281
1282
1283/*******************************************************************************
1284 *
1285 * FUNCTION:    AcpiDmDumpFpdt
1286 *
1287 * PARAMETERS:  Table               - A FPDT table
1288 *
1289 * RETURN:      None
1290 *
1291 * DESCRIPTION: Format the contents of a FPDT. This table type consists
1292 *              of an open-ended number of subtables.
1293 *
1294 ******************************************************************************/
1295
1296void
1297AcpiDmDumpFpdt (
1298    ACPI_TABLE_HEADER       *Table)
1299{
1300    ACPI_STATUS             Status;
1301    ACPI_FPDT_HEADER        *SubTable;
1302    UINT32                  Length = Table->Length;
1303    UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
1304    ACPI_DMTABLE_INFO       *InfoTable;
1305
1306
1307    /* There is no main table (other than the standard ACPI header) */
1308
1309    /* Subtables */
1310
1311    SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
1312    while (Offset < Table->Length)
1313    {
1314        /* Common subtable header */
1315
1316        AcpiOsPrintf ("\n");
1317        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1318                    SubTable->Length, AcpiDmTableInfoFpdtHdr);
1319        if (ACPI_FAILURE (Status))
1320        {
1321            return;
1322        }
1323
1324        switch (SubTable->Type)
1325        {
1326        case ACPI_FPDT_TYPE_BOOT:
1327
1328            InfoTable = AcpiDmTableInfoFpdt0;
1329            break;
1330
1331        case ACPI_FPDT_TYPE_S3PERF:
1332
1333            InfoTable = AcpiDmTableInfoFpdt1;
1334            break;
1335
1336        default:
1337
1338            AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n", SubTable->Type);
1339
1340            /* Attempt to continue */
1341
1342            if (!SubTable->Length)
1343            {
1344                AcpiOsPrintf ("Invalid zero length subtable\n");
1345                return;
1346            }
1347            goto NextSubTable;
1348        }
1349
1350        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1351                    SubTable->Length, InfoTable);
1352        if (ACPI_FAILURE (Status))
1353        {
1354            return;
1355        }
1356
1357NextSubTable:
1358        /* Point to next subtable */
1359
1360        Offset += SubTable->Length;
1361        SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, SubTable, SubTable->Length);
1362    }
1363}
1364
1365
1366/*******************************************************************************
1367 *
1368 * FUNCTION:    AcpiDmDumpGtdt
1369 *
1370 * PARAMETERS:  Table               - A GTDT table
1371 *
1372 * RETURN:      None
1373 *
1374 * DESCRIPTION: Format the contents of a GTDT. This table type consists
1375 *              of an open-ended number of subtables.
1376 *
1377 ******************************************************************************/
1378
1379void
1380AcpiDmDumpGtdt (
1381    ACPI_TABLE_HEADER       *Table)
1382{
1383    ACPI_STATUS             Status;
1384    ACPI_GTDT_HEADER        *SubTable;
1385    UINT32                  Length = Table->Length;
1386    UINT32                  Offset = sizeof (ACPI_TABLE_GTDT);
1387    ACPI_DMTABLE_INFO       *InfoTable;
1388    UINT32                  SubTableLength;
1389    UINT32                  GtCount;
1390    ACPI_GTDT_TIMER_ENTRY   *GtxTable;
1391
1392
1393    /* Main table */
1394
1395    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoGtdt);
1396    if (ACPI_FAILURE (Status))
1397    {
1398        return;
1399    }
1400
1401    /* Subtables */
1402
1403    SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
1404    while (Offset < Table->Length)
1405    {
1406        /* Common subtable header */
1407
1408        AcpiOsPrintf ("\n");
1409        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1410                    SubTable->Length, AcpiDmTableInfoGtdtHdr);
1411        if (ACPI_FAILURE (Status))
1412        {
1413            return;
1414        }
1415
1416        GtCount = 0;
1417        switch (SubTable->Type)
1418        {
1419        case ACPI_GTDT_TYPE_TIMER_BLOCK:
1420
1421            SubTableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
1422            GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1423                        SubTable))->TimerCount;
1424
1425            InfoTable = AcpiDmTableInfoGtdt0;
1426            break;
1427
1428        case ACPI_GTDT_TYPE_WATCHDOG:
1429
1430            SubTableLength = sizeof (ACPI_GTDT_WATCHDOG);
1431
1432            InfoTable = AcpiDmTableInfoGtdt1;
1433            break;
1434
1435        default:
1436
1437            /* Cannot continue on unknown type - no length */
1438
1439            AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n", SubTable->Type);
1440            return;
1441        }
1442
1443        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1444                    SubTable->Length, InfoTable);
1445        if (ACPI_FAILURE (Status))
1446        {
1447            return;
1448        }
1449
1450        /* Point to end of current subtable (each subtable above is of fixed length) */
1451
1452        Offset += SubTableLength;
1453
1454        /* If there are any Gt Timer Blocks from above, dump them now */
1455
1456        if (GtCount)
1457        {
1458            GtxTable = ACPI_ADD_PTR (ACPI_GTDT_TIMER_ENTRY, SubTable, SubTableLength);
1459            SubTableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
1460
1461            while (GtCount)
1462            {
1463                AcpiOsPrintf ("\n");
1464                Status = AcpiDmDumpTable (Length, Offset, GtxTable,
1465                            sizeof (ACPI_GTDT_TIMER_ENTRY), AcpiDmTableInfoGtdt0a);
1466                if (ACPI_FAILURE (Status))
1467                {
1468                    return;
1469                }
1470                Offset += sizeof (ACPI_GTDT_TIMER_ENTRY);
1471                GtxTable++;
1472                GtCount--;
1473            }
1474        }
1475
1476        /* Point to next subtable */
1477
1478        SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, SubTable, SubTableLength);
1479    }
1480}
1481
1482
1483/*******************************************************************************
1484 *
1485 * FUNCTION:    AcpiDmDumpHest
1486 *
1487 * PARAMETERS:  Table               - A HEST table
1488 *
1489 * RETURN:      None
1490 *
1491 * DESCRIPTION: Format the contents of a HEST. This table type consists
1492 *              of an open-ended number of subtables.
1493 *
1494 ******************************************************************************/
1495
1496void
1497AcpiDmDumpHest (
1498    ACPI_TABLE_HEADER       *Table)
1499{
1500    ACPI_STATUS             Status;
1501    ACPI_HEST_HEADER        *SubTable;
1502    UINT32                  Length = Table->Length;
1503    UINT32                  Offset = sizeof (ACPI_TABLE_HEST);
1504    ACPI_DMTABLE_INFO       *InfoTable;
1505    UINT32                  SubTableLength;
1506    UINT32                  BankCount;
1507    ACPI_HEST_IA_ERROR_BANK *BankTable;
1508
1509
1510    /* Main table */
1511
1512    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest);
1513    if (ACPI_FAILURE (Status))
1514    {
1515        return;
1516    }
1517
1518    /* Subtables */
1519
1520    SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
1521    while (Offset < Table->Length)
1522    {
1523        BankCount = 0;
1524        switch (SubTable->Type)
1525        {
1526        case ACPI_HEST_TYPE_IA32_CHECK:
1527
1528            InfoTable = AcpiDmTableInfoHest0;
1529            SubTableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
1530            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1531                            SubTable))->NumHardwareBanks;
1532            break;
1533
1534        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1535
1536            InfoTable = AcpiDmTableInfoHest1;
1537            SubTableLength = sizeof (ACPI_HEST_IA_CORRECTED);
1538            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1539                            SubTable))->NumHardwareBanks;
1540            break;
1541
1542        case ACPI_HEST_TYPE_IA32_NMI:
1543
1544            InfoTable = AcpiDmTableInfoHest2;
1545            SubTableLength = sizeof (ACPI_HEST_IA_NMI);
1546            break;
1547
1548        case ACPI_HEST_TYPE_AER_ROOT_PORT:
1549
1550            InfoTable = AcpiDmTableInfoHest6;
1551            SubTableLength = sizeof (ACPI_HEST_AER_ROOT);
1552            break;
1553
1554        case ACPI_HEST_TYPE_AER_ENDPOINT:
1555
1556            InfoTable = AcpiDmTableInfoHest7;
1557            SubTableLength = sizeof (ACPI_HEST_AER);
1558            break;
1559
1560        case ACPI_HEST_TYPE_AER_BRIDGE:
1561
1562            InfoTable = AcpiDmTableInfoHest8;
1563            SubTableLength = sizeof (ACPI_HEST_AER_BRIDGE);
1564            break;
1565
1566        case ACPI_HEST_TYPE_GENERIC_ERROR:
1567
1568            InfoTable = AcpiDmTableInfoHest9;
1569            SubTableLength = sizeof (ACPI_HEST_GENERIC);
1570            break;
1571
1572        default:
1573
1574            /* Cannot continue on unknown type - no length */
1575
1576            AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n", SubTable->Type);
1577            return;
1578        }
1579
1580        AcpiOsPrintf ("\n");
1581        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1582                    SubTableLength, InfoTable);
1583        if (ACPI_FAILURE (Status))
1584        {
1585            return;
1586        }
1587
1588        /* Point to end of current subtable (each subtable above is of fixed length) */
1589
1590        Offset += SubTableLength;
1591
1592        /* If there are any (fixed-length) Error Banks from above, dump them now */
1593
1594        if (BankCount)
1595        {
1596            BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, SubTable, SubTableLength);
1597            SubTableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
1598
1599            while (BankCount)
1600            {
1601                AcpiOsPrintf ("\n");
1602                Status = AcpiDmDumpTable (Length, Offset, BankTable,
1603                            sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank);
1604                if (ACPI_FAILURE (Status))
1605                {
1606                    return;
1607                }
1608                Offset += sizeof (ACPI_HEST_IA_ERROR_BANK);
1609                BankTable++;
1610                BankCount--;
1611            }
1612        }
1613
1614        /* Point to next subtable */
1615
1616        SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, SubTable, SubTableLength);
1617    }
1618}
1619
1620
1621/*******************************************************************************
1622 *
1623 * FUNCTION:    AcpiDmDumpIort
1624 *
1625 * PARAMETERS:  Table               - A IORT table
1626 *
1627 * RETURN:      None
1628 *
1629 * DESCRIPTION: Format the contents of a IORT
1630 *
1631 ******************************************************************************/
1632
1633void
1634AcpiDmDumpIort (
1635    ACPI_TABLE_HEADER       *Table)
1636{
1637    ACPI_STATUS             Status;
1638    ACPI_TABLE_IORT         *Iort;
1639    ACPI_IORT_NODE          *IortNode;
1640    ACPI_IORT_ITS_GROUP     *IortItsGroup = NULL;
1641    ACPI_IORT_SMMU          *IortSmmu = NULL;
1642    UINT32                  Offset;
1643    UINT32                  NodeOffset;
1644    UINT32                  Length;
1645    ACPI_DMTABLE_INFO       *InfoTable;
1646    char                    *String;
1647    UINT32                  i;
1648
1649
1650    /* Main table */
1651
1652    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIort);
1653    if (ACPI_FAILURE (Status))
1654    {
1655        return;
1656    }
1657
1658    Iort = ACPI_CAST_PTR (ACPI_TABLE_IORT, Table);
1659    Offset = sizeof (ACPI_TABLE_IORT);
1660
1661    /* Dump the OptionalPadding (optional) */
1662
1663    if (Iort->NodeOffset > Offset)
1664    {
1665        Status = AcpiDmDumpTable (Table->Length, Offset, Table,
1666                    Iort->NodeOffset - Offset, AcpiDmTableInfoIortPad);
1667        if (ACPI_FAILURE (Status))
1668        {
1669            return;
1670        }
1671    }
1672
1673    Offset = Iort->NodeOffset;
1674    while (Offset < Table->Length)
1675    {
1676        /* Common subtable header */
1677
1678        IortNode = ACPI_ADD_PTR (ACPI_IORT_NODE, Table, Offset);
1679        AcpiOsPrintf ("\n");
1680        Length = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1681        Status = AcpiDmDumpTable (Table->Length, Offset,
1682                    IortNode, Length, AcpiDmTableInfoIortHdr);
1683        if (ACPI_FAILURE (Status))
1684        {
1685            return;
1686        }
1687
1688        NodeOffset = Length;
1689
1690        switch (IortNode->Type)
1691        {
1692        case ACPI_IORT_NODE_ITS_GROUP:
1693
1694            InfoTable = AcpiDmTableInfoIort0;
1695            Length = ACPI_OFFSET (ACPI_IORT_ITS_GROUP, Identifiers);
1696            IortItsGroup = ACPI_ADD_PTR (ACPI_IORT_ITS_GROUP, IortNode, NodeOffset);
1697            break;
1698
1699        case ACPI_IORT_NODE_NAMED_COMPONENT:
1700
1701            InfoTable = AcpiDmTableInfoIort1;
1702            Length = ACPI_OFFSET (ACPI_IORT_NAMED_COMPONENT, DeviceName);
1703            String = ACPI_ADD_PTR (char, IortNode, NodeOffset + Length);
1704            Length += ACPI_STRLEN (String) + 1;
1705            break;
1706
1707        case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
1708
1709            InfoTable = AcpiDmTableInfoIort2;
1710            Length = IortNode->Length - NodeOffset;
1711            break;
1712
1713        case ACPI_IORT_NODE_SMMU:
1714
1715            InfoTable = AcpiDmTableInfoIort3;
1716            Length = ACPI_OFFSET (ACPI_IORT_SMMU, Interrupts);
1717            IortSmmu = ACPI_ADD_PTR (ACPI_IORT_SMMU, IortNode, NodeOffset);
1718            break;
1719
1720        default:
1721
1722            AcpiOsPrintf ("\n**** Unknown IORT node type 0x%X\n",
1723                IortNode->Type);
1724
1725            /* Attempt to continue */
1726
1727            if (!IortNode->Length)
1728            {
1729                AcpiOsPrintf ("Invalid zero length IORT node\n");
1730                return;
1731            }
1732            goto NextSubTable;
1733        }
1734
1735        /* Dump the node subtable header */
1736
1737        AcpiOsPrintf ("\n");
1738        Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
1739                    ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
1740                    Length, InfoTable);
1741        if (ACPI_FAILURE (Status))
1742        {
1743            return;
1744        }
1745
1746        NodeOffset += Length;
1747
1748        /* Dump the node specific data */
1749
1750        switch (IortNode->Type)
1751        {
1752        case ACPI_IORT_NODE_ITS_GROUP:
1753
1754            /* Validate IortItsGroup to avoid compiler warnings */
1755
1756            if (IortItsGroup)
1757            {
1758                for (i = 0; i < IortItsGroup->ItsCount; i++)
1759                {
1760                    Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
1761                                ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
1762                                4, AcpiDmTableInfoIort0a);
1763                    NodeOffset += 4;
1764                }
1765            }
1766            break;
1767
1768        case ACPI_IORT_NODE_NAMED_COMPONENT:
1769
1770            /* Dump the Padding (optional) */
1771
1772            if (IortNode->Length > NodeOffset)
1773            {
1774                Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
1775                            Table, IortNode->Length - NodeOffset,
1776                            AcpiDmTableInfoIort1a);
1777                if (ACPI_FAILURE (Status))
1778                {
1779                    return;
1780                }
1781            }
1782            break;
1783
1784        case ACPI_IORT_NODE_SMMU:
1785
1786            AcpiOsPrintf ("\n");
1787
1788            /* Validate IortSmmu to avoid compiler warnings */
1789
1790            if (IortSmmu)
1791            {
1792                Length = 2 * sizeof (UINT64);
1793                NodeOffset = IortSmmu->GlobalInterruptOffset;
1794                Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
1795                            ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
1796                            Length, AcpiDmTableInfoIort3a);
1797
1798                NodeOffset = IortSmmu->ContextInterruptOffset;
1799                for (i = 0; i < IortSmmu->ContextInterruptCount; i++)
1800                {
1801                    Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
1802                                ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
1803                                8, AcpiDmTableInfoIort3b);
1804                    NodeOffset += 8;
1805                }
1806
1807                NodeOffset = IortSmmu->PmuInterruptOffset;
1808                for (i = 0; i < IortSmmu->PmuInterruptCount; i++)
1809                {
1810                    Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
1811                                ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
1812                                8, AcpiDmTableInfoIort3c);
1813                    NodeOffset += 8;
1814                }
1815            }
1816            break;
1817
1818        default:
1819
1820            break;
1821        }
1822
1823        /* Dump the ID mappings */
1824
1825        NodeOffset = IortNode->MappingOffset;
1826        for (i = 0; i < IortNode->MappingCount; i++)
1827        {
1828            AcpiOsPrintf ("\n");
1829            Length = sizeof (ACPI_IORT_ID_MAPPING);
1830            Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
1831                        ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
1832                        Length, AcpiDmTableInfoIortMap);
1833            NodeOffset += Length;
1834        }
1835
1836NextSubTable:
1837        /* Point to next node subtable */
1838
1839        Offset += IortNode->Length;
1840        IortNode = ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, IortNode->Length);
1841    }
1842}
1843
1844
1845/*******************************************************************************
1846 *
1847 * FUNCTION:    AcpiDmDumpIvrs
1848 *
1849 * PARAMETERS:  Table               - A IVRS table
1850 *
1851 * RETURN:      None
1852 *
1853 * DESCRIPTION: Format the contents of a IVRS
1854 *
1855 ******************************************************************************/
1856
1857static UINT8 EntrySizes[] = {4,8,16,32};
1858
1859void
1860AcpiDmDumpIvrs (
1861    ACPI_TABLE_HEADER       *Table)
1862{
1863    ACPI_STATUS             Status;
1864    UINT32                  Offset = sizeof (ACPI_TABLE_IVRS);
1865    UINT32                  EntryOffset;
1866    UINT32                  EntryLength;
1867    UINT32                  EntryType;
1868    ACPI_IVRS_DE_HEADER     *DeviceEntry;
1869    ACPI_IVRS_HEADER        *SubTable;
1870    ACPI_DMTABLE_INFO       *InfoTable;
1871
1872
1873    /* Main table */
1874
1875    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs);
1876    if (ACPI_FAILURE (Status))
1877    {
1878        return;
1879    }
1880
1881    /* Subtables */
1882
1883    SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
1884    while (Offset < Table->Length)
1885    {
1886        /* Common subtable header */
1887
1888        AcpiOsPrintf ("\n");
1889        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1890                    SubTable->Length, AcpiDmTableInfoIvrsHdr);
1891        if (ACPI_FAILURE (Status))
1892        {
1893            return;
1894        }
1895
1896        switch (SubTable->Type)
1897        {
1898        case ACPI_IVRS_TYPE_HARDWARE:
1899
1900            InfoTable = AcpiDmTableInfoIvrs0;
1901            break;
1902
1903        case ACPI_IVRS_TYPE_MEMORY1:
1904        case ACPI_IVRS_TYPE_MEMORY2:
1905        case ACPI_IVRS_TYPE_MEMORY3:
1906
1907            InfoTable = AcpiDmTableInfoIvrs1;
1908            break;
1909
1910        default:
1911
1912            AcpiOsPrintf ("\n**** Unknown IVRS subtable type 0x%X\n",
1913                SubTable->Type);
1914
1915            /* Attempt to continue */
1916
1917            if (!SubTable->Length)
1918            {
1919                AcpiOsPrintf ("Invalid zero length subtable\n");
1920                return;
1921            }
1922            goto NextSubTable;
1923        }
1924
1925        /* Dump the subtable */
1926
1927        AcpiOsPrintf ("\n");
1928        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1929                    SubTable->Length, InfoTable);
1930        if (ACPI_FAILURE (Status))
1931        {
1932            return;
1933        }
1934
1935        /* The hardware subtable can contain multiple device entries */
1936
1937        if (SubTable->Type == ACPI_IVRS_TYPE_HARDWARE)
1938        {
1939            EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE);
1940            DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, SubTable,
1941                            sizeof (ACPI_IVRS_HARDWARE));
1942
1943            while (EntryOffset < (Offset + SubTable->Length))
1944            {
1945                AcpiOsPrintf ("\n");
1946                /*
1947                 * Upper 2 bits of Type encode the length of the device entry
1948                 *
1949                 * 00 = 4 byte
1950                 * 01 = 8 byte
1951                 * 10 = 16 byte - currently no entries defined
1952                 * 11 = 32 byte - currently no entries defined
1953                 */
1954                EntryType = DeviceEntry->Type;
1955                EntryLength = EntrySizes [EntryType >> 6];
1956
1957                switch (EntryType)
1958                {
1959                /* 4-byte device entries */
1960
1961                case ACPI_IVRS_TYPE_PAD4:
1962                case ACPI_IVRS_TYPE_ALL:
1963                case ACPI_IVRS_TYPE_SELECT:
1964                case ACPI_IVRS_TYPE_START:
1965                case ACPI_IVRS_TYPE_END:
1966
1967                    InfoTable = AcpiDmTableInfoIvrs4;
1968                    break;
1969
1970                /* 8-byte entries, type A */
1971
1972                case ACPI_IVRS_TYPE_ALIAS_SELECT:
1973                case ACPI_IVRS_TYPE_ALIAS_START:
1974
1975                    InfoTable = AcpiDmTableInfoIvrs8a;
1976                    break;
1977
1978                /* 8-byte entries, type B */
1979
1980                case ACPI_IVRS_TYPE_PAD8:
1981                case ACPI_IVRS_TYPE_EXT_SELECT:
1982                case ACPI_IVRS_TYPE_EXT_START:
1983
1984                    InfoTable = AcpiDmTableInfoIvrs8b;
1985                    break;
1986
1987                /* 8-byte entries, type C */
1988
1989                case ACPI_IVRS_TYPE_SPECIAL:
1990
1991                    InfoTable = AcpiDmTableInfoIvrs8c;
1992                    break;
1993
1994                default:
1995                    InfoTable = AcpiDmTableInfoIvrs4;
1996                    AcpiOsPrintf (
1997                        "\n**** Unknown IVRS device entry type/length: "
1998                        "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
1999                        EntryType, EntryLength, EntryOffset);
2000                    break;
2001                }
2002
2003                /* Dump the Device Entry */
2004
2005                Status = AcpiDmDumpTable (Table->Length, EntryOffset,
2006                            DeviceEntry, EntryLength, InfoTable);
2007
2008                EntryOffset += EntryLength;
2009                DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, DeviceEntry,
2010                                EntryLength);
2011            }
2012        }
2013
2014NextSubTable:
2015        /* Point to next subtable */
2016
2017        Offset += SubTable->Length;
2018        SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, SubTable, SubTable->Length);
2019    }
2020}
2021
2022
2023/*******************************************************************************
2024 *
2025 * FUNCTION:    AcpiDmDumpLpit
2026 *
2027 * PARAMETERS:  Table               - A LPIT table
2028 *
2029 * RETURN:      None
2030 *
2031 * DESCRIPTION: Format the contents of a LPIT. This table type consists
2032 *              of an open-ended number of subtables. Note: There are no
2033 *              entries in the main table. An LPIT consists of the table
2034 *              header and then subtables only.
2035 *
2036 ******************************************************************************/
2037
2038void
2039AcpiDmDumpLpit (
2040    ACPI_TABLE_HEADER       *Table)
2041{
2042    ACPI_STATUS             Status;
2043    ACPI_LPIT_HEADER        *SubTable;
2044    UINT32                  Length = Table->Length;
2045    UINT32                  Offset = sizeof (ACPI_TABLE_LPIT);
2046    ACPI_DMTABLE_INFO       *InfoTable;
2047    UINT32                  SubTableLength;
2048
2049
2050    /* Subtables */
2051
2052    SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset);
2053    while (Offset < Table->Length)
2054    {
2055        /* Common subtable header */
2056
2057        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2058                    sizeof (ACPI_LPIT_HEADER), AcpiDmTableInfoLpitHdr);
2059        if (ACPI_FAILURE (Status))
2060        {
2061            return;
2062        }
2063
2064        switch (SubTable->Type)
2065        {
2066        case ACPI_LPIT_TYPE_NATIVE_CSTATE:
2067
2068            InfoTable = AcpiDmTableInfoLpit0;
2069            SubTableLength = sizeof (ACPI_LPIT_NATIVE);
2070            break;
2071
2072        default:
2073
2074            /* Cannot continue on unknown type - no length */
2075
2076            AcpiOsPrintf ("\n**** Unknown LPIT subtable type 0x%X\n", SubTable->Type);
2077            return;
2078        }
2079
2080        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2081                    SubTableLength, InfoTable);
2082        if (ACPI_FAILURE (Status))
2083        {
2084            return;
2085        }
2086        AcpiOsPrintf ("\n");
2087
2088        /* Point to next subtable */
2089
2090        Offset += SubTableLength;
2091        SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, SubTable, SubTableLength);
2092    }
2093}
2094
2095
2096/*******************************************************************************
2097 *
2098 * FUNCTION:    AcpiDmDumpMadt
2099 *
2100 * PARAMETERS:  Table               - A MADT table
2101 *
2102 * RETURN:      None
2103 *
2104 * DESCRIPTION: Format the contents of a MADT. This table type consists
2105 *              of an open-ended number of subtables.
2106 *
2107 ******************************************************************************/
2108
2109void
2110AcpiDmDumpMadt (
2111    ACPI_TABLE_HEADER       *Table)
2112{
2113    ACPI_STATUS             Status;
2114    ACPI_SUBTABLE_HEADER    *SubTable;
2115    UINT32                  Length = Table->Length;
2116    UINT32                  Offset = sizeof (ACPI_TABLE_MADT);
2117    ACPI_DMTABLE_INFO       *InfoTable;
2118
2119
2120    /* Main table */
2121
2122    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoMadt);
2123    if (ACPI_FAILURE (Status))
2124    {
2125        return;
2126    }
2127
2128    /* Subtables */
2129
2130    SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
2131    while (Offset < Table->Length)
2132    {
2133        /* Common subtable header */
2134
2135        AcpiOsPrintf ("\n");
2136        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2137                    SubTable->Length, AcpiDmTableInfoMadtHdr);
2138        if (ACPI_FAILURE (Status))
2139        {
2140            return;
2141        }
2142
2143        switch (SubTable->Type)
2144        {
2145        case ACPI_MADT_TYPE_LOCAL_APIC:
2146
2147            InfoTable = AcpiDmTableInfoMadt0;
2148            break;
2149
2150        case ACPI_MADT_TYPE_IO_APIC:
2151
2152            InfoTable = AcpiDmTableInfoMadt1;
2153            break;
2154
2155        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
2156
2157            InfoTable = AcpiDmTableInfoMadt2;
2158            break;
2159
2160        case ACPI_MADT_TYPE_NMI_SOURCE:
2161
2162            InfoTable = AcpiDmTableInfoMadt3;
2163            break;
2164
2165        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
2166
2167            InfoTable = AcpiDmTableInfoMadt4;
2168            break;
2169
2170        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
2171
2172            InfoTable = AcpiDmTableInfoMadt5;
2173            break;
2174
2175        case ACPI_MADT_TYPE_IO_SAPIC:
2176
2177            InfoTable = AcpiDmTableInfoMadt6;
2178            break;
2179
2180        case ACPI_MADT_TYPE_LOCAL_SAPIC:
2181
2182            InfoTable = AcpiDmTableInfoMadt7;
2183            break;
2184
2185        case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
2186
2187            InfoTable = AcpiDmTableInfoMadt8;
2188            break;
2189
2190        case ACPI_MADT_TYPE_LOCAL_X2APIC:
2191
2192            InfoTable = AcpiDmTableInfoMadt9;
2193            break;
2194
2195        case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
2196
2197            InfoTable = AcpiDmTableInfoMadt10;
2198            break;
2199
2200        case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
2201
2202            InfoTable = AcpiDmTableInfoMadt11;
2203            break;
2204
2205        case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
2206
2207            InfoTable = AcpiDmTableInfoMadt12;
2208            break;
2209
2210        case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
2211
2212            InfoTable = AcpiDmTableInfoMadt13;
2213            break;
2214
2215        case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
2216
2217            InfoTable = AcpiDmTableInfoMadt14;
2218            break;
2219
2220        case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
2221
2222            InfoTable = AcpiDmTableInfoMadt15;
2223            break;
2224
2225        default:
2226
2227            AcpiOsPrintf ("\n**** Unknown MADT subtable type 0x%X\n\n", SubTable->Type);
2228
2229            /* Attempt to continue */
2230
2231            if (!SubTable->Length)
2232            {
2233                AcpiOsPrintf ("Invalid zero length subtable\n");
2234                return;
2235            }
2236            goto NextSubTable;
2237        }
2238
2239        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2240                    SubTable->Length, InfoTable);
2241        if (ACPI_FAILURE (Status))
2242        {
2243            return;
2244        }
2245
2246NextSubTable:
2247        /* Point to next subtable */
2248
2249        Offset += SubTable->Length;
2250        SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length);
2251    }
2252}
2253
2254
2255/*******************************************************************************
2256 *
2257 * FUNCTION:    AcpiDmDumpMcfg
2258 *
2259 * PARAMETERS:  Table               - A MCFG Table
2260 *
2261 * RETURN:      None
2262 *
2263 * DESCRIPTION: Format the contents of a MCFG table
2264 *
2265 ******************************************************************************/
2266
2267void
2268AcpiDmDumpMcfg (
2269    ACPI_TABLE_HEADER       *Table)
2270{
2271    ACPI_STATUS             Status;
2272    UINT32                  Offset = sizeof (ACPI_TABLE_MCFG);
2273    ACPI_MCFG_ALLOCATION    *SubTable;
2274
2275
2276    /* Main table */
2277
2278    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMcfg);
2279    if (ACPI_FAILURE (Status))
2280    {
2281        return;
2282    }
2283
2284    /* Subtables */
2285
2286    SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
2287    while (Offset < Table->Length)
2288    {
2289        if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length)
2290        {
2291            AcpiOsPrintf ("Warning: there are %u invalid trailing bytes\n",
2292                sizeof (ACPI_MCFG_ALLOCATION) - (Offset - Table->Length));
2293            return;
2294        }
2295
2296        AcpiOsPrintf ("\n");
2297        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2298                    sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0);
2299        if (ACPI_FAILURE (Status))
2300        {
2301            return;
2302        }
2303
2304        /* Point to next subtable (each subtable is of fixed length) */
2305
2306        Offset += sizeof (ACPI_MCFG_ALLOCATION);
2307        SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, SubTable,
2308                        sizeof (ACPI_MCFG_ALLOCATION));
2309    }
2310}
2311
2312
2313/*******************************************************************************
2314 *
2315 * FUNCTION:    AcpiDmDumpMpst
2316 *
2317 * PARAMETERS:  Table               - A MPST Table
2318 *
2319 * RETURN:      None
2320 *
2321 * DESCRIPTION: Format the contents of a MPST table
2322 *
2323 ******************************************************************************/
2324
2325void
2326AcpiDmDumpMpst (
2327    ACPI_TABLE_HEADER       *Table)
2328{
2329    ACPI_STATUS             Status;
2330    UINT32                  Offset = sizeof (ACPI_TABLE_MPST);
2331    ACPI_MPST_POWER_NODE    *SubTable0;
2332    ACPI_MPST_POWER_STATE   *SubTable0A;
2333    ACPI_MPST_COMPONENT     *SubTable0B;
2334    ACPI_MPST_DATA_HDR      *SubTable1;
2335    ACPI_MPST_POWER_DATA    *SubTable2;
2336    UINT16                  SubtableCount;
2337    UINT32                  PowerStateCount;
2338    UINT32                  ComponentCount;
2339
2340
2341    /* Main table */
2342
2343    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMpst);
2344    if (ACPI_FAILURE (Status))
2345    {
2346        return;
2347    }
2348
2349    /* Subtable: Memory Power Node(s) */
2350
2351    SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount;
2352    SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
2353
2354    while ((Offset < Table->Length) && SubtableCount)
2355    {
2356        AcpiOsPrintf ("\n");
2357        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0,
2358                    sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0);
2359        if (ACPI_FAILURE (Status))
2360        {
2361            return;
2362        }
2363
2364        /* Extract the sub-subtable counts */
2365
2366        PowerStateCount = SubTable0->NumPowerStates;
2367        ComponentCount = SubTable0->NumPhysicalComponents;
2368        Offset += sizeof (ACPI_MPST_POWER_NODE);
2369
2370        /* Sub-subtables - Memory Power State Structure(s) */
2371
2372        SubTable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, SubTable0,
2373            sizeof (ACPI_MPST_POWER_NODE));
2374
2375        while (PowerStateCount)
2376        {
2377            AcpiOsPrintf ("\n");
2378            Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0A,
2379                        sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A);
2380            if (ACPI_FAILURE (Status))
2381            {
2382                return;
2383            }
2384
2385            SubTable0A++;
2386            PowerStateCount--;
2387            Offset += sizeof (ACPI_MPST_POWER_STATE);
2388       }
2389
2390        /* Sub-subtables - Physical Component ID Structure(s) */
2391
2392        SubTable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, SubTable0A);
2393
2394        if (ComponentCount)
2395        {
2396            AcpiOsPrintf ("\n");
2397        }
2398
2399        while (ComponentCount)
2400        {
2401            Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0B,
2402                        sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B);
2403            if (ACPI_FAILURE (Status))
2404            {
2405                return;
2406            }
2407
2408            SubTable0B++;
2409            ComponentCount--;
2410            Offset += sizeof (ACPI_MPST_COMPONENT);
2411        }
2412
2413        /* Point to next Memory Power Node subtable */
2414
2415        SubtableCount--;
2416        SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, SubTable0,
2417            sizeof (ACPI_MPST_POWER_NODE) +
2418            (sizeof (ACPI_MPST_POWER_STATE) * SubTable0->NumPowerStates) +
2419            (sizeof (ACPI_MPST_COMPONENT) * SubTable0->NumPhysicalComponents));
2420    }
2421
2422    /* Subtable: Count of Memory Power State Characteristic structures */
2423
2424    AcpiOsPrintf ("\n");
2425    SubTable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, SubTable0);
2426    Status = AcpiDmDumpTable (Table->Length, Offset, SubTable1,
2427                sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1);
2428    if (ACPI_FAILURE (Status))
2429    {
2430        return;
2431    }
2432
2433    SubtableCount = SubTable1->CharacteristicsCount;
2434    Offset += sizeof (ACPI_MPST_DATA_HDR);
2435
2436    /* Subtable: Memory Power State Characteristics structure(s) */
2437
2438    SubTable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, SubTable1, sizeof (ACPI_MPST_DATA_HDR));
2439
2440    while ((Offset < Table->Length) && SubtableCount)
2441    {
2442        AcpiOsPrintf ("\n");
2443        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable2,
2444                    sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2);
2445        if (ACPI_FAILURE (Status))
2446        {
2447            return;
2448        }
2449
2450        SubTable2++;
2451        SubtableCount--;
2452        Offset += sizeof (ACPI_MPST_POWER_DATA);
2453    }
2454}
2455
2456
2457/*******************************************************************************
2458 *
2459 * FUNCTION:    AcpiDmDumpMsct
2460 *
2461 * PARAMETERS:  Table               - A MSCT table
2462 *
2463 * RETURN:      None
2464 *
2465 * DESCRIPTION: Format the contents of a MSCT
2466 *
2467 ******************************************************************************/
2468
2469void
2470AcpiDmDumpMsct (
2471    ACPI_TABLE_HEADER       *Table)
2472{
2473    ACPI_STATUS             Status;
2474    UINT32                  Offset = sizeof (ACPI_TABLE_MSCT);
2475    ACPI_MSCT_PROXIMITY     *SubTable;
2476
2477
2478    /* Main table */
2479
2480    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct);
2481    if (ACPI_FAILURE (Status))
2482    {
2483        return;
2484    }
2485
2486    /* Subtables */
2487
2488    SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
2489    while (Offset < Table->Length)
2490    {
2491        /* Common subtable header */
2492
2493        AcpiOsPrintf ("\n");
2494        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2495                    sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0);
2496        if (ACPI_FAILURE (Status))
2497        {
2498            return;
2499        }
2500
2501        /* Point to next subtable */
2502
2503        Offset += sizeof (ACPI_MSCT_PROXIMITY);
2504        SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, SubTable, sizeof (ACPI_MSCT_PROXIMITY));
2505    }
2506}
2507
2508
2509/*******************************************************************************
2510 *
2511 * FUNCTION:    AcpiDmDumpMtmr
2512 *
2513 * PARAMETERS:  Table               - A MTMR table
2514 *
2515 * RETURN:      None
2516 *
2517 * DESCRIPTION: Format the contents of a MTMR
2518 *
2519 ******************************************************************************/
2520
2521void
2522AcpiDmDumpMtmr (
2523    ACPI_TABLE_HEADER       *Table)
2524{
2525    ACPI_STATUS             Status;
2526    UINT32                  Offset = sizeof (ACPI_TABLE_MTMR);
2527    ACPI_MTMR_ENTRY         *SubTable;
2528
2529
2530    /* Main table */
2531
2532    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMtmr);
2533    if (ACPI_FAILURE (Status))
2534    {
2535        return;
2536    }
2537
2538    /* Subtables */
2539
2540    SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Table, Offset);
2541    while (Offset < Table->Length)
2542    {
2543        /* Common subtable header */
2544
2545        AcpiOsPrintf ("\n");
2546        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2547                    sizeof (ACPI_MTMR_ENTRY), AcpiDmTableInfoMtmr0);
2548        if (ACPI_FAILURE (Status))
2549        {
2550            return;
2551        }
2552
2553        /* Point to next subtable */
2554
2555        Offset += sizeof (ACPI_MTMR_ENTRY);
2556        SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, SubTable, sizeof (ACPI_MTMR_ENTRY));
2557    }
2558}
2559
2560
2561/*******************************************************************************
2562 *
2563 * FUNCTION:    AcpiDmDumpNfit
2564 *
2565 * PARAMETERS:  Table               - A NFIT table
2566 *
2567 * RETURN:      None
2568 *
2569 * DESCRIPTION: Format the contents of an NFIT.
2570 *
2571 ******************************************************************************/
2572
2573void
2574AcpiDmDumpNfit (
2575    ACPI_TABLE_HEADER       *Table)
2576{
2577    ACPI_STATUS             Status;
2578    UINT32                  Offset = sizeof (ACPI_TABLE_NFIT);
2579    UINT32                  FieldOffset = 0;
2580    UINT32                  Length;
2581    ACPI_NFIT_HEADER        *SubTable;
2582    ACPI_DMTABLE_INFO       *InfoTable;
2583    ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
2584    ACPI_NFIT_SMBIOS        *SmbiosInfo = NULL;
2585    ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
2586    UINT32                  i;
2587
2588
2589    /* Main table */
2590
2591    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoNfit);
2592    if (ACPI_FAILURE (Status))
2593    {
2594        return;
2595    }
2596
2597    /* Subtables */
2598
2599    SubTable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset);
2600    while (Offset < Table->Length)
2601    {
2602        /* NFIT subtable header */
2603
2604        AcpiOsPrintf ("\n");
2605        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2606                    SubTable->Length, AcpiDmTableInfoNfitHdr);
2607        if (ACPI_FAILURE (Status))
2608        {
2609            return;
2610        }
2611
2612        switch (SubTable->Type)
2613        {
2614        case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
2615
2616            InfoTable = AcpiDmTableInfoNfit0;
2617            break;
2618
2619        case ACPI_NFIT_TYPE_MEMORY_MAP:
2620
2621            InfoTable = AcpiDmTableInfoNfit1;
2622            break;
2623
2624        case ACPI_NFIT_TYPE_INTERLEAVE:
2625
2626            /* Has a variable number of 32-bit values at the end */
2627
2628            InfoTable = AcpiDmTableInfoNfit2;
2629            Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, SubTable);
2630            FieldOffset = sizeof (ACPI_NFIT_INTERLEAVE);
2631            break;
2632
2633        case ACPI_NFIT_TYPE_SMBIOS:
2634
2635            SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, SubTable);
2636            InfoTable = AcpiDmTableInfoNfit3;
2637            break;
2638
2639        case ACPI_NFIT_TYPE_CONTROL_REGION:
2640
2641            InfoTable = AcpiDmTableInfoNfit4;
2642            break;
2643
2644        case ACPI_NFIT_TYPE_DATA_REGION:
2645
2646            InfoTable = AcpiDmTableInfoNfit5;
2647            break;
2648
2649        case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2650
2651            /* Has a variable number of 64-bit addresses at the end */
2652
2653            InfoTable = AcpiDmTableInfoNfit6;
2654            Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, SubTable);
2655            FieldOffset = sizeof (ACPI_NFIT_FLUSH_ADDRESS) - sizeof (UINT64);
2656            break;
2657
2658        default:
2659            AcpiOsPrintf ("\n**** Unknown NFIT subtable type 0x%X\n", SubTable->Type);
2660
2661            /* Attempt to continue */
2662
2663            if (!SubTable->Length)
2664            {
2665                AcpiOsPrintf ("Invalid zero length subtable\n");
2666                return;
2667            }
2668            goto NextSubTable;
2669        }
2670
2671        AcpiOsPrintf ("\n");
2672        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2673                    SubTable->Length, InfoTable);
2674        if (ACPI_FAILURE (Status))
2675        {
2676            return;
2677        }
2678
2679        /* Per-subtable variable-length fields */
2680
2681        switch (SubTable->Type)
2682        {
2683        case ACPI_NFIT_TYPE_INTERLEAVE:
2684
2685            for (i = 0; i < Interleave->LineCount; i++)
2686            {
2687                Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
2688                            &Interleave->LineOffset[i],
2689                            sizeof (UINT32), AcpiDmTableInfoNfit2a);
2690                FieldOffset += sizeof (UINT32);
2691            }
2692            break;
2693
2694        case ACPI_NFIT_TYPE_SMBIOS:
2695
2696            Length = SubTable->Length - sizeof (ACPI_NFIT_SMBIOS) + sizeof (UINT8);
2697            if (Length)
2698            {
2699                Status = AcpiDmDumpTable (Table->Length,
2700                            sizeof (ACPI_NFIT_SMBIOS) - sizeof (UINT8),
2701                            SmbiosInfo,
2702                            Length, AcpiDmTableInfoNfit3a);
2703                if (ACPI_FAILURE (Status))
2704                {
2705                    return;
2706                }
2707            }
2708
2709            break;
2710
2711        case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2712
2713            for (i = 0; i < Hint->HintCount; i++)
2714            {
2715                Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
2716                            &Hint->HintAddress[i],
2717                            sizeof (UINT64), AcpiDmTableInfoNfit6a);
2718                FieldOffset += sizeof (UINT64);
2719            }
2720            break;
2721
2722        default:
2723            break;
2724        }
2725
2726NextSubTable:
2727        /* Point to next subtable */
2728
2729        Offset += SubTable->Length;
2730        SubTable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, SubTable, SubTable->Length);
2731    }
2732}
2733
2734
2735/*******************************************************************************
2736 *
2737 * FUNCTION:    AcpiDmDumpPcct
2738 *
2739 * PARAMETERS:  Table               - A PCCT table
2740 *
2741 * RETURN:      None
2742 *
2743 * DESCRIPTION: Format the contents of a PCCT. This table type consists
2744 *              of an open-ended number of subtables.
2745 *
2746 ******************************************************************************/
2747
2748void
2749AcpiDmDumpPcct (
2750    ACPI_TABLE_HEADER       *Table)
2751{
2752    ACPI_STATUS             Status;
2753    ACPI_PCCT_SUBSPACE      *SubTable;
2754    ACPI_DMTABLE_INFO       *InfoTable;
2755    UINT32                  Length = Table->Length;
2756    UINT32                  Offset = sizeof (ACPI_TABLE_PCCT);
2757
2758
2759    /* Main table */
2760
2761    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct);
2762    if (ACPI_FAILURE (Status))
2763    {
2764        return;
2765    }
2766
2767    /* Subtables */
2768
2769    SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
2770    while (Offset < Table->Length)
2771    {
2772        /* Common subtable header */
2773
2774        AcpiOsPrintf ("\n");
2775        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2776                    SubTable->Header.Length, AcpiDmTableInfoPcctHdr);
2777        if (ACPI_FAILURE (Status))
2778        {
2779            return;
2780        }
2781
2782        switch (SubTable->Header.Type)
2783        {
2784        case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
2785
2786            InfoTable = AcpiDmTableInfoPcct0;
2787            break;
2788
2789        case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
2790
2791            InfoTable = AcpiDmTableInfoPcct1;
2792            break;
2793
2794        default:
2795
2796            AcpiOsPrintf (
2797                "\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n",
2798                SubTable->Header.Type);
2799            return;
2800        }
2801
2802        AcpiOsPrintf ("\n");
2803        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2804                    SubTable->Header.Length, InfoTable);
2805        if (ACPI_FAILURE (Status))
2806        {
2807            return;
2808        }
2809
2810        /* Point to next subtable */
2811
2812        Offset += SubTable->Header.Length;
2813        SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, SubTable,
2814                    SubTable->Header.Length);
2815    }
2816}
2817
2818
2819/*******************************************************************************
2820 *
2821 * FUNCTION:    AcpiDmDumpPmtt
2822 *
2823 * PARAMETERS:  Table               - A PMTT table
2824 *
2825 * RETURN:      None
2826 *
2827 * DESCRIPTION: Format the contents of a PMTT. This table type consists
2828 *              of an open-ended number of subtables.
2829 *
2830 ******************************************************************************/
2831
2832void
2833AcpiDmDumpPmtt (
2834    ACPI_TABLE_HEADER       *Table)
2835{
2836    ACPI_STATUS             Status;
2837    ACPI_PMTT_HEADER        *SubTable;
2838    ACPI_PMTT_HEADER        *MemSubTable;
2839    ACPI_PMTT_HEADER        *DimmSubTable;
2840    ACPI_PMTT_DOMAIN        *DomainArray;
2841    UINT32                  Length = Table->Length;
2842    UINT32                  Offset = sizeof (ACPI_TABLE_PMTT);
2843    UINT32                  MemOffset;
2844    UINT32                  DimmOffset;
2845    UINT32                  DomainOffset;
2846    UINT32                  DomainCount;
2847
2848
2849    /* Main table */
2850
2851    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt);
2852    if (ACPI_FAILURE (Status))
2853    {
2854        return;
2855    }
2856
2857    /* Subtables */
2858
2859    SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
2860    while (Offset < Table->Length)
2861    {
2862        /* Common subtable header */
2863
2864        AcpiOsPrintf ("\n");
2865        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2866                    SubTable->Length, AcpiDmTableInfoPmttHdr);
2867        if (ACPI_FAILURE (Status))
2868        {
2869            return;
2870        }
2871
2872        /* Only Socket subtables are expected at this level */
2873
2874        if (SubTable->Type != ACPI_PMTT_TYPE_SOCKET)
2875        {
2876            AcpiOsPrintf (
2877                "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
2878                SubTable->Type);
2879            return;
2880        }
2881
2882        /* Dump the fixed-length portion of the subtable */
2883
2884        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2885                    SubTable->Length, AcpiDmTableInfoPmtt0);
2886        if (ACPI_FAILURE (Status))
2887        {
2888            return;
2889        }
2890
2891        /* Walk the memory controller subtables */
2892
2893        MemOffset = sizeof (ACPI_PMTT_SOCKET);
2894        MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, SubTable,
2895            sizeof (ACPI_PMTT_SOCKET));
2896
2897        while (((Offset + MemOffset) < Table->Length) &&
2898            (MemOffset < SubTable->Length))
2899        {
2900            /* Common subtable header */
2901
2902            AcpiOsPrintf ("\n");
2903            Status = AcpiDmDumpTable (Length,
2904                        Offset + MemOffset, MemSubTable,
2905                        MemSubTable->Length, AcpiDmTableInfoPmttHdr);
2906            if (ACPI_FAILURE (Status))
2907            {
2908                return;
2909            }
2910
2911            /* Only memory controller subtables are expected at this level */
2912
2913            if (MemSubTable->Type != ACPI_PMTT_TYPE_CONTROLLER)
2914            {
2915                AcpiOsPrintf (
2916                    "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
2917                    MemSubTable->Type);
2918                return;
2919            }
2920
2921            /* Dump the fixed-length portion of the controller subtable */
2922
2923            Status = AcpiDmDumpTable (Length,
2924                        Offset + MemOffset, MemSubTable,
2925                        MemSubTable->Length, AcpiDmTableInfoPmtt1);
2926            if (ACPI_FAILURE (Status))
2927            {
2928                return;
2929            }
2930
2931            /* Walk the variable count of proximity domains */
2932
2933            DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubTable)->DomainCount;
2934            DomainOffset = sizeof (ACPI_PMTT_CONTROLLER);
2935            DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubTable,
2936                sizeof (ACPI_PMTT_CONTROLLER));
2937
2938            while (((Offset + MemOffset + DomainOffset) < Table->Length) &&
2939                ((MemOffset + DomainOffset) < SubTable->Length) &&
2940                DomainCount)
2941            {
2942                Status = AcpiDmDumpTable (Length,
2943                            Offset + MemOffset + DomainOffset, DomainArray,
2944                            sizeof (ACPI_PMTT_DOMAIN), AcpiDmTableInfoPmtt1a);
2945                if (ACPI_FAILURE (Status))
2946                {
2947                    return;
2948                }
2949
2950                DomainOffset += sizeof (ACPI_PMTT_DOMAIN);
2951                DomainArray++;
2952                DomainCount--;
2953            }
2954
2955            if (DomainCount)
2956            {
2957                AcpiOsPrintf (
2958                    "\n**** DomainCount exceeds subtable length\n\n");
2959            }
2960
2961            /* Walk the physical component (DIMM) subtables */
2962
2963            DimmOffset = DomainOffset;
2964            DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubTable,
2965                DomainOffset);
2966
2967            while (((Offset + MemOffset + DimmOffset) < Table->Length) &&
2968                (DimmOffset < MemSubTable->Length))
2969            {
2970                /* Common subtable header */
2971
2972                AcpiOsPrintf ("\n");
2973                Status = AcpiDmDumpTable (Length,
2974                            Offset + MemOffset + DimmOffset, DimmSubTable,
2975                            DimmSubTable->Length, AcpiDmTableInfoPmttHdr);
2976                if (ACPI_FAILURE (Status))
2977                {
2978                    return;
2979                }
2980
2981                /* Only DIMM subtables are expected at this level */
2982
2983                if (DimmSubTable->Type != ACPI_PMTT_TYPE_DIMM)
2984                {
2985                    AcpiOsPrintf (
2986                        "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
2987                        DimmSubTable->Type);
2988                    return;
2989                }
2990
2991                /* Dump the fixed-length DIMM subtable */
2992
2993                Status = AcpiDmDumpTable (Length,
2994                            Offset + MemOffset + DimmOffset, DimmSubTable,
2995                            DimmSubTable->Length, AcpiDmTableInfoPmtt2);
2996                if (ACPI_FAILURE (Status))
2997                {
2998                    return;
2999                }
3000
3001                /* Point to next DIMM subtable */
3002
3003                DimmOffset += DimmSubTable->Length;
3004                DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
3005                    DimmSubTable, DimmSubTable->Length);
3006            }
3007
3008            /* Point to next Controller subtable */
3009
3010            MemOffset += MemSubTable->Length;
3011            MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
3012                MemSubTable, MemSubTable->Length);
3013        }
3014
3015        /* Point to next Socket subtable */
3016
3017        Offset += SubTable->Length;
3018        SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
3019            SubTable, SubTable->Length);
3020    }
3021}
3022
3023
3024/*******************************************************************************
3025 *
3026 * FUNCTION:    AcpiDmDumpS3pt
3027 *
3028 * PARAMETERS:  Table               - A S3PT table
3029 *
3030 * RETURN:      Length of the table
3031 *
3032 * DESCRIPTION: Format the contents of a S3PT
3033 *
3034 ******************************************************************************/
3035
3036UINT32
3037AcpiDmDumpS3pt (
3038    ACPI_TABLE_HEADER       *Tables)
3039{
3040    ACPI_STATUS             Status;
3041    UINT32                  Offset = sizeof (ACPI_TABLE_S3PT);
3042    ACPI_S3PT_HEADER        *SubTable;
3043    ACPI_DMTABLE_INFO       *InfoTable;
3044    ACPI_TABLE_S3PT         *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
3045
3046
3047    /* Main table */
3048
3049    Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt);
3050    if (ACPI_FAILURE (Status))
3051    {
3052        return 0;
3053    }
3054
3055    SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, S3ptTable, Offset);
3056    while (Offset < S3ptTable->Length)
3057    {
3058        /* Common subtable header */
3059
3060        AcpiOsPrintf ("\n");
3061        Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
3062                    SubTable->Length, AcpiDmTableInfoS3ptHdr);
3063        if (ACPI_FAILURE (Status))
3064        {
3065            return 0;
3066        }
3067
3068        switch (SubTable->Type)
3069        {
3070        case ACPI_S3PT_TYPE_RESUME:
3071
3072            InfoTable = AcpiDmTableInfoS3pt0;
3073            break;
3074
3075        case ACPI_S3PT_TYPE_SUSPEND:
3076
3077            InfoTable = AcpiDmTableInfoS3pt1;
3078            break;
3079
3080        default:
3081
3082            AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n", SubTable->Type);
3083
3084            /* Attempt to continue */
3085
3086            if (!SubTable->Length)
3087            {
3088                AcpiOsPrintf ("Invalid zero length subtable\n");
3089                return 0;
3090            }
3091            goto NextSubTable;
3092        }
3093
3094        AcpiOsPrintf ("\n");
3095        Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
3096                    SubTable->Length, InfoTable);
3097        if (ACPI_FAILURE (Status))
3098        {
3099            return 0;
3100        }
3101
3102NextSubTable:
3103        /* Point to next subtable */
3104
3105        Offset += SubTable->Length;
3106        SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, SubTable, SubTable->Length);
3107    }
3108
3109    return (S3ptTable->Length);
3110}
3111
3112
3113/*******************************************************************************
3114 *
3115 * FUNCTION:    AcpiDmDumpSlic
3116 *
3117 * PARAMETERS:  Table               - A SLIC table
3118 *
3119 * RETURN:      None
3120 *
3121 * DESCRIPTION: Format the contents of a SLIC
3122 *
3123 ******************************************************************************/
3124
3125void
3126AcpiDmDumpSlic (
3127    ACPI_TABLE_HEADER       *Table)
3128{
3129    AcpiDmDumpTable (Table->Length, sizeof (ACPI_TABLE_HEADER), Table,
3130                Table->Length - sizeof (*Table), AcpiDmTableInfoSlic);
3131}
3132
3133
3134/*******************************************************************************
3135 *
3136 * FUNCTION:    AcpiDmDumpSlit
3137 *
3138 * PARAMETERS:  Table               - An SLIT
3139 *
3140 * RETURN:      None
3141 *
3142 * DESCRIPTION: Format the contents of a SLIT
3143 *
3144 ******************************************************************************/
3145
3146void
3147AcpiDmDumpSlit (
3148    ACPI_TABLE_HEADER       *Table)
3149{
3150    ACPI_STATUS             Status;
3151    UINT32                  Offset;
3152    UINT8                   *Row;
3153    UINT32                  Localities;
3154    UINT32                  i;
3155    UINT32                  j;
3156
3157
3158    /* Main table */
3159
3160    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSlit);
3161    if (ACPI_FAILURE (Status))
3162    {
3163        return;
3164    }
3165
3166    /* Display the Locality NxN Matrix */
3167
3168    Localities = (UINT32) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->LocalityCount;
3169    Offset = ACPI_OFFSET (ACPI_TABLE_SLIT, Entry[0]);
3170    Row = (UINT8 *) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->Entry;
3171
3172    for (i = 0; i < Localities; i++)
3173    {
3174        /* Display one row of the matrix */
3175
3176        AcpiDmLineHeader2 (Offset, Localities, "Locality", i);
3177        for  (j = 0; j < Localities; j++)
3178        {
3179            /* Check for beyond EOT */
3180
3181            if (Offset >= Table->Length)
3182            {
3183                AcpiOsPrintf ("\n**** Not enough room in table for all localities\n");
3184                return;
3185            }
3186
3187            AcpiOsPrintf ("%2.2X", Row[j]);
3188            Offset++;
3189
3190            /* Display up to 16 bytes per output row */
3191
3192            if ((j+1) < Localities)
3193            {
3194                AcpiOsPrintf (" ");
3195
3196                if (j && (((j+1) % 16) == 0))
3197                {
3198                    AcpiOsPrintf ("\\\n"); /* With line continuation char */
3199                    AcpiDmLineHeader (Offset, 0, NULL);
3200                }
3201            }
3202        }
3203
3204        /* Point to next row */
3205
3206        AcpiOsPrintf ("\n");
3207        Row += Localities;
3208    }
3209}
3210
3211
3212/*******************************************************************************
3213 *
3214 * FUNCTION:    AcpiDmDumpSrat
3215 *
3216 * PARAMETERS:  Table               - A SRAT table
3217 *
3218 * RETURN:      None
3219 *
3220 * DESCRIPTION: Format the contents of a SRAT
3221 *
3222 ******************************************************************************/
3223
3224void
3225AcpiDmDumpSrat (
3226    ACPI_TABLE_HEADER       *Table)
3227{
3228    ACPI_STATUS             Status;
3229    UINT32                  Offset = sizeof (ACPI_TABLE_SRAT);
3230    ACPI_SUBTABLE_HEADER    *SubTable;
3231    ACPI_DMTABLE_INFO       *InfoTable;
3232
3233
3234    /* Main table */
3235
3236    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSrat);
3237    if (ACPI_FAILURE (Status))
3238    {
3239        return;
3240    }
3241
3242    /* Subtables */
3243
3244    SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
3245    while (Offset < Table->Length)
3246    {
3247        /* Common subtable header */
3248
3249        AcpiOsPrintf ("\n");
3250        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
3251                    SubTable->Length, AcpiDmTableInfoSratHdr);
3252        if (ACPI_FAILURE (Status))
3253        {
3254            return;
3255        }
3256
3257        switch (SubTable->Type)
3258        {
3259        case ACPI_SRAT_TYPE_CPU_AFFINITY:
3260
3261            InfoTable = AcpiDmTableInfoSrat0;
3262            break;
3263
3264        case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
3265
3266            InfoTable = AcpiDmTableInfoSrat1;
3267            break;
3268
3269        case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
3270
3271            InfoTable = AcpiDmTableInfoSrat2;
3272            break;
3273
3274        case ACPI_SRAT_TYPE_GICC_AFFINITY:
3275
3276            InfoTable = AcpiDmTableInfoSrat3;
3277            break;
3278
3279        default:
3280            AcpiOsPrintf ("\n**** Unknown SRAT subtable type 0x%X\n", SubTable->Type);
3281
3282            /* Attempt to continue */
3283
3284            if (!SubTable->Length)
3285            {
3286                AcpiOsPrintf ("Invalid zero length subtable\n");
3287                return;
3288            }
3289            goto NextSubTable;
3290        }
3291
3292        AcpiOsPrintf ("\n");
3293        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
3294                    SubTable->Length, InfoTable);
3295        if (ACPI_FAILURE (Status))
3296        {
3297            return;
3298        }
3299
3300NextSubTable:
3301        /* Point to next subtable */
3302
3303        Offset += SubTable->Length;
3304        SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length);
3305    }
3306}
3307
3308
3309/*******************************************************************************
3310 *
3311 * FUNCTION:    AcpiDmDumpStao
3312 *
3313 * PARAMETERS:  Table               - A STAO table
3314 *
3315 * RETURN:      None
3316 *
3317 * DESCRIPTION: Format the contents of a STAO. This is a variable-length
3318 *              table that contains an open-ended number of ASCII strings
3319 *              at the end of the table.
3320 *
3321 ******************************************************************************/
3322
3323void
3324AcpiDmDumpStao (
3325    ACPI_TABLE_HEADER       *Table)
3326{
3327    ACPI_STATUS             Status;
3328    char                    *Namepath;
3329    UINT32                  Length = Table->Length;
3330    UINT32                  StringLength;
3331    UINT32                  Offset = sizeof (ACPI_TABLE_STAO);
3332
3333
3334    /* Main table */
3335
3336    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoStao);
3337    if (ACPI_FAILURE (Status))
3338    {
3339        return;
3340    }
3341
3342    /* The rest of the table consists of Namepath strings */
3343
3344    while (Offset < Table->Length)
3345    {
3346        Namepath = ACPI_ADD_PTR (char, Table, Offset);
3347        StringLength = ACPI_STRLEN (Namepath) + 1;
3348
3349        AcpiDmLineHeader (Offset, StringLength, "Namestring");
3350        AcpiOsPrintf ("\"%s\"\n", Namepath);
3351
3352        /* Point to next namepath */
3353
3354        Offset += StringLength;
3355    }
3356}
3357
3358
3359/*******************************************************************************
3360 *
3361 * FUNCTION:    AcpiDmDumpVrtc
3362 *
3363 * PARAMETERS:  Table               - A VRTC table
3364 *
3365 * RETURN:      None
3366 *
3367 * DESCRIPTION: Format the contents of a VRTC
3368 *
3369 ******************************************************************************/
3370
3371void
3372AcpiDmDumpVrtc (
3373    ACPI_TABLE_HEADER       *Table)
3374{
3375    ACPI_STATUS             Status;
3376    UINT32                  Offset = sizeof (ACPI_TABLE_VRTC);
3377    ACPI_VRTC_ENTRY         *SubTable;
3378
3379
3380    /* Main table */
3381
3382    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoVrtc);
3383    if (ACPI_FAILURE (Status))
3384    {
3385        return;
3386    }
3387
3388    /* Subtables */
3389
3390    SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, Table, Offset);
3391    while (Offset < Table->Length)
3392    {
3393        /* Common subtable header */
3394
3395        AcpiOsPrintf ("\n");
3396        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
3397                    sizeof (ACPI_VRTC_ENTRY), AcpiDmTableInfoVrtc0);
3398        if (ACPI_FAILURE (Status))
3399        {
3400            return;
3401        }
3402
3403        /* Point to next subtable */
3404
3405        Offset += sizeof (ACPI_VRTC_ENTRY);
3406        SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, SubTable, sizeof (ACPI_VRTC_ENTRY));
3407    }
3408}
3409
3410
3411/*******************************************************************************
3412 *
3413 * FUNCTION:    AcpiDmDumpWdat
3414 *
3415 * PARAMETERS:  Table               - A WDAT table
3416 *
3417 * RETURN:      None
3418 *
3419 * DESCRIPTION: Format the contents of a WDAT
3420 *
3421 ******************************************************************************/
3422
3423void
3424AcpiDmDumpWdat (
3425    ACPI_TABLE_HEADER       *Table)
3426{
3427    ACPI_STATUS             Status;
3428    UINT32                  Offset = sizeof (ACPI_TABLE_WDAT);
3429    ACPI_WDAT_ENTRY         *SubTable;
3430
3431
3432    /* Main table */
3433
3434    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoWdat);
3435    if (ACPI_FAILURE (Status))
3436    {
3437        return;
3438    }
3439
3440    /* Subtables */
3441
3442    SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset);
3443    while (Offset < Table->Length)
3444    {
3445        /* Common subtable header */
3446
3447        AcpiOsPrintf ("\n");
3448        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
3449                    sizeof (ACPI_WDAT_ENTRY), AcpiDmTableInfoWdat0);
3450        if (ACPI_FAILURE (Status))
3451        {
3452            return;
3453        }
3454
3455        /* Point to next subtable */
3456
3457        Offset += sizeof (ACPI_WDAT_ENTRY);
3458        SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, SubTable, sizeof (ACPI_WDAT_ENTRY));
3459    }
3460}
3461
3462/*******************************************************************************
3463 *
3464 * FUNCTION:    AcpiDmDumpWpbt
3465 *
3466 * PARAMETERS:  Table               - A WPBT table
3467 *
3468 * RETURN:      None
3469 *
3470 * DESCRIPTION: Format the contents of a WPBT. This table type consists
3471 *              of an open-ended arguments buffer at the end of the table.
3472 *
3473 ******************************************************************************/
3474
3475void
3476AcpiDmDumpWpbt (
3477    ACPI_TABLE_HEADER       *Table)
3478{
3479    ACPI_STATUS             Status;
3480    ACPI_TABLE_WPBT         *SubTable;
3481    UINT32                  Length = Table->Length;
3482    UINT16                  ArgumentsLength;
3483
3484
3485    /* Dump the main table */
3486
3487    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoWpbt);
3488    if (ACPI_FAILURE (Status))
3489    {
3490        return;
3491    }
3492
3493    /* Extract the arguments buffer length from the main table */
3494
3495    SubTable = ACPI_CAST_PTR (ACPI_TABLE_WPBT, Table);
3496    ArgumentsLength = SubTable->ArgumentsLength;
3497
3498    /* Dump the arguments buffer */
3499
3500    AcpiDmDumpTable (Table->Length, 0, Table, ArgumentsLength,
3501        AcpiDmTableInfoWpbt0);
3502    if (ACPI_FAILURE (Status))
3503    {
3504        return;
3505    }
3506}
3507