dmtbdump.c revision 281687
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 *              MultiLine           - TRUE if a large, multi-line buffer
74 *
75 * RETURN:      None
76 *
77 * DESCRIPTION: Format the contents of an arbitrary length data buffer (in the
78 *              disassembler output format.)
79 *
80 ******************************************************************************/
81
82void
83AcpiDmDumpBuffer (
84    void                    *Table,
85    UINT32                  BufferOffset,
86    UINT32                  Length,
87    UINT32                  AbsoluteOffset,
88    char                    *Header,
89    BOOLEAN                 MultiLine)
90{
91    UINT8                   *Buffer;
92    UINT32                  i;
93
94
95    if (!Length)
96    {
97        return;
98    }
99
100    Buffer = ACPI_CAST_PTR (UINT8, Table) + BufferOffset;
101    i = 0;
102
103    while (i < Length)
104    {
105        if (!(i % 16))
106        {
107            if (MultiLine)
108            {
109                /* Insert a backslash - line continuation character */
110
111                AcpiOsPrintf ("\\\n    ");
112            }
113            else
114            {
115                AcpiOsPrintf ("\n");
116                AcpiDmLineHeader (AbsoluteOffset,
117                    ((Length - i) > 16) ? 16 : (Length - i), Header);
118                Header = NULL;
119            }
120        }
121
122        AcpiOsPrintf ("%.02X ", *Buffer);
123        i++;
124        Buffer++;
125        AbsoluteOffset++;
126    }
127
128    AcpiOsPrintf ("\n");
129}
130
131
132/*******************************************************************************
133 *
134 * FUNCTION:    AcpiDmDumpRsdp
135 *
136 * PARAMETERS:  Table               - A RSDP
137 *
138 * RETURN:      Length of the table (there is not always a length field,
139 *              use revision or length if available (ACPI 2.0+))
140 *
141 * DESCRIPTION: Format the contents of a RSDP
142 *
143 ******************************************************************************/
144
145UINT32
146AcpiDmDumpRsdp (
147    ACPI_TABLE_HEADER       *Table)
148{
149    ACPI_TABLE_RSDP         *Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table);
150    UINT32                  Length = sizeof (ACPI_RSDP_COMMON);
151    UINT8                   Checksum;
152
153
154    /* Dump the common ACPI 1.0 portion */
155
156    AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp1);
157
158    /* Validate the first checksum */
159
160    Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_RSDP_COMMON),
161                Rsdp->Checksum);
162    if (Checksum != Rsdp->Checksum)
163    {
164        AcpiOsPrintf ("/* Incorrect Checksum above, should be 0x%2.2X */\n",
165            Checksum);
166    }
167
168    /* The RSDP for ACPI 2.0+ contains more data and has a Length field */
169
170    if (Rsdp->Revision > 0)
171    {
172        Length = Rsdp->Length;
173        AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp2);
174
175        /* Validate the extended checksum over entire RSDP */
176
177        Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_TABLE_RSDP),
178                    Rsdp->ExtendedChecksum);
179        if (Checksum != Rsdp->ExtendedChecksum)
180        {
181            AcpiOsPrintf (
182                "/* Incorrect Extended Checksum above, should be 0x%2.2X */\n",
183                Checksum);
184        }
185    }
186
187    return (Length);
188}
189
190
191/*******************************************************************************
192 *
193 * FUNCTION:    AcpiDmDumpRsdt
194 *
195 * PARAMETERS:  Table               - A RSDT
196 *
197 * RETURN:      None
198 *
199 * DESCRIPTION: Format the contents of a RSDT
200 *
201 ******************************************************************************/
202
203void
204AcpiDmDumpRsdt (
205    ACPI_TABLE_HEADER       *Table)
206{
207    UINT32                  *Array;
208    UINT32                  Entries;
209    UINT32                  Offset;
210    UINT32                  i;
211
212
213    /* Point to start of table pointer array */
214
215    Array = ACPI_CAST_PTR (ACPI_TABLE_RSDT, Table)->TableOffsetEntry;
216    Offset = sizeof (ACPI_TABLE_HEADER);
217
218    /* RSDT uses 32-bit pointers */
219
220    Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT32);
221
222    for (i = 0; i < Entries; i++)
223    {
224        AcpiDmLineHeader2 (Offset, sizeof (UINT32), "ACPI Table Address", i);
225        AcpiOsPrintf ("%8.8X\n", Array[i]);
226        Offset += sizeof (UINT32);
227    }
228}
229
230
231/*******************************************************************************
232 *
233 * FUNCTION:    AcpiDmDumpXsdt
234 *
235 * PARAMETERS:  Table               - A XSDT
236 *
237 * RETURN:      None
238 *
239 * DESCRIPTION: Format the contents of a XSDT
240 *
241 ******************************************************************************/
242
243void
244AcpiDmDumpXsdt (
245    ACPI_TABLE_HEADER       *Table)
246{
247    UINT64                  *Array;
248    UINT32                  Entries;
249    UINT32                  Offset;
250    UINT32                  i;
251
252
253    /* Point to start of table pointer array */
254
255    Array = ACPI_CAST_PTR (ACPI_TABLE_XSDT, Table)->TableOffsetEntry;
256    Offset = sizeof (ACPI_TABLE_HEADER);
257
258    /* XSDT uses 64-bit pointers */
259
260    Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT64);
261
262    for (i = 0; i < Entries; i++)
263    {
264        AcpiDmLineHeader2 (Offset, sizeof (UINT64), "ACPI Table Address", i);
265        AcpiOsPrintf ("%8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Array[i]));
266        Offset += sizeof (UINT64);
267    }
268}
269
270
271/*******************************************************************************
272 *
273 * FUNCTION:    AcpiDmDumpFadt
274 *
275 * PARAMETERS:  Table               - A FADT
276 *
277 * RETURN:      None
278 *
279 * DESCRIPTION: Format the contents of a FADT
280 *
281 * NOTE:        We cannot depend on the FADT version to indicate the actual
282 *              contents of the FADT because of BIOS bugs. The table length
283 *              is the only reliable indicator.
284 *
285 ******************************************************************************/
286
287void
288AcpiDmDumpFadt (
289    ACPI_TABLE_HEADER       *Table)
290{
291
292    /* Always dump the minimum FADT revision 1 fields (ACPI 1.0) */
293
294    AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt1);
295
296    /* Check for FADT revision 2 fields (ACPI 1.0B MS extensions) */
297
298    if ((Table->Length > ACPI_FADT_V1_SIZE) &&
299        (Table->Length <= ACPI_FADT_V2_SIZE))
300    {
301        AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt2);
302    }
303
304    /* Check for FADT revision 3/4 fields and up (ACPI 2.0+ extended data) */
305
306    else if (Table->Length > ACPI_FADT_V2_SIZE)
307    {
308        AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt3);
309
310        /* Check for FADT revision 5 fields and up (ACPI 5.0+) */
311
312        if (Table->Length > ACPI_FADT_V3_SIZE)
313        {
314            AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt5);
315        }
316    }
317
318    /* Validate various fields in the FADT, including length */
319
320    AcpiTbCreateLocalFadt (Table, Table->Length);
321
322    /* Validate FADT length against the revision */
323
324    AcpiDmValidateFadtLength (Table->Revision, Table->Length);
325}
326
327
328/*******************************************************************************
329 *
330 * FUNCTION:    AcpiDmValidateFadtLength
331 *
332 * PARAMETERS:  Revision            - FADT revision (Header->Revision)
333 *              Length              - FADT length (Header->Length
334 *
335 * RETURN:      None
336 *
337 * DESCRIPTION: Check the FADT revision against the expected table length for
338 *              that revision. Issue a warning if the length is not what was
339 *              expected. This seems to be such a common BIOS bug that the
340 *              FADT revision has been rendered virtually meaningless.
341 *
342 ******************************************************************************/
343
344static void
345AcpiDmValidateFadtLength (
346    UINT32                  Revision,
347    UINT32                  Length)
348{
349    UINT32                  ExpectedLength;
350
351
352    switch (Revision)
353    {
354    case 0:
355
356        AcpiOsPrintf ("// ACPI Warning: Invalid FADT revision: 0\n");
357        return;
358
359    case 1:
360
361        ExpectedLength = ACPI_FADT_V1_SIZE;
362        break;
363
364    case 2:
365
366        ExpectedLength = ACPI_FADT_V2_SIZE;
367        break;
368
369    case 3:
370    case 4:
371
372        ExpectedLength = ACPI_FADT_V3_SIZE;
373        break;
374
375    case 5:
376
377        ExpectedLength = ACPI_FADT_V5_SIZE;
378        break;
379
380    default:
381
382        return;
383    }
384
385    if (Length == ExpectedLength)
386    {
387        return;
388    }
389
390    AcpiOsPrintf (
391        "\n// ACPI Warning: FADT revision %X does not match length: found %X expected %X\n",
392        Revision, Length, ExpectedLength);
393}
394
395
396/*******************************************************************************
397 *
398 * FUNCTION:    AcpiDmDumpAsf
399 *
400 * PARAMETERS:  Table               - A ASF table
401 *
402 * RETURN:      None
403 *
404 * DESCRIPTION: Format the contents of a ASF table
405 *
406 ******************************************************************************/
407
408void
409AcpiDmDumpAsf (
410    ACPI_TABLE_HEADER       *Table)
411{
412    ACPI_STATUS             Status;
413    UINT32                  Offset = sizeof (ACPI_TABLE_HEADER);
414    ACPI_ASF_INFO           *SubTable;
415    ACPI_DMTABLE_INFO       *InfoTable;
416    ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
417    UINT8                   *DataTable = NULL;
418    UINT32                  DataCount = 0;
419    UINT32                  DataLength = 0;
420    UINT32                  DataOffset = 0;
421    UINT32                  i;
422    UINT8                   Type;
423
424
425    /* No main table, only subtables */
426
427    SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
428    while (Offset < Table->Length)
429    {
430        /* Common subtable header */
431
432        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
433                    SubTable->Header.Length, AcpiDmTableInfoAsfHdr);
434        if (ACPI_FAILURE (Status))
435        {
436            return;
437        }
438
439        /* The actual type is the lower 7 bits of Type */
440
441        Type = (UINT8) (SubTable->Header.Type & 0x7F);
442
443        switch (Type)
444        {
445        case ACPI_ASF_TYPE_INFO:
446
447            InfoTable = AcpiDmTableInfoAsf0;
448            break;
449
450        case ACPI_ASF_TYPE_ALERT:
451
452            InfoTable = AcpiDmTableInfoAsf1;
453            DataInfoTable = AcpiDmTableInfoAsf1a;
454            DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ALERT));
455            DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->Alerts;
456            DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->DataLength;
457            DataOffset = Offset + sizeof (ACPI_ASF_ALERT);
458            break;
459
460        case ACPI_ASF_TYPE_CONTROL:
461
462            InfoTable = AcpiDmTableInfoAsf2;
463            DataInfoTable = AcpiDmTableInfoAsf2a;
464            DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_REMOTE));
465            DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->Controls;
466            DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->DataLength;
467            DataOffset = Offset + sizeof (ACPI_ASF_REMOTE);
468            break;
469
470        case ACPI_ASF_TYPE_BOOT:
471
472            InfoTable = AcpiDmTableInfoAsf3;
473            break;
474
475        case ACPI_ASF_TYPE_ADDRESS:
476
477            InfoTable = AcpiDmTableInfoAsf4;
478            DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ADDRESS));
479            DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, SubTable)->Devices;
480            DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS);
481            break;
482
483        default:
484
485            AcpiOsPrintf ("\n**** Unknown ASF subtable type 0x%X\n", SubTable->Header.Type);
486            return;
487        }
488
489        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
490                    SubTable->Header.Length, InfoTable);
491        if (ACPI_FAILURE (Status))
492        {
493            return;
494        }
495
496        /* Dump variable-length extra data */
497
498        switch (Type)
499        {
500        case ACPI_ASF_TYPE_ALERT:
501        case ACPI_ASF_TYPE_CONTROL:
502
503            for (i = 0; i < DataCount; i++)
504            {
505                AcpiOsPrintf ("\n");
506                Status = AcpiDmDumpTable (Table->Length, DataOffset,
507                            DataTable, DataLength, DataInfoTable);
508                if (ACPI_FAILURE (Status))
509                {
510                    return;
511                }
512
513                DataTable = ACPI_ADD_PTR (UINT8, DataTable, DataLength);
514                DataOffset += DataLength;
515            }
516            break;
517
518        case ACPI_ASF_TYPE_ADDRESS:
519
520            for (i = 0; i < DataLength; i++)
521            {
522                if (!(i % 16))
523                {
524                    AcpiDmLineHeader (DataOffset, 1, "Addresses");
525                }
526
527                AcpiOsPrintf ("%2.2X ", *DataTable);
528                DataTable++;
529                DataOffset++;
530                if (DataOffset > Table->Length)
531                {
532                    AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure! (ASF! table)\n");
533                    return;
534                }
535            }
536
537            AcpiOsPrintf ("\n");
538            break;
539
540        default:
541
542            break;
543        }
544
545        AcpiOsPrintf ("\n");
546
547        /* Point to next subtable */
548
549        if (!SubTable->Header.Length)
550        {
551            AcpiOsPrintf ("Invalid zero subtable header length\n");
552            return;
553        }
554
555        Offset += SubTable->Header.Length;
556        SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, SubTable, SubTable->Header.Length);
557    }
558}
559
560
561/*******************************************************************************
562 *
563 * FUNCTION:    AcpiDmDumpCpep
564 *
565 * PARAMETERS:  Table               - A CPEP table
566 *
567 * RETURN:      None
568 *
569 * DESCRIPTION: Format the contents of a CPEP. This table type consists
570 *              of an open-ended number of subtables.
571 *
572 ******************************************************************************/
573
574void
575AcpiDmDumpCpep (
576    ACPI_TABLE_HEADER       *Table)
577{
578    ACPI_STATUS             Status;
579    ACPI_CPEP_POLLING       *SubTable;
580    UINT32                  Length = Table->Length;
581    UINT32                  Offset = sizeof (ACPI_TABLE_CPEP);
582
583
584    /* Main table */
585
586    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoCpep);
587    if (ACPI_FAILURE (Status))
588    {
589        return;
590    }
591
592    /* Subtables */
593
594    SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
595    while (Offset < Table->Length)
596    {
597        AcpiOsPrintf ("\n");
598        Status = AcpiDmDumpTable (Length, Offset, SubTable,
599                    SubTable->Header.Length, AcpiDmTableInfoCpep0);
600        if (ACPI_FAILURE (Status))
601        {
602            return;
603        }
604
605        /* Point to next subtable */
606
607        Offset += SubTable->Header.Length;
608        SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, SubTable,
609                    SubTable->Header.Length);
610    }
611}
612
613
614/*******************************************************************************
615 *
616 * FUNCTION:    AcpiDmDumpCsrt
617 *
618 * PARAMETERS:  Table               - A CSRT table
619 *
620 * RETURN:      None
621 *
622 * DESCRIPTION: Format the contents of a CSRT. This table type consists
623 *              of an open-ended number of subtables.
624 *
625 ******************************************************************************/
626
627void
628AcpiDmDumpCsrt (
629    ACPI_TABLE_HEADER       *Table)
630{
631    ACPI_STATUS             Status;
632    ACPI_CSRT_GROUP         *SubTable;
633    ACPI_CSRT_SHARED_INFO   *SharedInfoTable;
634    ACPI_CSRT_DESCRIPTOR    *SubSubTable;
635    UINT32                  Length = Table->Length;
636    UINT32                  Offset = sizeof (ACPI_TABLE_CSRT);
637    UINT32                  SubOffset;
638    UINT32                  SubSubOffset;
639    UINT32                  InfoLength;
640
641
642    /* The main table only contains the ACPI header, thus already handled */
643
644    /* Subtables (Resource Groups) */
645
646    SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset);
647    while (Offset < Table->Length)
648    {
649        /* Resource group subtable */
650
651        AcpiOsPrintf ("\n");
652        Status = AcpiDmDumpTable (Length, Offset, SubTable,
653                    SubTable->Length, AcpiDmTableInfoCsrt0);
654        if (ACPI_FAILURE (Status))
655        {
656            return;
657        }
658
659        /* Shared info subtable (One per resource group) */
660
661        SubOffset = sizeof (ACPI_CSRT_GROUP);
662        SharedInfoTable = ACPI_ADD_PTR (ACPI_CSRT_SHARED_INFO, Table,
663            Offset + SubOffset);
664
665        AcpiOsPrintf ("\n");
666        Status = AcpiDmDumpTable (Length, Offset + SubOffset, SharedInfoTable,
667                    sizeof (ACPI_CSRT_SHARED_INFO), AcpiDmTableInfoCsrt1);
668        if (ACPI_FAILURE (Status))
669        {
670            return;
671        }
672
673        SubOffset += SubTable->SharedInfoLength;
674
675        /* Sub-Subtables (Resource Descriptors) */
676
677        SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table,
678            Offset + SubOffset);
679
680        while ((SubOffset < SubTable->Length) &&
681              ((Offset + SubOffset) < Table->Length))
682        {
683            AcpiOsPrintf ("\n");
684            Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubTable,
685                        SubSubTable->Length, AcpiDmTableInfoCsrt2);
686            if (ACPI_FAILURE (Status))
687            {
688                return;
689            }
690
691            SubSubOffset = sizeof (ACPI_CSRT_DESCRIPTOR);
692
693            /* Resource-specific info buffer */
694
695            InfoLength = SubSubTable->Length - SubSubOffset;
696
697            AcpiDmDumpBuffer (SubSubTable, SubSubOffset, InfoLength,
698                Offset + SubOffset + SubSubOffset, "ResourceInfo", FALSE);
699            SubSubOffset += InfoLength;
700
701            /* Point to next sub-subtable */
702
703            SubOffset += SubSubTable->Length;
704            SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubTable,
705                        SubSubTable->Length);
706        }
707
708        /* Point to next subtable */
709
710        Offset += SubTable->Length;
711        SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, SubTable,
712                    SubTable->Length);
713    }
714}
715
716
717/*******************************************************************************
718 *
719 * FUNCTION:    AcpiDmDumpDbg2
720 *
721 * PARAMETERS:  Table               - A DBG2 table
722 *
723 * RETURN:      None
724 *
725 * DESCRIPTION: Format the contents of a DBG2. This table type consists
726 *              of an open-ended number of subtables.
727 *
728 ******************************************************************************/
729
730void
731AcpiDmDumpDbg2 (
732    ACPI_TABLE_HEADER       *Table)
733{
734    ACPI_STATUS             Status;
735    ACPI_DBG2_DEVICE        *SubTable;
736    UINT32                  Length = Table->Length;
737    UINT32                  Offset = sizeof (ACPI_TABLE_DBG2);
738    UINT32                  i;
739    UINT32                  ArrayOffset;
740    UINT32                  AbsoluteOffset;
741    UINT8                   *Array;
742
743
744    /* Main table */
745
746    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDbg2);
747    if (ACPI_FAILURE (Status))
748    {
749        return;
750    }
751
752    /* Subtables */
753
754    SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
755    while (Offset < Table->Length)
756    {
757        AcpiOsPrintf ("\n");
758        Status = AcpiDmDumpTable (Length, Offset, SubTable,
759                    SubTable->Length, AcpiDmTableInfoDbg2Device);
760        if (ACPI_FAILURE (Status))
761        {
762            return;
763        }
764
765        /* Dump the BaseAddress array */
766
767        for (i = 0; i < SubTable->RegisterCount; i++)
768        {
769            ArrayOffset = SubTable->BaseAddressOffset +
770                (sizeof (ACPI_GENERIC_ADDRESS) * i);
771            AbsoluteOffset = Offset + ArrayOffset;
772            Array = (UINT8 *) SubTable + ArrayOffset;
773
774            Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
775                        SubTable->Length, AcpiDmTableInfoDbg2Addr);
776            if (ACPI_FAILURE (Status))
777            {
778                return;
779            }
780        }
781
782        /* Dump the AddressSize array */
783
784        for (i = 0; i < SubTable->RegisterCount; i++)
785        {
786            ArrayOffset = SubTable->AddressSizeOffset +
787                (sizeof (UINT32) * i);
788            AbsoluteOffset = Offset + ArrayOffset;
789            Array = (UINT8 *) SubTable + ArrayOffset;
790
791            Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
792                        SubTable->Length, AcpiDmTableInfoDbg2Size);
793            if (ACPI_FAILURE (Status))
794            {
795                return;
796            }
797        }
798
799        /* Dump the Namestring (required) */
800
801        AcpiOsPrintf ("\n");
802        ArrayOffset = SubTable->NamepathOffset;
803        AbsoluteOffset = Offset + ArrayOffset;
804        Array = (UINT8 *) SubTable + ArrayOffset;
805
806        Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
807                    SubTable->Length, AcpiDmTableInfoDbg2Name);
808        if (ACPI_FAILURE (Status))
809        {
810            return;
811        }
812
813        /* Dump the OemData (optional) */
814
815        if (SubTable->OemDataOffset)
816        {
817            AcpiDmDumpBuffer (SubTable, SubTable->OemDataOffset, SubTable->OemDataLength,
818                Offset + SubTable->OemDataOffset, "OEM Data", FALSE);
819        }
820
821        /* Point to next subtable */
822
823        Offset += SubTable->Length;
824        SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, SubTable,
825                    SubTable->Length);
826    }
827}
828
829
830/*******************************************************************************
831 *
832 * FUNCTION:    AcpiDmDumpDmar
833 *
834 * PARAMETERS:  Table               - A DMAR table
835 *
836 * RETURN:      None
837 *
838 * DESCRIPTION: Format the contents of a DMAR. This table type consists
839 *              of an open-ended number of subtables.
840 *
841 ******************************************************************************/
842
843
844void
845AcpiDmDumpDmar (
846    ACPI_TABLE_HEADER       *Table)
847{
848    ACPI_STATUS             Status;
849    ACPI_DMAR_HEADER        *SubTable;
850    UINT32                  Length = Table->Length;
851    UINT32                  Offset = sizeof (ACPI_TABLE_DMAR);
852    ACPI_DMTABLE_INFO       *InfoTable;
853    ACPI_DMAR_DEVICE_SCOPE  *ScopeTable;
854    UINT32                  ScopeOffset;
855    UINT8                   *PciPath;
856    UINT32                  PathOffset;
857
858
859    /* Main table */
860
861    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar);
862    if (ACPI_FAILURE (Status))
863    {
864        return;
865    }
866
867    /* Subtables */
868
869    SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
870    while (Offset < Table->Length)
871    {
872        /* Common subtable header */
873
874        AcpiOsPrintf ("\n");
875        Status = AcpiDmDumpTable (Length, Offset, SubTable,
876                    SubTable->Length, AcpiDmTableInfoDmarHdr);
877        if (ACPI_FAILURE (Status))
878        {
879            return;
880        }
881        AcpiOsPrintf ("\n");
882
883        switch (SubTable->Type)
884        {
885        case ACPI_DMAR_TYPE_HARDWARE_UNIT:
886
887            InfoTable = AcpiDmTableInfoDmar0;
888            ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT);
889            break;
890
891        case ACPI_DMAR_TYPE_RESERVED_MEMORY:
892
893            InfoTable = AcpiDmTableInfoDmar1;
894            ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY);
895            break;
896
897        case ACPI_DMAR_TYPE_ROOT_ATS:
898
899            InfoTable = AcpiDmTableInfoDmar2;
900            ScopeOffset = sizeof (ACPI_DMAR_ATSR);
901            break;
902
903        case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
904
905            InfoTable = AcpiDmTableInfoDmar3;
906            ScopeOffset = sizeof (ACPI_DMAR_RHSA);
907            break;
908
909        case ACPI_DMAR_TYPE_NAMESPACE:
910
911            InfoTable = AcpiDmTableInfoDmar4;
912            ScopeOffset = sizeof (ACPI_DMAR_ANDD);
913            break;
914
915        default:
916
917            AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n", SubTable->Type);
918            return;
919        }
920
921        Status = AcpiDmDumpTable (Length, Offset, SubTable,
922                    SubTable->Length, InfoTable);
923        if (ACPI_FAILURE (Status))
924        {
925            return;
926        }
927
928        /*
929         * Dump the optional device scope entries
930         */
931        if ((SubTable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
932            (SubTable->Type == ACPI_DMAR_TYPE_NAMESPACE))
933        {
934            /* These types do not support device scopes */
935
936            goto NextSubtable;
937        }
938
939        ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, SubTable, ScopeOffset);
940        while (ScopeOffset < SubTable->Length)
941        {
942            AcpiOsPrintf ("\n");
943            Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
944                        ScopeTable->Length, AcpiDmTableInfoDmarScope);
945            if (ACPI_FAILURE (Status))
946            {
947                return;
948            }
949            AcpiOsPrintf ("\n");
950
951            /* Dump the PCI Path entries for this device scope */
952
953            PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */
954
955            PciPath = ACPI_ADD_PTR (UINT8, ScopeTable,
956                sizeof (ACPI_DMAR_DEVICE_SCOPE));
957
958            while (PathOffset < ScopeTable->Length)
959            {
960                AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2, "PCI Path");
961                AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]);
962
963                /* Point to next PCI Path entry */
964
965                PathOffset += 2;
966                PciPath += 2;
967                AcpiOsPrintf ("\n");
968            }
969
970            /* Point to next device scope entry */
971
972            ScopeOffset += ScopeTable->Length;
973            ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE,
974                ScopeTable, ScopeTable->Length);
975        }
976
977NextSubtable:
978        /* Point to next subtable */
979
980        Offset += SubTable->Length;
981        SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, SubTable, SubTable->Length);
982    }
983}
984
985
986/*******************************************************************************
987 *
988 * FUNCTION:    AcpiDmDumpEinj
989 *
990 * PARAMETERS:  Table               - A EINJ table
991 *
992 * RETURN:      None
993 *
994 * DESCRIPTION: Format the contents of a EINJ. This table type consists
995 *              of an open-ended number of subtables.
996 *
997 ******************************************************************************/
998
999void
1000AcpiDmDumpEinj (
1001    ACPI_TABLE_HEADER       *Table)
1002{
1003    ACPI_STATUS             Status;
1004    ACPI_WHEA_HEADER        *SubTable;
1005    UINT32                  Length = Table->Length;
1006    UINT32                  Offset = sizeof (ACPI_TABLE_EINJ);
1007
1008
1009    /* Main table */
1010
1011    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj);
1012    if (ACPI_FAILURE (Status))
1013    {
1014        return;
1015    }
1016
1017    /* Subtables */
1018
1019    SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
1020    while (Offset < Table->Length)
1021    {
1022        AcpiOsPrintf ("\n");
1023        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1024                    sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
1025        if (ACPI_FAILURE (Status))
1026        {
1027            return;
1028        }
1029
1030        /* Point to next subtable (each subtable is of fixed length) */
1031
1032        Offset += sizeof (ACPI_WHEA_HEADER);
1033        SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
1034                        sizeof (ACPI_WHEA_HEADER));
1035    }
1036}
1037
1038
1039/*******************************************************************************
1040 *
1041 * FUNCTION:    AcpiDmDumpErst
1042 *
1043 * PARAMETERS:  Table               - A ERST table
1044 *
1045 * RETURN:      None
1046 *
1047 * DESCRIPTION: Format the contents of a ERST. This table type consists
1048 *              of an open-ended number of subtables.
1049 *
1050 ******************************************************************************/
1051
1052void
1053AcpiDmDumpErst (
1054    ACPI_TABLE_HEADER       *Table)
1055{
1056    ACPI_STATUS             Status;
1057    ACPI_WHEA_HEADER        *SubTable;
1058    UINT32                  Length = Table->Length;
1059    UINT32                  Offset = sizeof (ACPI_TABLE_ERST);
1060
1061
1062    /* Main table */
1063
1064    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst);
1065    if (ACPI_FAILURE (Status))
1066    {
1067        return;
1068    }
1069
1070    /* Subtables */
1071
1072    SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
1073    while (Offset < Table->Length)
1074    {
1075        AcpiOsPrintf ("\n");
1076        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1077                    sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
1078        if (ACPI_FAILURE (Status))
1079        {
1080            return;
1081        }
1082
1083        /* Point to next subtable (each subtable is of fixed length) */
1084
1085        Offset += sizeof (ACPI_WHEA_HEADER);
1086        SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
1087                        sizeof (ACPI_WHEA_HEADER));
1088    }
1089}
1090
1091
1092/*******************************************************************************
1093 *
1094 * FUNCTION:    AcpiDmDumpFpdt
1095 *
1096 * PARAMETERS:  Table               - A FPDT table
1097 *
1098 * RETURN:      None
1099 *
1100 * DESCRIPTION: Format the contents of a FPDT. This table type consists
1101 *              of an open-ended number of subtables.
1102 *
1103 ******************************************************************************/
1104
1105void
1106AcpiDmDumpFpdt (
1107    ACPI_TABLE_HEADER       *Table)
1108{
1109    ACPI_STATUS             Status;
1110    ACPI_FPDT_HEADER        *SubTable;
1111    UINT32                  Length = Table->Length;
1112    UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
1113    ACPI_DMTABLE_INFO       *InfoTable;
1114
1115
1116    /* There is no main table (other than the standard ACPI header) */
1117
1118    /* Subtables */
1119
1120    SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
1121    while (Offset < Table->Length)
1122    {
1123        /* Common subtable header */
1124
1125        AcpiOsPrintf ("\n");
1126        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1127                    SubTable->Length, AcpiDmTableInfoFpdtHdr);
1128        if (ACPI_FAILURE (Status))
1129        {
1130            return;
1131        }
1132
1133        switch (SubTable->Type)
1134        {
1135        case ACPI_FPDT_TYPE_BOOT:
1136
1137            InfoTable = AcpiDmTableInfoFpdt0;
1138            break;
1139
1140        case ACPI_FPDT_TYPE_S3PERF:
1141
1142            InfoTable = AcpiDmTableInfoFpdt1;
1143            break;
1144
1145        default:
1146
1147            AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n", SubTable->Type);
1148
1149            /* Attempt to continue */
1150
1151            if (!SubTable->Length)
1152            {
1153                AcpiOsPrintf ("Invalid zero length subtable\n");
1154                return;
1155            }
1156            goto NextSubTable;
1157        }
1158
1159        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1160                    SubTable->Length, InfoTable);
1161        if (ACPI_FAILURE (Status))
1162        {
1163            return;
1164        }
1165
1166NextSubTable:
1167        /* Point to next subtable */
1168
1169        Offset += SubTable->Length;
1170        SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, SubTable, SubTable->Length);
1171    }
1172}
1173
1174
1175/*******************************************************************************
1176 *
1177 * FUNCTION:    AcpiDmDumpGtdt
1178 *
1179 * PARAMETERS:  Table               - A GTDT table
1180 *
1181 * RETURN:      None
1182 *
1183 * DESCRIPTION: Format the contents of a GTDT. This table type consists
1184 *              of an open-ended number of subtables.
1185 *
1186 ******************************************************************************/
1187
1188void
1189AcpiDmDumpGtdt (
1190    ACPI_TABLE_HEADER       *Table)
1191{
1192    ACPI_STATUS             Status;
1193    ACPI_GTDT_HEADER        *SubTable;
1194    UINT32                  Length = Table->Length;
1195    UINT32                  Offset = sizeof (ACPI_TABLE_GTDT);
1196    ACPI_DMTABLE_INFO       *InfoTable;
1197    UINT32                  SubTableLength;
1198    UINT32                  GtCount;
1199    ACPI_GTDT_TIMER_ENTRY   *GtxTable;
1200
1201
1202    /* Main table */
1203
1204    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoGtdt);
1205    if (ACPI_FAILURE (Status))
1206    {
1207        return;
1208    }
1209
1210    /* Subtables */
1211
1212    SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
1213    while (Offset < Table->Length)
1214    {
1215        /* Common subtable header */
1216
1217        AcpiOsPrintf ("\n");
1218        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1219                    SubTable->Length, AcpiDmTableInfoGtdtHdr);
1220        if (ACPI_FAILURE (Status))
1221        {
1222            return;
1223        }
1224
1225        GtCount = 0;
1226        switch (SubTable->Type)
1227        {
1228        case ACPI_GTDT_TYPE_TIMER_BLOCK:
1229
1230            SubTableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
1231            GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1232                        SubTable))->TimerCount;
1233
1234            InfoTable = AcpiDmTableInfoGtdt0;
1235            break;
1236
1237        case ACPI_GTDT_TYPE_WATCHDOG:
1238
1239            SubTableLength = sizeof (ACPI_GTDT_WATCHDOG);
1240
1241            InfoTable = AcpiDmTableInfoGtdt1;
1242            break;
1243
1244        default:
1245
1246            /* Cannot continue on unknown type - no length */
1247
1248            AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n", SubTable->Type);
1249            return;
1250        }
1251
1252        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1253                    SubTable->Length, InfoTable);
1254        if (ACPI_FAILURE (Status))
1255        {
1256            return;
1257        }
1258
1259        /* Point to end of current subtable (each subtable above is of fixed length) */
1260
1261        Offset += SubTableLength;
1262
1263        /* If there are any Gt Timer Blocks from above, dump them now */
1264
1265        if (GtCount)
1266        {
1267            GtxTable = ACPI_ADD_PTR (ACPI_GTDT_TIMER_ENTRY, SubTable, SubTableLength);
1268            SubTableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
1269
1270            while (GtCount)
1271            {
1272                AcpiOsPrintf ("\n");
1273                Status = AcpiDmDumpTable (Length, Offset, GtxTable,
1274                            sizeof (ACPI_GTDT_TIMER_ENTRY), AcpiDmTableInfoGtdt0a);
1275                if (ACPI_FAILURE (Status))
1276                {
1277                    return;
1278                }
1279                Offset += sizeof (ACPI_GTDT_TIMER_ENTRY);
1280                GtxTable++;
1281                GtCount--;
1282            }
1283        }
1284
1285        /* Point to next subtable */
1286
1287        SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, SubTable, SubTableLength);
1288    }
1289}
1290
1291
1292/*******************************************************************************
1293 *
1294 * FUNCTION:    AcpiDmDumpHest
1295 *
1296 * PARAMETERS:  Table               - A HEST table
1297 *
1298 * RETURN:      None
1299 *
1300 * DESCRIPTION: Format the contents of a HEST. This table type consists
1301 *              of an open-ended number of subtables.
1302 *
1303 ******************************************************************************/
1304
1305void
1306AcpiDmDumpHest (
1307    ACPI_TABLE_HEADER       *Table)
1308{
1309    ACPI_STATUS             Status;
1310    ACPI_HEST_HEADER        *SubTable;
1311    UINT32                  Length = Table->Length;
1312    UINT32                  Offset = sizeof (ACPI_TABLE_HEST);
1313    ACPI_DMTABLE_INFO       *InfoTable;
1314    UINT32                  SubTableLength;
1315    UINT32                  BankCount;
1316    ACPI_HEST_IA_ERROR_BANK *BankTable;
1317
1318
1319    /* Main table */
1320
1321    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest);
1322    if (ACPI_FAILURE (Status))
1323    {
1324        return;
1325    }
1326
1327    /* Subtables */
1328
1329    SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
1330    while (Offset < Table->Length)
1331    {
1332        BankCount = 0;
1333        switch (SubTable->Type)
1334        {
1335        case ACPI_HEST_TYPE_IA32_CHECK:
1336
1337            InfoTable = AcpiDmTableInfoHest0;
1338            SubTableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
1339            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1340                            SubTable))->NumHardwareBanks;
1341            break;
1342
1343        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1344
1345            InfoTable = AcpiDmTableInfoHest1;
1346            SubTableLength = sizeof (ACPI_HEST_IA_CORRECTED);
1347            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1348                            SubTable))->NumHardwareBanks;
1349            break;
1350
1351        case ACPI_HEST_TYPE_IA32_NMI:
1352
1353            InfoTable = AcpiDmTableInfoHest2;
1354            SubTableLength = sizeof (ACPI_HEST_IA_NMI);
1355            break;
1356
1357        case ACPI_HEST_TYPE_AER_ROOT_PORT:
1358
1359            InfoTable = AcpiDmTableInfoHest6;
1360            SubTableLength = sizeof (ACPI_HEST_AER_ROOT);
1361            break;
1362
1363        case ACPI_HEST_TYPE_AER_ENDPOINT:
1364
1365            InfoTable = AcpiDmTableInfoHest7;
1366            SubTableLength = sizeof (ACPI_HEST_AER);
1367            break;
1368
1369        case ACPI_HEST_TYPE_AER_BRIDGE:
1370
1371            InfoTable = AcpiDmTableInfoHest8;
1372            SubTableLength = sizeof (ACPI_HEST_AER_BRIDGE);
1373            break;
1374
1375        case ACPI_HEST_TYPE_GENERIC_ERROR:
1376
1377            InfoTable = AcpiDmTableInfoHest9;
1378            SubTableLength = sizeof (ACPI_HEST_GENERIC);
1379            break;
1380
1381        default:
1382
1383            /* Cannot continue on unknown type - no length */
1384
1385            AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n", SubTable->Type);
1386            return;
1387        }
1388
1389        AcpiOsPrintf ("\n");
1390        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1391                    SubTableLength, InfoTable);
1392        if (ACPI_FAILURE (Status))
1393        {
1394            return;
1395        }
1396
1397        /* Point to end of current subtable (each subtable above is of fixed length) */
1398
1399        Offset += SubTableLength;
1400
1401        /* If there are any (fixed-length) Error Banks from above, dump them now */
1402
1403        if (BankCount)
1404        {
1405            BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, SubTable, SubTableLength);
1406            SubTableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
1407
1408            while (BankCount)
1409            {
1410                AcpiOsPrintf ("\n");
1411                Status = AcpiDmDumpTable (Length, Offset, BankTable,
1412                            sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank);
1413                if (ACPI_FAILURE (Status))
1414                {
1415                    return;
1416                }
1417                Offset += sizeof (ACPI_HEST_IA_ERROR_BANK);
1418                BankTable++;
1419                BankCount--;
1420            }
1421        }
1422
1423        /* Point to next subtable */
1424
1425        SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, SubTable, SubTableLength);
1426    }
1427}
1428
1429
1430/*******************************************************************************
1431 *
1432 * FUNCTION:    AcpiDmDumpIvrs
1433 *
1434 * PARAMETERS:  Table               - A IVRS table
1435 *
1436 * RETURN:      None
1437 *
1438 * DESCRIPTION: Format the contents of a IVRS
1439 *
1440 ******************************************************************************/
1441
1442static UINT8 EntrySizes[] = {4,8,16,32};
1443
1444void
1445AcpiDmDumpIvrs (
1446    ACPI_TABLE_HEADER       *Table)
1447{
1448    ACPI_STATUS             Status;
1449    UINT32                  Offset = sizeof (ACPI_TABLE_IVRS);
1450    UINT32                  EntryOffset;
1451    UINT32                  EntryLength;
1452    UINT32                  EntryType;
1453    ACPI_IVRS_DE_HEADER     *DeviceEntry;
1454    ACPI_IVRS_HEADER        *SubTable;
1455    ACPI_DMTABLE_INFO       *InfoTable;
1456
1457
1458    /* Main table */
1459
1460    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs);
1461    if (ACPI_FAILURE (Status))
1462    {
1463        return;
1464    }
1465
1466    /* Subtables */
1467
1468    SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
1469    while (Offset < Table->Length)
1470    {
1471        /* Common subtable header */
1472
1473        AcpiOsPrintf ("\n");
1474        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1475                    SubTable->Length, AcpiDmTableInfoIvrsHdr);
1476        if (ACPI_FAILURE (Status))
1477        {
1478            return;
1479        }
1480
1481        switch (SubTable->Type)
1482        {
1483        case ACPI_IVRS_TYPE_HARDWARE:
1484
1485            InfoTable = AcpiDmTableInfoIvrs0;
1486            break;
1487
1488        case ACPI_IVRS_TYPE_MEMORY1:
1489        case ACPI_IVRS_TYPE_MEMORY2:
1490        case ACPI_IVRS_TYPE_MEMORY3:
1491
1492            InfoTable = AcpiDmTableInfoIvrs1;
1493            break;
1494
1495        default:
1496
1497            AcpiOsPrintf ("\n**** Unknown IVRS subtable type 0x%X\n",
1498                SubTable->Type);
1499
1500            /* Attempt to continue */
1501
1502            if (!SubTable->Length)
1503            {
1504                AcpiOsPrintf ("Invalid zero length subtable\n");
1505                return;
1506            }
1507            goto NextSubTable;
1508        }
1509
1510        /* Dump the subtable */
1511
1512        AcpiOsPrintf ("\n");
1513        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1514                    SubTable->Length, InfoTable);
1515        if (ACPI_FAILURE (Status))
1516        {
1517            return;
1518        }
1519
1520        /* The hardware subtable can contain multiple device entries */
1521
1522        if (SubTable->Type == ACPI_IVRS_TYPE_HARDWARE)
1523        {
1524            EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE);
1525            DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, SubTable,
1526                            sizeof (ACPI_IVRS_HARDWARE));
1527
1528            while (EntryOffset < (Offset + SubTable->Length))
1529            {
1530                AcpiOsPrintf ("\n");
1531                /*
1532                 * Upper 2 bits of Type encode the length of the device entry
1533                 *
1534                 * 00 = 4 byte
1535                 * 01 = 8 byte
1536                 * 10 = 16 byte - currently no entries defined
1537                 * 11 = 32 byte - currently no entries defined
1538                 */
1539                EntryType = DeviceEntry->Type;
1540                EntryLength = EntrySizes [EntryType >> 6];
1541
1542                switch (EntryType)
1543                {
1544                /* 4-byte device entries */
1545
1546                case ACPI_IVRS_TYPE_PAD4:
1547                case ACPI_IVRS_TYPE_ALL:
1548                case ACPI_IVRS_TYPE_SELECT:
1549                case ACPI_IVRS_TYPE_START:
1550                case ACPI_IVRS_TYPE_END:
1551
1552                    InfoTable = AcpiDmTableInfoIvrs4;
1553                    break;
1554
1555                /* 8-byte entries, type A */
1556
1557                case ACPI_IVRS_TYPE_ALIAS_SELECT:
1558                case ACPI_IVRS_TYPE_ALIAS_START:
1559
1560                    InfoTable = AcpiDmTableInfoIvrs8a;
1561                    break;
1562
1563                /* 8-byte entries, type B */
1564
1565                case ACPI_IVRS_TYPE_PAD8:
1566                case ACPI_IVRS_TYPE_EXT_SELECT:
1567                case ACPI_IVRS_TYPE_EXT_START:
1568
1569                    InfoTable = AcpiDmTableInfoIvrs8b;
1570                    break;
1571
1572                /* 8-byte entries, type C */
1573
1574                case ACPI_IVRS_TYPE_SPECIAL:
1575
1576                    InfoTable = AcpiDmTableInfoIvrs8c;
1577                    break;
1578
1579                default:
1580                    InfoTable = AcpiDmTableInfoIvrs4;
1581                    AcpiOsPrintf (
1582                        "\n**** Unknown IVRS device entry type/length: "
1583                        "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
1584                        EntryType, EntryLength, EntryOffset);
1585                    break;
1586                }
1587
1588                /* Dump the Device Entry */
1589
1590                Status = AcpiDmDumpTable (Table->Length, EntryOffset,
1591                            DeviceEntry, EntryLength, InfoTable);
1592
1593                EntryOffset += EntryLength;
1594                DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, DeviceEntry,
1595                                EntryLength);
1596            }
1597        }
1598
1599NextSubTable:
1600        /* Point to next subtable */
1601
1602        Offset += SubTable->Length;
1603        SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, SubTable, SubTable->Length);
1604    }
1605}
1606
1607
1608/*******************************************************************************
1609 *
1610 * FUNCTION:    AcpiDmDumpLpit
1611 *
1612 * PARAMETERS:  Table               - A LPIT table
1613 *
1614 * RETURN:      None
1615 *
1616 * DESCRIPTION: Format the contents of a LPIT. This table type consists
1617 *              of an open-ended number of subtables. Note: There are no
1618 *              entries in the main table. An LPIT consists of the table
1619 *              header and then subtables only.
1620 *
1621 ******************************************************************************/
1622
1623void
1624AcpiDmDumpLpit (
1625    ACPI_TABLE_HEADER       *Table)
1626{
1627    ACPI_STATUS             Status;
1628    ACPI_LPIT_HEADER        *SubTable;
1629    UINT32                  Length = Table->Length;
1630    UINT32                  Offset = sizeof (ACPI_TABLE_LPIT);
1631    ACPI_DMTABLE_INFO       *InfoTable;
1632    UINT32                  SubTableLength;
1633
1634
1635    /* Subtables */
1636
1637    SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset);
1638    while (Offset < Table->Length)
1639    {
1640        /* Common subtable header */
1641
1642        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1643                    sizeof (ACPI_LPIT_HEADER), AcpiDmTableInfoLpitHdr);
1644        if (ACPI_FAILURE (Status))
1645        {
1646            return;
1647        }
1648
1649        switch (SubTable->Type)
1650        {
1651        case ACPI_LPIT_TYPE_NATIVE_CSTATE:
1652
1653            InfoTable = AcpiDmTableInfoLpit0;
1654            SubTableLength = sizeof (ACPI_LPIT_NATIVE);
1655            break;
1656
1657        case ACPI_LPIT_TYPE_SIMPLE_IO:
1658
1659            InfoTable = AcpiDmTableInfoLpit1;
1660            SubTableLength = sizeof (ACPI_LPIT_IO);
1661            break;
1662
1663        default:
1664
1665            /* Cannot continue on unknown type - no length */
1666
1667            AcpiOsPrintf ("\n**** Unknown LPIT subtable type 0x%X\n", SubTable->Type);
1668            return;
1669        }
1670
1671        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1672                    SubTableLength, InfoTable);
1673        if (ACPI_FAILURE (Status))
1674        {
1675            return;
1676        }
1677        AcpiOsPrintf ("\n");
1678
1679        /* Point to next subtable */
1680
1681        Offset += SubTableLength;
1682        SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, SubTable, SubTableLength);
1683    }
1684}
1685
1686
1687/*******************************************************************************
1688 *
1689 * FUNCTION:    AcpiDmDumpMadt
1690 *
1691 * PARAMETERS:  Table               - A MADT table
1692 *
1693 * RETURN:      None
1694 *
1695 * DESCRIPTION: Format the contents of a MADT. This table type consists
1696 *              of an open-ended number of subtables.
1697 *
1698 ******************************************************************************/
1699
1700void
1701AcpiDmDumpMadt (
1702    ACPI_TABLE_HEADER       *Table)
1703{
1704    ACPI_STATUS             Status;
1705    ACPI_SUBTABLE_HEADER    *SubTable;
1706    UINT32                  Length = Table->Length;
1707    UINT32                  Offset = sizeof (ACPI_TABLE_MADT);
1708    ACPI_DMTABLE_INFO       *InfoTable;
1709
1710
1711    /* Main table */
1712
1713    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoMadt);
1714    if (ACPI_FAILURE (Status))
1715    {
1716        return;
1717    }
1718
1719    /* Subtables */
1720
1721    SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
1722    while (Offset < Table->Length)
1723    {
1724        /* Common subtable header */
1725
1726        AcpiOsPrintf ("\n");
1727        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1728                    SubTable->Length, AcpiDmTableInfoMadtHdr);
1729        if (ACPI_FAILURE (Status))
1730        {
1731            return;
1732        }
1733
1734        switch (SubTable->Type)
1735        {
1736        case ACPI_MADT_TYPE_LOCAL_APIC:
1737
1738            InfoTable = AcpiDmTableInfoMadt0;
1739            break;
1740
1741        case ACPI_MADT_TYPE_IO_APIC:
1742
1743            InfoTable = AcpiDmTableInfoMadt1;
1744            break;
1745
1746        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1747
1748            InfoTable = AcpiDmTableInfoMadt2;
1749            break;
1750
1751        case ACPI_MADT_TYPE_NMI_SOURCE:
1752
1753            InfoTable = AcpiDmTableInfoMadt3;
1754            break;
1755
1756        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1757
1758            InfoTable = AcpiDmTableInfoMadt4;
1759            break;
1760
1761        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1762
1763            InfoTable = AcpiDmTableInfoMadt5;
1764            break;
1765
1766        case ACPI_MADT_TYPE_IO_SAPIC:
1767
1768            InfoTable = AcpiDmTableInfoMadt6;
1769            break;
1770
1771        case ACPI_MADT_TYPE_LOCAL_SAPIC:
1772
1773            InfoTable = AcpiDmTableInfoMadt7;
1774            break;
1775
1776        case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1777
1778            InfoTable = AcpiDmTableInfoMadt8;
1779            break;
1780
1781        case ACPI_MADT_TYPE_LOCAL_X2APIC:
1782
1783            InfoTable = AcpiDmTableInfoMadt9;
1784            break;
1785
1786        case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1787
1788            InfoTable = AcpiDmTableInfoMadt10;
1789            break;
1790
1791        case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1792
1793            InfoTable = AcpiDmTableInfoMadt11;
1794            break;
1795
1796        case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1797
1798            InfoTable = AcpiDmTableInfoMadt12;
1799            break;
1800
1801        case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
1802
1803            InfoTable = AcpiDmTableInfoMadt13;
1804            break;
1805
1806        case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
1807
1808            InfoTable = AcpiDmTableInfoMadt14;
1809            break;
1810
1811        default:
1812
1813            AcpiOsPrintf ("\n**** Unknown MADT subtable type 0x%X\n\n", SubTable->Type);
1814
1815            /* Attempt to continue */
1816
1817            if (!SubTable->Length)
1818            {
1819                AcpiOsPrintf ("Invalid zero length subtable\n");
1820                return;
1821            }
1822            goto NextSubTable;
1823        }
1824
1825        Status = AcpiDmDumpTable (Length, Offset, SubTable,
1826                    SubTable->Length, InfoTable);
1827        if (ACPI_FAILURE (Status))
1828        {
1829            return;
1830        }
1831
1832NextSubTable:
1833        /* Point to next subtable */
1834
1835        Offset += SubTable->Length;
1836        SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length);
1837    }
1838}
1839
1840
1841/*******************************************************************************
1842 *
1843 * FUNCTION:    AcpiDmDumpMcfg
1844 *
1845 * PARAMETERS:  Table               - A MCFG Table
1846 *
1847 * RETURN:      None
1848 *
1849 * DESCRIPTION: Format the contents of a MCFG table
1850 *
1851 ******************************************************************************/
1852
1853void
1854AcpiDmDumpMcfg (
1855    ACPI_TABLE_HEADER       *Table)
1856{
1857    ACPI_STATUS             Status;
1858    UINT32                  Offset = sizeof (ACPI_TABLE_MCFG);
1859    ACPI_MCFG_ALLOCATION    *SubTable;
1860
1861
1862    /* Main table */
1863
1864    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMcfg);
1865    if (ACPI_FAILURE (Status))
1866    {
1867        return;
1868    }
1869
1870    /* Subtables */
1871
1872    SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
1873    while (Offset < Table->Length)
1874    {
1875        if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length)
1876        {
1877            AcpiOsPrintf ("Warning: there are %u invalid trailing bytes\n",
1878                sizeof (ACPI_MCFG_ALLOCATION) - (Offset - Table->Length));
1879            return;
1880        }
1881
1882        AcpiOsPrintf ("\n");
1883        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1884                    sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0);
1885        if (ACPI_FAILURE (Status))
1886        {
1887            return;
1888        }
1889
1890        /* Point to next subtable (each subtable is of fixed length) */
1891
1892        Offset += sizeof (ACPI_MCFG_ALLOCATION);
1893        SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, SubTable,
1894                        sizeof (ACPI_MCFG_ALLOCATION));
1895    }
1896}
1897
1898
1899/*******************************************************************************
1900 *
1901 * FUNCTION:    AcpiDmDumpMpst
1902 *
1903 * PARAMETERS:  Table               - A MPST Table
1904 *
1905 * RETURN:      None
1906 *
1907 * DESCRIPTION: Format the contents of a MPST table
1908 *
1909 ******************************************************************************/
1910
1911void
1912AcpiDmDumpMpst (
1913    ACPI_TABLE_HEADER       *Table)
1914{
1915    ACPI_STATUS             Status;
1916    UINT32                  Offset = sizeof (ACPI_TABLE_MPST);
1917    ACPI_MPST_POWER_NODE    *SubTable0;
1918    ACPI_MPST_POWER_STATE   *SubTable0A;
1919    ACPI_MPST_COMPONENT     *SubTable0B;
1920    ACPI_MPST_DATA_HDR      *SubTable1;
1921    ACPI_MPST_POWER_DATA    *SubTable2;
1922    UINT16                  SubtableCount;
1923    UINT32                  PowerStateCount;
1924    UINT32                  ComponentCount;
1925
1926
1927    /* Main table */
1928
1929    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMpst);
1930    if (ACPI_FAILURE (Status))
1931    {
1932        return;
1933    }
1934
1935    /* Subtable: Memory Power Node(s) */
1936
1937    SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount;
1938    SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
1939
1940    while ((Offset < Table->Length) && SubtableCount)
1941    {
1942        AcpiOsPrintf ("\n");
1943        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0,
1944                    sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0);
1945        if (ACPI_FAILURE (Status))
1946        {
1947            return;
1948        }
1949
1950        /* Extract the sub-subtable counts */
1951
1952        PowerStateCount = SubTable0->NumPowerStates;
1953        ComponentCount = SubTable0->NumPhysicalComponents;
1954        Offset += sizeof (ACPI_MPST_POWER_NODE);
1955
1956        /* Sub-subtables - Memory Power State Structure(s) */
1957
1958        SubTable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, SubTable0,
1959            sizeof (ACPI_MPST_POWER_NODE));
1960
1961        while (PowerStateCount)
1962        {
1963            AcpiOsPrintf ("\n");
1964            Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0A,
1965                        sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A);
1966            if (ACPI_FAILURE (Status))
1967            {
1968                return;
1969            }
1970
1971            SubTable0A++;
1972            PowerStateCount--;
1973            Offset += sizeof (ACPI_MPST_POWER_STATE);
1974       }
1975
1976        /* Sub-subtables - Physical Component ID Structure(s) */
1977
1978        SubTable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, SubTable0A);
1979
1980        if (ComponentCount)
1981        {
1982            AcpiOsPrintf ("\n");
1983        }
1984
1985        while (ComponentCount)
1986        {
1987            Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0B,
1988                        sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B);
1989            if (ACPI_FAILURE (Status))
1990            {
1991                return;
1992            }
1993
1994            SubTable0B++;
1995            ComponentCount--;
1996            Offset += sizeof (ACPI_MPST_COMPONENT);
1997        }
1998
1999        /* Point to next Memory Power Node subtable */
2000
2001        SubtableCount--;
2002        SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, SubTable0,
2003            sizeof (ACPI_MPST_POWER_NODE) +
2004            (sizeof (ACPI_MPST_POWER_STATE) * SubTable0->NumPowerStates) +
2005            (sizeof (ACPI_MPST_COMPONENT) * SubTable0->NumPhysicalComponents));
2006    }
2007
2008    /* Subtable: Count of Memory Power State Characteristic structures */
2009
2010    AcpiOsPrintf ("\n");
2011    SubTable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, SubTable0);
2012    Status = AcpiDmDumpTable (Table->Length, Offset, SubTable1,
2013                sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1);
2014    if (ACPI_FAILURE (Status))
2015    {
2016        return;
2017    }
2018
2019    SubtableCount = SubTable1->CharacteristicsCount;
2020    Offset += sizeof (ACPI_MPST_DATA_HDR);
2021
2022    /* Subtable: Memory Power State Characteristics structure(s) */
2023
2024    SubTable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, SubTable1, sizeof (ACPI_MPST_DATA_HDR));
2025
2026    while ((Offset < Table->Length) && SubtableCount)
2027    {
2028        AcpiOsPrintf ("\n");
2029        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable2,
2030                    sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2);
2031        if (ACPI_FAILURE (Status))
2032        {
2033            return;
2034        }
2035
2036        SubTable2++;
2037        SubtableCount--;
2038        Offset += sizeof (ACPI_MPST_POWER_DATA);
2039    }
2040}
2041
2042
2043/*******************************************************************************
2044 *
2045 * FUNCTION:    AcpiDmDumpMsct
2046 *
2047 * PARAMETERS:  Table               - A MSCT table
2048 *
2049 * RETURN:      None
2050 *
2051 * DESCRIPTION: Format the contents of a MSCT
2052 *
2053 ******************************************************************************/
2054
2055void
2056AcpiDmDumpMsct (
2057    ACPI_TABLE_HEADER       *Table)
2058{
2059    ACPI_STATUS             Status;
2060    UINT32                  Offset = sizeof (ACPI_TABLE_MSCT);
2061    ACPI_MSCT_PROXIMITY     *SubTable;
2062
2063
2064    /* Main table */
2065
2066    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct);
2067    if (ACPI_FAILURE (Status))
2068    {
2069        return;
2070    }
2071
2072    /* Subtables */
2073
2074    SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
2075    while (Offset < Table->Length)
2076    {
2077        /* Common subtable header */
2078
2079        AcpiOsPrintf ("\n");
2080        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2081                    sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0);
2082        if (ACPI_FAILURE (Status))
2083        {
2084            return;
2085        }
2086
2087        /* Point to next subtable */
2088
2089        Offset += sizeof (ACPI_MSCT_PROXIMITY);
2090        SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, SubTable, sizeof (ACPI_MSCT_PROXIMITY));
2091    }
2092}
2093
2094
2095/*******************************************************************************
2096 *
2097 * FUNCTION:    AcpiDmDumpMtmr
2098 *
2099 * PARAMETERS:  Table               - A MTMR table
2100 *
2101 * RETURN:      None
2102 *
2103 * DESCRIPTION: Format the contents of a MTMR
2104 *
2105 ******************************************************************************/
2106
2107void
2108AcpiDmDumpMtmr (
2109    ACPI_TABLE_HEADER       *Table)
2110{
2111    ACPI_STATUS             Status;
2112    UINT32                  Offset = sizeof (ACPI_TABLE_MTMR);
2113    ACPI_MTMR_ENTRY         *SubTable;
2114
2115
2116    /* Main table */
2117
2118    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMtmr);
2119    if (ACPI_FAILURE (Status))
2120    {
2121        return;
2122    }
2123
2124    /* Subtables */
2125
2126    SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Table, Offset);
2127    while (Offset < Table->Length)
2128    {
2129        /* Common subtable header */
2130
2131        AcpiOsPrintf ("\n");
2132        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2133                    sizeof (ACPI_MTMR_ENTRY), AcpiDmTableInfoMtmr0);
2134        if (ACPI_FAILURE (Status))
2135        {
2136            return;
2137        }
2138
2139        /* Point to next subtable */
2140
2141        Offset += sizeof (ACPI_MTMR_ENTRY);
2142        SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, SubTable, sizeof (ACPI_MTMR_ENTRY));
2143    }
2144}
2145
2146
2147/*******************************************************************************
2148 *
2149 * FUNCTION:    AcpiDmDumpPcct
2150 *
2151 * PARAMETERS:  Table               - A PCCT table
2152 *
2153 * RETURN:      None
2154 *
2155 * DESCRIPTION: Format the contents of a PCCT. This table type consists
2156 *              of an open-ended number of subtables.
2157 *
2158 ******************************************************************************/
2159
2160void
2161AcpiDmDumpPcct (
2162    ACPI_TABLE_HEADER       *Table)
2163{
2164    ACPI_STATUS             Status;
2165    ACPI_PCCT_SUBSPACE      *SubTable;
2166    ACPI_DMTABLE_INFO       *InfoTable;
2167    UINT32                  Length = Table->Length;
2168    UINT32                  Offset = sizeof (ACPI_TABLE_PCCT);
2169
2170
2171    /* Main table */
2172
2173    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct);
2174    if (ACPI_FAILURE (Status))
2175    {
2176        return;
2177    }
2178
2179    /* Subtables */
2180
2181    SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
2182    while (Offset < Table->Length)
2183    {
2184        /* Common subtable header */
2185
2186        AcpiOsPrintf ("\n");
2187        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2188                    SubTable->Header.Length, AcpiDmTableInfoPcctHdr);
2189        if (ACPI_FAILURE (Status))
2190        {
2191            return;
2192        }
2193
2194        switch (SubTable->Header.Type)
2195        {
2196        case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
2197
2198            InfoTable = AcpiDmTableInfoPcct0;
2199            break;
2200
2201        case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
2202
2203            InfoTable = AcpiDmTableInfoPcct1;
2204            break;
2205
2206        default:
2207
2208            AcpiOsPrintf (
2209                "\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n",
2210                SubTable->Header.Type);
2211            return;
2212        }
2213
2214        AcpiOsPrintf ("\n");
2215        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2216                    SubTable->Header.Length, InfoTable);
2217        if (ACPI_FAILURE (Status))
2218        {
2219            return;
2220        }
2221
2222        /* Point to next subtable */
2223
2224        Offset += SubTable->Header.Length;
2225        SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, SubTable,
2226                    SubTable->Header.Length);
2227    }
2228}
2229
2230
2231/*******************************************************************************
2232 *
2233 * FUNCTION:    AcpiDmDumpPmtt
2234 *
2235 * PARAMETERS:  Table               - A PMTT table
2236 *
2237 * RETURN:      None
2238 *
2239 * DESCRIPTION: Format the contents of a PMTT. This table type consists
2240 *              of an open-ended number of subtables.
2241 *
2242 ******************************************************************************/
2243
2244void
2245AcpiDmDumpPmtt (
2246    ACPI_TABLE_HEADER       *Table)
2247{
2248    ACPI_STATUS             Status;
2249    ACPI_PMTT_HEADER        *SubTable;
2250    ACPI_PMTT_HEADER        *MemSubTable;
2251    ACPI_PMTT_HEADER        *DimmSubTable;
2252    ACPI_PMTT_DOMAIN        *DomainArray;
2253    UINT32                  Length = Table->Length;
2254    UINT32                  Offset = sizeof (ACPI_TABLE_PMTT);
2255    UINT32                  MemOffset;
2256    UINT32                  DimmOffset;
2257    UINT32                  DomainOffset;
2258    UINT32                  DomainCount;
2259
2260
2261    /* Main table */
2262
2263    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt);
2264    if (ACPI_FAILURE (Status))
2265    {
2266        return;
2267    }
2268
2269    /* Subtables */
2270
2271    SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
2272    while (Offset < Table->Length)
2273    {
2274        /* Common subtable header */
2275
2276        AcpiOsPrintf ("\n");
2277        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2278                    SubTable->Length, AcpiDmTableInfoPmttHdr);
2279        if (ACPI_FAILURE (Status))
2280        {
2281            return;
2282        }
2283
2284        /* Only Socket subtables are expected at this level */
2285
2286        if (SubTable->Type != ACPI_PMTT_TYPE_SOCKET)
2287        {
2288            AcpiOsPrintf (
2289                "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
2290                SubTable->Type);
2291            return;
2292        }
2293
2294        /* Dump the fixed-length portion of the subtable */
2295
2296        Status = AcpiDmDumpTable (Length, Offset, SubTable,
2297                    SubTable->Length, AcpiDmTableInfoPmtt0);
2298        if (ACPI_FAILURE (Status))
2299        {
2300            return;
2301        }
2302
2303        /* Walk the memory controller subtables */
2304
2305        MemOffset = sizeof (ACPI_PMTT_SOCKET);
2306        MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, SubTable,
2307            sizeof (ACPI_PMTT_SOCKET));
2308
2309        while (((Offset + MemOffset) < Table->Length) &&
2310            (MemOffset < SubTable->Length))
2311        {
2312            /* Common subtable header */
2313
2314            AcpiOsPrintf ("\n");
2315            Status = AcpiDmDumpTable (Length,
2316                        Offset + MemOffset, MemSubTable,
2317                        MemSubTable->Length, AcpiDmTableInfoPmttHdr);
2318            if (ACPI_FAILURE (Status))
2319            {
2320                return;
2321            }
2322
2323            /* Only memory controller subtables are expected at this level */
2324
2325            if (MemSubTable->Type != ACPI_PMTT_TYPE_CONTROLLER)
2326            {
2327                AcpiOsPrintf (
2328                    "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
2329                    MemSubTable->Type);
2330                return;
2331            }
2332
2333            /* Dump the fixed-length portion of the controller subtable */
2334
2335            Status = AcpiDmDumpTable (Length,
2336                        Offset + MemOffset, MemSubTable,
2337                        MemSubTable->Length, AcpiDmTableInfoPmtt1);
2338            if (ACPI_FAILURE (Status))
2339            {
2340                return;
2341            }
2342
2343            /* Walk the variable count of proximity domains */
2344
2345            DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubTable)->DomainCount;
2346            DomainOffset = sizeof (ACPI_PMTT_CONTROLLER);
2347            DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubTable,
2348                sizeof (ACPI_PMTT_CONTROLLER));
2349
2350            while (((Offset + MemOffset + DomainOffset) < Table->Length) &&
2351                ((MemOffset + DomainOffset) < SubTable->Length) &&
2352                DomainCount)
2353            {
2354                Status = AcpiDmDumpTable (Length,
2355                            Offset + MemOffset + DomainOffset, DomainArray,
2356                            sizeof (ACPI_PMTT_DOMAIN), AcpiDmTableInfoPmtt1a);
2357                if (ACPI_FAILURE (Status))
2358                {
2359                    return;
2360                }
2361
2362                DomainOffset += sizeof (ACPI_PMTT_DOMAIN);
2363                DomainArray++;
2364                DomainCount--;
2365            }
2366
2367            if (DomainCount)
2368            {
2369                AcpiOsPrintf (
2370                    "\n**** DomainCount exceeds subtable length\n\n");
2371            }
2372
2373            /* Walk the physical component (DIMM) subtables */
2374
2375            DimmOffset = DomainOffset;
2376            DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubTable,
2377                DomainOffset);
2378
2379            while (((Offset + MemOffset + DimmOffset) < Table->Length) &&
2380                (DimmOffset < MemSubTable->Length))
2381            {
2382                /* Common subtable header */
2383
2384                AcpiOsPrintf ("\n");
2385                Status = AcpiDmDumpTable (Length,
2386                            Offset + MemOffset + DimmOffset, DimmSubTable,
2387                            DimmSubTable->Length, AcpiDmTableInfoPmttHdr);
2388                if (ACPI_FAILURE (Status))
2389                {
2390                    return;
2391                }
2392
2393                /* Only DIMM subtables are expected at this level */
2394
2395                if (DimmSubTable->Type != ACPI_PMTT_TYPE_DIMM)
2396                {
2397                    AcpiOsPrintf (
2398                        "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
2399                        DimmSubTable->Type);
2400                    return;
2401                }
2402
2403                /* Dump the fixed-length DIMM subtable */
2404
2405                Status = AcpiDmDumpTable (Length,
2406                            Offset + MemOffset + DimmOffset, DimmSubTable,
2407                            DimmSubTable->Length, AcpiDmTableInfoPmtt2);
2408                if (ACPI_FAILURE (Status))
2409                {
2410                    return;
2411                }
2412
2413                /* Point to next DIMM subtable */
2414
2415                DimmOffset += DimmSubTable->Length;
2416                DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
2417                    DimmSubTable, DimmSubTable->Length);
2418            }
2419
2420            /* Point to next Controller subtable */
2421
2422            MemOffset += MemSubTable->Length;
2423            MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
2424                MemSubTable, MemSubTable->Length);
2425        }
2426
2427        /* Point to next Socket subtable */
2428
2429        Offset += SubTable->Length;
2430        SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
2431            SubTable, SubTable->Length);
2432    }
2433}
2434
2435
2436/*******************************************************************************
2437 *
2438 * FUNCTION:    AcpiDmDumpS3pt
2439 *
2440 * PARAMETERS:  Table               - A S3PT table
2441 *
2442 * RETURN:      Length of the table
2443 *
2444 * DESCRIPTION: Format the contents of a S3PT
2445 *
2446 ******************************************************************************/
2447
2448UINT32
2449AcpiDmDumpS3pt (
2450    ACPI_TABLE_HEADER       *Tables)
2451{
2452    ACPI_STATUS             Status;
2453    UINT32                  Offset = sizeof (ACPI_TABLE_S3PT);
2454    ACPI_S3PT_HEADER        *SubTable;
2455    ACPI_DMTABLE_INFO       *InfoTable;
2456    ACPI_TABLE_S3PT         *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
2457
2458
2459    /* Main table */
2460
2461    Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt);
2462    if (ACPI_FAILURE (Status))
2463    {
2464        return 0;
2465    }
2466
2467    SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, S3ptTable, Offset);
2468    while (Offset < S3ptTable->Length)
2469    {
2470        /* Common subtable header */
2471
2472        AcpiOsPrintf ("\n");
2473        Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
2474                    SubTable->Length, AcpiDmTableInfoS3ptHdr);
2475        if (ACPI_FAILURE (Status))
2476        {
2477            return 0;
2478        }
2479
2480        switch (SubTable->Type)
2481        {
2482        case ACPI_S3PT_TYPE_RESUME:
2483
2484            InfoTable = AcpiDmTableInfoS3pt0;
2485            break;
2486
2487        case ACPI_S3PT_TYPE_SUSPEND:
2488
2489            InfoTable = AcpiDmTableInfoS3pt1;
2490            break;
2491
2492        default:
2493
2494            AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n", SubTable->Type);
2495
2496            /* Attempt to continue */
2497
2498            if (!SubTable->Length)
2499            {
2500                AcpiOsPrintf ("Invalid zero length subtable\n");
2501                return 0;
2502            }
2503            goto NextSubTable;
2504        }
2505
2506        AcpiOsPrintf ("\n");
2507        Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
2508                    SubTable->Length, InfoTable);
2509        if (ACPI_FAILURE (Status))
2510        {
2511            return 0;
2512        }
2513
2514NextSubTable:
2515        /* Point to next subtable */
2516
2517        Offset += SubTable->Length;
2518        SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, SubTable, SubTable->Length);
2519    }
2520
2521    return (S3ptTable->Length);
2522}
2523
2524
2525/*******************************************************************************
2526 *
2527 * FUNCTION:    AcpiDmDumpSlic
2528 *
2529 * PARAMETERS:  Table               - A SLIC table
2530 *
2531 * RETURN:      None
2532 *
2533 * DESCRIPTION: Format the contents of a SLIC
2534 *
2535 ******************************************************************************/
2536
2537void
2538AcpiDmDumpSlic (
2539    ACPI_TABLE_HEADER       *Table)
2540{
2541    AcpiDmDumpTable (Table->Length, sizeof (ACPI_TABLE_HEADER), Table,
2542                Table->Length - sizeof (*Table), AcpiDmTableInfoSlic);
2543}
2544
2545
2546/*******************************************************************************
2547 *
2548 * FUNCTION:    AcpiDmDumpSlit
2549 *
2550 * PARAMETERS:  Table               - An SLIT
2551 *
2552 * RETURN:      None
2553 *
2554 * DESCRIPTION: Format the contents of a SLIT
2555 *
2556 ******************************************************************************/
2557
2558void
2559AcpiDmDumpSlit (
2560    ACPI_TABLE_HEADER       *Table)
2561{
2562    ACPI_STATUS             Status;
2563    UINT32                  Offset;
2564    UINT8                   *Row;
2565    UINT32                  Localities;
2566    UINT32                  i;
2567    UINT32                  j;
2568
2569
2570    /* Main table */
2571
2572    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSlit);
2573    if (ACPI_FAILURE (Status))
2574    {
2575        return;
2576    }
2577
2578    /* Display the Locality NxN Matrix */
2579
2580    Localities = (UINT32) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->LocalityCount;
2581    Offset = ACPI_OFFSET (ACPI_TABLE_SLIT, Entry[0]);
2582    Row = (UINT8 *) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->Entry;
2583
2584    for (i = 0; i < Localities; i++)
2585    {
2586        /* Display one row of the matrix */
2587
2588        AcpiDmLineHeader2 (Offset, Localities, "Locality", i);
2589        for  (j = 0; j < Localities; j++)
2590        {
2591            /* Check for beyond EOT */
2592
2593            if (Offset >= Table->Length)
2594            {
2595                AcpiOsPrintf ("\n**** Not enough room in table for all localities\n");
2596                return;
2597            }
2598
2599            AcpiOsPrintf ("%2.2X", Row[j]);
2600            Offset++;
2601
2602            /* Display up to 16 bytes per output row */
2603
2604            if ((j+1) < Localities)
2605            {
2606                AcpiOsPrintf (" ");
2607
2608                if (j && (((j+1) % 16) == 0))
2609                {
2610                    AcpiOsPrintf ("\\\n"); /* With line continuation char */
2611                    AcpiDmLineHeader (Offset, 0, NULL);
2612                }
2613            }
2614        }
2615
2616        /* Point to next row */
2617
2618        AcpiOsPrintf ("\n");
2619        Row += Localities;
2620    }
2621}
2622
2623
2624/*******************************************************************************
2625 *
2626 * FUNCTION:    AcpiDmDumpSrat
2627 *
2628 * PARAMETERS:  Table               - A SRAT table
2629 *
2630 * RETURN:      None
2631 *
2632 * DESCRIPTION: Format the contents of a SRAT
2633 *
2634 ******************************************************************************/
2635
2636void
2637AcpiDmDumpSrat (
2638    ACPI_TABLE_HEADER       *Table)
2639{
2640    ACPI_STATUS             Status;
2641    UINT32                  Offset = sizeof (ACPI_TABLE_SRAT);
2642    ACPI_SUBTABLE_HEADER    *SubTable;
2643    ACPI_DMTABLE_INFO       *InfoTable;
2644
2645
2646    /* Main table */
2647
2648    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSrat);
2649    if (ACPI_FAILURE (Status))
2650    {
2651        return;
2652    }
2653
2654    /* Subtables */
2655
2656    SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
2657    while (Offset < Table->Length)
2658    {
2659        /* Common subtable header */
2660
2661        AcpiOsPrintf ("\n");
2662        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2663                    SubTable->Length, AcpiDmTableInfoSratHdr);
2664        if (ACPI_FAILURE (Status))
2665        {
2666            return;
2667        }
2668
2669        switch (SubTable->Type)
2670        {
2671        case ACPI_SRAT_TYPE_CPU_AFFINITY:
2672
2673            InfoTable = AcpiDmTableInfoSrat0;
2674            break;
2675
2676        case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2677
2678            InfoTable = AcpiDmTableInfoSrat1;
2679            break;
2680
2681        case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2682
2683            InfoTable = AcpiDmTableInfoSrat2;
2684            break;
2685
2686        case ACPI_SRAT_TYPE_GICC_AFFINITY:
2687
2688            InfoTable = AcpiDmTableInfoSrat3;
2689            break;
2690
2691        default:
2692            AcpiOsPrintf ("\n**** Unknown SRAT subtable type 0x%X\n", SubTable->Type);
2693
2694            /* Attempt to continue */
2695
2696            if (!SubTable->Length)
2697            {
2698                AcpiOsPrintf ("Invalid zero length subtable\n");
2699                return;
2700            }
2701            goto NextSubTable;
2702        }
2703
2704        AcpiOsPrintf ("\n");
2705        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2706                    SubTable->Length, InfoTable);
2707        if (ACPI_FAILURE (Status))
2708        {
2709            return;
2710        }
2711
2712NextSubTable:
2713        /* Point to next subtable */
2714
2715        Offset += SubTable->Length;
2716        SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length);
2717    }
2718}
2719
2720
2721/*******************************************************************************
2722 *
2723 * FUNCTION:    AcpiDmDumpVrtc
2724 *
2725 * PARAMETERS:  Table               - A VRTC table
2726 *
2727 * RETURN:      None
2728 *
2729 * DESCRIPTION: Format the contents of a VRTC
2730 *
2731 ******************************************************************************/
2732
2733void
2734AcpiDmDumpVrtc (
2735    ACPI_TABLE_HEADER       *Table)
2736{
2737    ACPI_STATUS             Status;
2738    UINT32                  Offset = sizeof (ACPI_TABLE_VRTC);
2739    ACPI_VRTC_ENTRY         *SubTable;
2740
2741
2742    /* Main table */
2743
2744    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoVrtc);
2745    if (ACPI_FAILURE (Status))
2746    {
2747        return;
2748    }
2749
2750    /* Subtables */
2751
2752    SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, Table, Offset);
2753    while (Offset < Table->Length)
2754    {
2755        /* Common subtable header */
2756
2757        AcpiOsPrintf ("\n");
2758        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2759                    sizeof (ACPI_VRTC_ENTRY), AcpiDmTableInfoVrtc0);
2760        if (ACPI_FAILURE (Status))
2761        {
2762            return;
2763        }
2764
2765        /* Point to next subtable */
2766
2767        Offset += sizeof (ACPI_VRTC_ENTRY);
2768        SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, SubTable, sizeof (ACPI_VRTC_ENTRY));
2769    }
2770}
2771
2772
2773/*******************************************************************************
2774 *
2775 * FUNCTION:    AcpiDmDumpWdat
2776 *
2777 * PARAMETERS:  Table               - A WDAT table
2778 *
2779 * RETURN:      None
2780 *
2781 * DESCRIPTION: Format the contents of a WDAT
2782 *
2783 ******************************************************************************/
2784
2785void
2786AcpiDmDumpWdat (
2787    ACPI_TABLE_HEADER       *Table)
2788{
2789    ACPI_STATUS             Status;
2790    UINT32                  Offset = sizeof (ACPI_TABLE_WDAT);
2791    ACPI_WDAT_ENTRY         *SubTable;
2792
2793
2794    /* Main table */
2795
2796    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoWdat);
2797    if (ACPI_FAILURE (Status))
2798    {
2799        return;
2800    }
2801
2802    /* Subtables */
2803
2804    SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset);
2805    while (Offset < Table->Length)
2806    {
2807        /* Common subtable header */
2808
2809        AcpiOsPrintf ("\n");
2810        Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
2811                    sizeof (ACPI_WDAT_ENTRY), AcpiDmTableInfoWdat0);
2812        if (ACPI_FAILURE (Status))
2813        {
2814            return;
2815        }
2816
2817        /* Point to next subtable */
2818
2819        Offset += sizeof (ACPI_WDAT_ENTRY);
2820        SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, SubTable, sizeof (ACPI_WDAT_ENTRY));
2821    }
2822}
2823