Sync ACPICA with Intel's version 20150515.
[dragonfly.git] / sys / contrib / dev / acpica / source / common / dmtbdump.c
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 "acpi.h"
45 #include "accommon.h"
46 #include "acdisasm.h"
47 #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
57 static void
58 AcpiDmValidateFadtLength (
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
81 void
82 AcpiDmDumpBuffer (
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
140 void
141 AcpiDmDumpUnicode (
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
184 DumpRawBuffer:
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
204 UINT32
205 AcpiDmDumpRsdp (
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
262 void
263 AcpiDmDumpRsdt (
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
302 void
303 AcpiDmDumpXsdt (
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
346 void
347 AcpiDmDumpFadt (
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
410 static void
411 AcpiDmValidateFadtLength (
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
474 void
475 AcpiDmDumpAsf (
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
640 void
641 AcpiDmDumpCpep (
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
693 void
694 AcpiDmDumpCsrt (
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
803 void
804 AcpiDmDumpDbg2 (
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
921 void
922 AcpiDmDumpDmar (
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
1054 NextSubtable:
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
1075 void
1076 AcpiDmDumpDrtm (
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
1190 void
1191 AcpiDmDumpEinj (
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
1243 void
1244 AcpiDmDumpErst (
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
1296 void
1297 AcpiDmDumpFpdt (
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
1357 NextSubTable:
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
1379 void
1380 AcpiDmDumpGtdt (
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
1496 void
1497 AcpiDmDumpHest (
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
1633 void
1634 AcpiDmDumpIort (
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
1836 NextSubTable:
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
1857 static UINT8 EntrySizes[] = {4,8,16,32};
1858
1859 void
1860 AcpiDmDumpIvrs (
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
2014 NextSubTable:
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
2038 void
2039 AcpiDmDumpLpit (
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
2109 void
2110 AcpiDmDumpMadt (
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
2246 NextSubTable:
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
2267 void
2268 AcpiDmDumpMcfg (
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
2325 void
2326 AcpiDmDumpMpst (
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
2469 void
2470 AcpiDmDumpMsct (
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
2521 void
2522 AcpiDmDumpMtmr (
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
2573 void
2574 AcpiDmDumpNfit (
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
2726 NextSubTable:
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
2748 void
2749 AcpiDmDumpPcct (
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
2832 void
2833 AcpiDmDumpPmtt (
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
3036 UINT32
3037 AcpiDmDumpS3pt (
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
3102 NextSubTable:
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
3125 void
3126 AcpiDmDumpSlic (
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
3146 void
3147 AcpiDmDumpSlit (
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
3224 void
3225 AcpiDmDumpSrat (
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
3300 NextSubTable:
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
3323 void
3324 AcpiDmDumpStao (
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
3371 void
3372 AcpiDmDumpVrtc (
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
3423 void
3424 AcpiDmDumpWdat (
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
3475 void
3476 AcpiDmDumpWpbt (
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 }