xref: /freebsd/sys/contrib/dev/acpica/common/dmtbdump.c (revision 5dcd9c10612684d1c823670cbb5b4715028784e7)
1 /******************************************************************************
2  *
3  * Module Name: dmtbdump - Dump ACPI data tables that contain no AML code
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2011, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/include/accommon.h>
46 #include <contrib/dev/acpica/include/acdisasm.h>
47 #include <contrib/dev/acpica/include/actables.h>
48 
49 /* This module used for application-level code only */
50 
51 #define _COMPONENT          ACPI_CA_DISASSEMBLER
52         ACPI_MODULE_NAME    ("dmtbdump")
53 
54 
55 static void
56 AcpiDmValidateFadtLength (
57     UINT32                  Revision,
58     UINT32                  Length);
59 
60 
61 /*******************************************************************************
62  *
63  * FUNCTION:    AcpiDmDumpRsdp
64  *
65  * PARAMETERS:  Table               - A RSDP
66  *
67  * RETURN:      Length of the table (there is not always a length field,
68  *              use revision or length if available (ACPI 2.0+))
69  *
70  * DESCRIPTION: Format the contents of a RSDP
71  *
72  ******************************************************************************/
73 
74 UINT32
75 AcpiDmDumpRsdp (
76     ACPI_TABLE_HEADER       *Table)
77 {
78     ACPI_TABLE_RSDP         *Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table);
79     UINT32                  Length = sizeof (ACPI_RSDP_COMMON);
80     UINT8                   Checksum;
81 
82 
83     /* Dump the common ACPI 1.0 portion */
84 
85     AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp1);
86 
87     /* Validate the first checksum */
88 
89     Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_RSDP_COMMON),
90                 Rsdp->Checksum);
91     if (Checksum != Rsdp->Checksum)
92     {
93         AcpiOsPrintf ("/* Incorrect Checksum above, should be 0x%2.2X */\n",
94             Checksum);
95     }
96 
97     /* The RSDP for ACPI 2.0+ contains more data and has a Length field */
98 
99     if (Rsdp->Revision > 0)
100     {
101         Length = Rsdp->Length;
102         AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp2);
103 
104         /* Validate the extended checksum over entire RSDP */
105 
106         Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_TABLE_RSDP),
107                     Rsdp->ExtendedChecksum);
108         if (Checksum != Rsdp->ExtendedChecksum)
109         {
110             AcpiOsPrintf (
111                 "/* Incorrect Extended Checksum above, should be 0x%2.2X */\n",
112                 Checksum);
113         }
114     }
115 
116     return (Length);
117 }
118 
119 
120 /*******************************************************************************
121  *
122  * FUNCTION:    AcpiDmDumpRsdt
123  *
124  * PARAMETERS:  Table               - A RSDT
125  *
126  * RETURN:      None
127  *
128  * DESCRIPTION: Format the contents of a RSDT
129  *
130  ******************************************************************************/
131 
132 void
133 AcpiDmDumpRsdt (
134     ACPI_TABLE_HEADER       *Table)
135 {
136     UINT32                  *Array;
137     UINT32                  Entries;
138     UINT32                  Offset;
139     UINT32                  i;
140 
141 
142     /* Point to start of table pointer array */
143 
144     Array = ACPI_CAST_PTR (ACPI_TABLE_RSDT, Table)->TableOffsetEntry;
145     Offset = sizeof (ACPI_TABLE_HEADER);
146 
147     /* RSDT uses 32-bit pointers */
148 
149     Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT32);
150 
151     for (i = 0; i < Entries; i++)
152     {
153         AcpiDmLineHeader2 (Offset, sizeof (UINT32), "ACPI Table Address", i);
154         AcpiOsPrintf ("%8.8X\n", Array[i]);
155         Offset += sizeof (UINT32);
156     }
157 }
158 
159 
160 /*******************************************************************************
161  *
162  * FUNCTION:    AcpiDmDumpXsdt
163  *
164  * PARAMETERS:  Table               - A XSDT
165  *
166  * RETURN:      None
167  *
168  * DESCRIPTION: Format the contents of a XSDT
169  *
170  ******************************************************************************/
171 
172 void
173 AcpiDmDumpXsdt (
174     ACPI_TABLE_HEADER       *Table)
175 {
176     UINT64                  *Array;
177     UINT32                  Entries;
178     UINT32                  Offset;
179     UINT32                  i;
180 
181 
182     /* Point to start of table pointer array */
183 
184     Array = ACPI_CAST_PTR (ACPI_TABLE_XSDT, Table)->TableOffsetEntry;
185     Offset = sizeof (ACPI_TABLE_HEADER);
186 
187     /* XSDT uses 64-bit pointers */
188 
189     Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT64);
190 
191     for (i = 0; i < Entries; i++)
192     {
193         AcpiDmLineHeader2 (Offset, sizeof (UINT64), "ACPI Table Address", i);
194         AcpiOsPrintf ("%8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Array[i]));
195         Offset += sizeof (UINT64);
196     }
197 }
198 
199 
200 /*******************************************************************************
201  *
202  * FUNCTION:    AcpiDmDumpFadt
203  *
204  * PARAMETERS:  Table               - A FADT
205  *
206  * RETURN:      None
207  *
208  * DESCRIPTION: Format the contents of a FADT
209  *
210  * NOTE:        We cannot depend on the FADT version to indicate the actual
211  *              contents of the FADT because of BIOS bugs. The table length
212  *              is the only reliable indicator.
213  *
214  ******************************************************************************/
215 
216 void
217 AcpiDmDumpFadt (
218     ACPI_TABLE_HEADER       *Table)
219 {
220 
221     /* Always dump the minimum FADT revision 1 fields (ACPI 1.0) */
222 
223     AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt1);
224 
225     /* Check for FADT revision 2 fields (ACPI 1.0B MS extensions) */
226 
227     if ((Table->Length > ACPI_FADT_V1_SIZE) &&
228         (Table->Length <= ACPI_FADT_V2_SIZE))
229     {
230         AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt2);
231     }
232 
233     /* Check for FADT revision 3 fields and up (ACPI 2.0+ extended data) */
234 
235     else if (Table->Length > ACPI_FADT_V2_SIZE)
236     {
237         AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt3);
238     }
239 
240     /* Validate various fields in the FADT, including length */
241 
242     AcpiTbCreateLocalFadt (Table, Table->Length);
243 
244     /* Validate FADT length against the revision */
245 
246     AcpiDmValidateFadtLength (Table->Revision, Table->Length);
247 }
248 
249 
250 /*******************************************************************************
251  *
252  * FUNCTION:    AcpiDmValidateFadtLength
253  *
254  * PARAMETERS:  Revision            - FADT revision (Header->Revision)
255  *              Length              - FADT length (Header->Length
256  *
257  * RETURN:      None
258  *
259  * DESCRIPTION: Check the FADT revision against the expected table length for
260  *              that revision. Issue a warning if the length is not what was
261  *              expected. This seems to be such a common BIOS bug that the
262  *              FADT revision has been rendered virtually meaningless.
263  *
264  ******************************************************************************/
265 
266 static void
267 AcpiDmValidateFadtLength (
268     UINT32                  Revision,
269     UINT32                  Length)
270 {
271     UINT32                  ExpectedLength;
272 
273 
274     switch (Revision)
275     {
276     case 0:
277         AcpiOsPrintf ("// ACPI Warning: Invalid FADT revision: 0\n");
278         return;
279 
280     case 1:
281         ExpectedLength = ACPI_FADT_V1_SIZE;
282         break;
283 
284     case 2:
285         ExpectedLength = ACPI_FADT_V2_SIZE;
286         break;
287 
288     case 3:
289     case 4:
290         ExpectedLength = ACPI_FADT_V3_SIZE;
291         break;
292 
293     default:
294         return;
295     }
296 
297     if (Length == ExpectedLength)
298     {
299         return;
300     }
301 
302     AcpiOsPrintf (
303         "\n// ACPI Warning: FADT revision %X does not match length: found %X expected %X\n",
304         Revision, Length, ExpectedLength);
305 }
306 
307 
308 /*******************************************************************************
309  *
310  * FUNCTION:    AcpiDmDumpAsf
311  *
312  * PARAMETERS:  Table               - A ASF table
313  *
314  * RETURN:      None
315  *
316  * DESCRIPTION: Format the contents of a ASF table
317  *
318  ******************************************************************************/
319 
320 void
321 AcpiDmDumpAsf (
322     ACPI_TABLE_HEADER       *Table)
323 {
324     ACPI_STATUS             Status;
325     UINT32                  Offset = sizeof (ACPI_TABLE_HEADER);
326     ACPI_ASF_INFO           *SubTable;
327     ACPI_DMTABLE_INFO       *InfoTable;
328     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
329     UINT8                   *DataTable = NULL;
330     UINT32                  DataCount = 0;
331     UINT32                  DataLength = 0;
332     UINT32                  DataOffset = 0;
333     UINT32                  i;
334     UINT8                   Type;
335 
336 
337     /* No main table, only sub-tables */
338 
339     SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
340     while (Offset < Table->Length)
341     {
342         /* Common sub-table header */
343 
344         Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
345                     SubTable->Header.Length, AcpiDmTableInfoAsfHdr);
346         if (ACPI_FAILURE (Status))
347         {
348             return;
349         }
350 
351         /* The actual type is the lower 7 bits of Type */
352 
353         Type = (UINT8) (SubTable->Header.Type & 0x7F);
354 
355         switch (Type)
356         {
357         case ACPI_ASF_TYPE_INFO:
358             InfoTable = AcpiDmTableInfoAsf0;
359             break;
360 
361         case ACPI_ASF_TYPE_ALERT:
362             InfoTable = AcpiDmTableInfoAsf1;
363             DataInfoTable = AcpiDmTableInfoAsf1a;
364             DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ALERT));
365             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->Alerts;
366             DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->DataLength;
367             DataOffset = Offset + sizeof (ACPI_ASF_ALERT);
368             break;
369 
370         case ACPI_ASF_TYPE_CONTROL:
371             InfoTable = AcpiDmTableInfoAsf2;
372             DataInfoTable = AcpiDmTableInfoAsf2a;
373             DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_REMOTE));
374             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->Controls;
375             DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->DataLength;
376             DataOffset = Offset + sizeof (ACPI_ASF_REMOTE);
377             break;
378 
379         case ACPI_ASF_TYPE_BOOT:
380             InfoTable = AcpiDmTableInfoAsf3;
381             break;
382 
383         case ACPI_ASF_TYPE_ADDRESS:
384             InfoTable = AcpiDmTableInfoAsf4;
385             DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ADDRESS));
386             DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, SubTable)->Devices;
387             DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS);
388             break;
389 
390         default:
391             AcpiOsPrintf ("\n**** Unknown ASF sub-table type 0x%X\n", SubTable->Header.Type);
392             return;
393         }
394 
395         Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
396                     SubTable->Header.Length, InfoTable);
397         if (ACPI_FAILURE (Status))
398         {
399             return;
400         }
401 
402         /* Dump variable-length extra data */
403 
404         switch (Type)
405         {
406         case ACPI_ASF_TYPE_ALERT:
407         case ACPI_ASF_TYPE_CONTROL:
408 
409             for (i = 0; i < DataCount; i++)
410             {
411                 AcpiOsPrintf ("\n");
412                 Status = AcpiDmDumpTable (Table->Length, DataOffset,
413                             DataTable, DataLength, DataInfoTable);
414                 if (ACPI_FAILURE (Status))
415                 {
416                     return;
417                 }
418 
419                 DataTable = ACPI_ADD_PTR (UINT8, DataTable, DataLength);
420                 DataOffset += DataLength;
421             }
422             break;
423 
424         case ACPI_ASF_TYPE_ADDRESS:
425 
426             for (i = 0; i < DataLength; i++)
427             {
428                 if (!(i % 16))
429                 {
430                     AcpiDmLineHeader (DataOffset, 1, "Addresses");
431                 }
432 
433                 AcpiOsPrintf ("%2.2X ", *DataTable);
434                 DataTable++;
435                 DataOffset++;
436                 if (DataOffset > Table->Length)
437                 {
438                     AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
439                     return;
440                 }
441             }
442 
443             AcpiOsPrintf ("\n");
444             break;
445 
446         default:
447             break;
448         }
449 
450         AcpiOsPrintf ("\n");
451 
452         /* Point to next sub-table */
453 
454         if (!SubTable->Header.Length)
455         {
456             AcpiOsPrintf ("Invalid zero subtable header length\n");
457             return;
458         }
459 
460         Offset += SubTable->Header.Length;
461         SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, SubTable, SubTable->Header.Length);
462     }
463 }
464 
465 
466 /*******************************************************************************
467  *
468  * FUNCTION:    AcpiDmDumpCpep
469  *
470  * PARAMETERS:  Table               - A CPEP table
471  *
472  * RETURN:      None
473  *
474  * DESCRIPTION: Format the contents of a CPEP. This table type consists
475  *              of an open-ended number of subtables.
476  *
477  ******************************************************************************/
478 
479 void
480 AcpiDmDumpCpep (
481     ACPI_TABLE_HEADER       *Table)
482 {
483     ACPI_STATUS             Status;
484     ACPI_CPEP_POLLING       *SubTable;
485     UINT32                  Length = Table->Length;
486     UINT32                  Offset = sizeof (ACPI_TABLE_CPEP);
487 
488 
489     /* Main table */
490 
491     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoCpep);
492     if (ACPI_FAILURE (Status))
493     {
494         return;
495     }
496 
497     /* Sub-tables */
498 
499     SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
500     while (Offset < Table->Length)
501     {
502         AcpiOsPrintf ("\n");
503         Status = AcpiDmDumpTable (Length, Offset, SubTable,
504                     SubTable->Header.Length, AcpiDmTableInfoCpep0);
505         if (ACPI_FAILURE (Status))
506         {
507             return;
508         }
509 
510         /* Point to next sub-table */
511 
512         Offset += SubTable->Header.Length;
513         SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, SubTable,
514                     SubTable->Header.Length);
515     }
516 }
517 
518 
519 /*******************************************************************************
520  *
521  * FUNCTION:    AcpiDmDumpDmar
522  *
523  * PARAMETERS:  Table               - A DMAR table
524  *
525  * RETURN:      None
526  *
527  * DESCRIPTION: Format the contents of a DMAR. This table type consists
528  *              of an open-ended number of subtables.
529  *
530  ******************************************************************************/
531 
532 void
533 AcpiDmDumpDmar (
534     ACPI_TABLE_HEADER       *Table)
535 {
536     ACPI_STATUS             Status;
537     ACPI_DMAR_HEADER        *SubTable;
538     UINT32                  Length = Table->Length;
539     UINT32                  Offset = sizeof (ACPI_TABLE_DMAR);
540     ACPI_DMTABLE_INFO       *InfoTable;
541     ACPI_DMAR_DEVICE_SCOPE  *ScopeTable;
542     UINT32                  ScopeOffset;
543     UINT8                   *PciPath;
544     UINT32                  PathOffset;
545 
546 
547     /* Main table */
548 
549     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar);
550     if (ACPI_FAILURE (Status))
551     {
552         return;
553     }
554 
555     /* Sub-tables */
556 
557     SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
558     while (Offset < Table->Length)
559     {
560         /* Common sub-table header */
561 
562         AcpiOsPrintf ("\n");
563         Status = AcpiDmDumpTable (Length, Offset, SubTable,
564                     SubTable->Length, AcpiDmTableInfoDmarHdr);
565         if (ACPI_FAILURE (Status))
566         {
567             return;
568         }
569 
570         switch (SubTable->Type)
571         {
572         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
573             InfoTable = AcpiDmTableInfoDmar0;
574             ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT);
575             break;
576         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
577             InfoTable = AcpiDmTableInfoDmar1;
578             ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY);
579             break;
580         case ACPI_DMAR_TYPE_ATSR:
581             InfoTable = AcpiDmTableInfoDmar2;
582             ScopeOffset = sizeof (ACPI_DMAR_ATSR);
583             break;
584         case ACPI_DMAR_HARDWARE_AFFINITY:
585             InfoTable = AcpiDmTableInfoDmar3;
586             ScopeOffset = sizeof (ACPI_DMAR_RHSA);
587             break;
588         default:
589             AcpiOsPrintf ("\n**** Unknown DMAR sub-table type 0x%X\n\n", SubTable->Type);
590             return;
591         }
592 
593         Status = AcpiDmDumpTable (Length, Offset, SubTable,
594                     SubTable->Length, InfoTable);
595         if (ACPI_FAILURE (Status))
596         {
597             return;
598         }
599 
600         /* Dump the device scope entries (if any) */
601 
602         ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, SubTable, ScopeOffset);
603         while (ScopeOffset < SubTable->Length)
604         {
605             AcpiOsPrintf ("\n");
606             Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
607                         ScopeTable->Length, AcpiDmTableInfoDmarScope);
608             if (ACPI_FAILURE (Status))
609             {
610                 return;
611             }
612 
613             /* Dump the PCI Path entries for this device scope */
614 
615             PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */
616 
617             PciPath = ACPI_ADD_PTR (UINT8, ScopeTable,
618                 sizeof (ACPI_DMAR_DEVICE_SCOPE));
619 
620             while (PathOffset < ScopeTable->Length)
621             {
622                 AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2, "PCI Path");
623                 AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]);
624 
625                 /* Point to next PCI Path entry */
626 
627                 PathOffset += 2;
628                 PciPath += 2;
629             }
630 
631             /* Point to next device scope entry */
632 
633             ScopeOffset += ScopeTable->Length;
634             ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE,
635                 ScopeTable, ScopeTable->Length);
636         }
637 
638         /* Point to next sub-table */
639 
640         Offset += SubTable->Length;
641         SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, SubTable, SubTable->Length);
642     }
643 }
644 
645 
646 /*******************************************************************************
647  *
648  * FUNCTION:    AcpiDmDumpEinj
649  *
650  * PARAMETERS:  Table               - A EINJ table
651  *
652  * RETURN:      None
653  *
654  * DESCRIPTION: Format the contents of a EINJ. This table type consists
655  *              of an open-ended number of subtables.
656  *
657  ******************************************************************************/
658 
659 void
660 AcpiDmDumpEinj (
661     ACPI_TABLE_HEADER       *Table)
662 {
663     ACPI_STATUS             Status;
664     ACPI_WHEA_HEADER        *SubTable;
665     UINT32                  Length = Table->Length;
666     UINT32                  Offset = sizeof (ACPI_TABLE_EINJ);
667 
668 
669     /* Main table */
670 
671     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj);
672     if (ACPI_FAILURE (Status))
673     {
674         return;
675     }
676 
677     /* Sub-tables */
678 
679     SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
680     while (Offset < Table->Length)
681     {
682         AcpiOsPrintf ("\n");
683         Status = AcpiDmDumpTable (Length, Offset, SubTable,
684                     sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
685         if (ACPI_FAILURE (Status))
686         {
687             return;
688         }
689 
690         /* Point to next sub-table (each subtable is of fixed length) */
691 
692         Offset += sizeof (ACPI_WHEA_HEADER);
693         SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
694                         sizeof (ACPI_WHEA_HEADER));
695     }
696 }
697 
698 
699 /*******************************************************************************
700  *
701  * FUNCTION:    AcpiDmDumpErst
702  *
703  * PARAMETERS:  Table               - A ERST table
704  *
705  * RETURN:      None
706  *
707  * DESCRIPTION: Format the contents of a ERST. This table type consists
708  *              of an open-ended number of subtables.
709  *
710  ******************************************************************************/
711 
712 void
713 AcpiDmDumpErst (
714     ACPI_TABLE_HEADER       *Table)
715 {
716     ACPI_STATUS             Status;
717     ACPI_WHEA_HEADER        *SubTable;
718     UINT32                  Length = Table->Length;
719     UINT32                  Offset = sizeof (ACPI_TABLE_ERST);
720 
721 
722     /* Main table */
723 
724     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst);
725     if (ACPI_FAILURE (Status))
726     {
727         return;
728     }
729 
730     /* Sub-tables */
731 
732     SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
733     while (Offset < Table->Length)
734     {
735         AcpiOsPrintf ("\n");
736         Status = AcpiDmDumpTable (Length, Offset, SubTable,
737                     sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
738         if (ACPI_FAILURE (Status))
739         {
740             return;
741         }
742 
743         /* Point to next sub-table (each subtable is of fixed length) */
744 
745         Offset += sizeof (ACPI_WHEA_HEADER);
746         SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
747                         sizeof (ACPI_WHEA_HEADER));
748     }
749 }
750 
751 
752 /*******************************************************************************
753  *
754  * FUNCTION:    AcpiDmDumpHest
755  *
756  * PARAMETERS:  Table               - A HEST table
757  *
758  * RETURN:      None
759  *
760  * DESCRIPTION: Format the contents of a HEST. This table type consists
761  *              of an open-ended number of subtables.
762  *
763  ******************************************************************************/
764 
765 void
766 AcpiDmDumpHest (
767     ACPI_TABLE_HEADER       *Table)
768 {
769     ACPI_STATUS             Status;
770     ACPI_HEST_HEADER        *SubTable;
771     UINT32                  Length = Table->Length;
772     UINT32                  Offset = sizeof (ACPI_TABLE_HEST);
773     ACPI_DMTABLE_INFO       *InfoTable;
774     UINT32                  SubTableLength;
775     UINT32                  BankCount;
776     ACPI_HEST_IA_ERROR_BANK *BankTable;
777 
778 
779     /* Main table */
780 
781     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest);
782     if (ACPI_FAILURE (Status))
783     {
784         return;
785     }
786 
787     /* Sub-tables */
788 
789     SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
790     while (Offset < Table->Length)
791     {
792         BankCount = 0;
793         switch (SubTable->Type)
794         {
795         case ACPI_HEST_TYPE_IA32_CHECK:
796             InfoTable = AcpiDmTableInfoHest0;
797             SubTableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
798             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
799                             SubTable))->NumHardwareBanks;
800             break;
801 
802         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
803             InfoTable = AcpiDmTableInfoHest1;
804             SubTableLength = sizeof (ACPI_HEST_IA_CORRECTED);
805             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
806                             SubTable))->NumHardwareBanks;
807             break;
808 
809         case ACPI_HEST_TYPE_IA32_NMI:
810             InfoTable = AcpiDmTableInfoHest2;
811             SubTableLength = sizeof (ACPI_HEST_IA_NMI);
812             break;
813 
814         case ACPI_HEST_TYPE_AER_ROOT_PORT:
815             InfoTable = AcpiDmTableInfoHest6;
816             SubTableLength = sizeof (ACPI_HEST_AER_ROOT);
817             break;
818 
819         case ACPI_HEST_TYPE_AER_ENDPOINT:
820             InfoTable = AcpiDmTableInfoHest7;
821             SubTableLength = sizeof (ACPI_HEST_AER);
822             break;
823 
824         case ACPI_HEST_TYPE_AER_BRIDGE:
825             InfoTable = AcpiDmTableInfoHest8;
826             SubTableLength = sizeof (ACPI_HEST_AER_BRIDGE);
827             break;
828 
829         case ACPI_HEST_TYPE_GENERIC_ERROR:
830             InfoTable = AcpiDmTableInfoHest9;
831             SubTableLength = sizeof (ACPI_HEST_GENERIC);
832             break;
833 
834         default:
835             /* Cannot continue on unknown type - no length */
836 
837             AcpiOsPrintf ("\n**** Unknown HEST sub-table type 0x%X\n", SubTable->Type);
838             return;
839         }
840 
841         AcpiOsPrintf ("\n");
842         Status = AcpiDmDumpTable (Length, Offset, SubTable,
843                     SubTableLength, InfoTable);
844         if (ACPI_FAILURE (Status))
845         {
846             return;
847         }
848 
849         /* Point to end of current subtable (each subtable above is of fixed length) */
850 
851         Offset += SubTableLength;
852 
853         /* If there are any (fixed-length) Error Banks from above, dump them now */
854 
855         if (BankCount)
856         {
857             BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, SubTable, SubTableLength);
858             SubTableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
859 
860             while (BankCount)
861             {
862                 AcpiOsPrintf ("\n");
863                 Status = AcpiDmDumpTable (Length, Offset, BankTable,
864                             sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank);
865                 if (ACPI_FAILURE (Status))
866                 {
867                     return;
868                 }
869                 Offset += sizeof (ACPI_HEST_IA_ERROR_BANK);
870                 BankTable++;
871                 BankCount--;
872             }
873         }
874 
875         /* Point to next sub-table */
876 
877         SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, SubTable, SubTableLength);
878     }
879 }
880 
881 
882 /*******************************************************************************
883  *
884  * FUNCTION:    AcpiDmDumpIvrs
885  *
886  * PARAMETERS:  Table               - A IVRS table
887  *
888  * RETURN:      None
889  *
890  * DESCRIPTION: Format the contents of a IVRS
891  *
892  ******************************************************************************/
893 
894 static UINT8 EntrySizes[] = {4,8,16,32};
895 
896 void
897 AcpiDmDumpIvrs (
898     ACPI_TABLE_HEADER       *Table)
899 {
900     ACPI_STATUS             Status;
901     UINT32                  Offset = sizeof (ACPI_TABLE_IVRS);
902     UINT32                  EntryOffset;
903     UINT32                  EntryLength;
904     UINT32                  EntryType;
905     ACPI_IVRS_DE_HEADER     *DeviceEntry;
906     ACPI_IVRS_HEADER        *SubTable;
907     ACPI_DMTABLE_INFO       *InfoTable;
908 
909 
910     /* Main table */
911 
912     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs);
913     if (ACPI_FAILURE (Status))
914     {
915         return;
916     }
917 
918     /* Sub-tables */
919 
920     SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
921     while (Offset < Table->Length)
922     {
923         /* Common sub-table header */
924 
925         AcpiOsPrintf ("\n");
926         Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
927                     SubTable->Length, AcpiDmTableInfoIvrsHdr);
928         if (ACPI_FAILURE (Status))
929         {
930             return;
931         }
932 
933         switch (SubTable->Type)
934         {
935         case ACPI_IVRS_TYPE_HARDWARE:
936             InfoTable = AcpiDmTableInfoIvrs0;
937             break;
938         case ACPI_IVRS_TYPE_MEMORY1:
939         case ACPI_IVRS_TYPE_MEMORY2:
940         case ACPI_IVRS_TYPE_MEMORY3:
941             InfoTable = AcpiDmTableInfoIvrs1;
942             break;
943         default:
944             AcpiOsPrintf ("\n**** Unknown IVRS sub-table type 0x%X\n",
945                 SubTable->Type);
946 
947             /* Attempt to continue */
948 
949             if (!SubTable->Length)
950             {
951                 AcpiOsPrintf ("Invalid zero length subtable\n");
952                 return;
953             }
954             goto NextSubTable;
955         }
956 
957         /* Dump the subtable */
958 
959         AcpiOsPrintf ("\n");
960         Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
961                     SubTable->Length, InfoTable);
962         if (ACPI_FAILURE (Status))
963         {
964             return;
965         }
966 
967         /* The hardware subtable can contain multiple device entries */
968 
969         if (SubTable->Type == ACPI_IVRS_TYPE_HARDWARE)
970         {
971             EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE);
972             DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, SubTable,
973                             sizeof (ACPI_IVRS_HARDWARE));
974 
975             while (EntryOffset < (Offset + SubTable->Length))
976             {
977                 AcpiOsPrintf ("\n");
978                 /*
979                  * Upper 2 bits of Type encode the length of the device entry
980                  *
981                  * 00 = 4 byte
982                  * 01 = 8 byte
983                  * 10 = 16 byte - currently no entries defined
984                  * 11 = 32 byte - currently no entries defined
985                  */
986                 EntryType = DeviceEntry->Type;
987                 EntryLength = EntrySizes [EntryType >> 6];
988 
989                 switch (EntryType)
990                 {
991                 /* 4-byte device entries */
992 
993                 case ACPI_IVRS_TYPE_PAD4:
994                 case ACPI_IVRS_TYPE_ALL:
995                 case ACPI_IVRS_TYPE_SELECT:
996                 case ACPI_IVRS_TYPE_START:
997                 case ACPI_IVRS_TYPE_END:
998 
999                     InfoTable = AcpiDmTableInfoIvrs4;
1000                     break;
1001 
1002                 /* 8-byte entries, type A */
1003 
1004                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1005                 case ACPI_IVRS_TYPE_ALIAS_START:
1006 
1007                     InfoTable = AcpiDmTableInfoIvrs8a;
1008                     break;
1009 
1010                 /* 8-byte entries, type B */
1011 
1012                 case ACPI_IVRS_TYPE_PAD8:
1013                 case ACPI_IVRS_TYPE_EXT_SELECT:
1014                 case ACPI_IVRS_TYPE_EXT_START:
1015 
1016                     InfoTable = AcpiDmTableInfoIvrs8b;
1017                     break;
1018 
1019                 /* 8-byte entries, type C */
1020 
1021                 case ACPI_IVRS_TYPE_SPECIAL:
1022 
1023                     InfoTable = AcpiDmTableInfoIvrs8c;
1024                     break;
1025 
1026                 default:
1027                     InfoTable = AcpiDmTableInfoIvrs4;
1028                     AcpiOsPrintf (
1029                         "\n**** Unknown IVRS device entry type/length: "
1030                         "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
1031                         EntryType, EntryLength, EntryOffset);
1032                     break;
1033                 }
1034 
1035                 /* Dump the Device Entry */
1036 
1037                 Status = AcpiDmDumpTable (Table->Length, EntryOffset,
1038                             DeviceEntry, EntryLength, InfoTable);
1039 
1040                 EntryOffset += EntryLength;
1041                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, DeviceEntry,
1042                                 EntryLength);
1043             }
1044         }
1045 
1046 NextSubTable:
1047         /* Point to next sub-table */
1048 
1049         Offset += SubTable->Length;
1050         SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, SubTable, SubTable->Length);
1051     }
1052 }
1053 
1054 
1055 /*******************************************************************************
1056  *
1057  * FUNCTION:    AcpiDmDumpMadt
1058  *
1059  * PARAMETERS:  Table               - A MADT table
1060  *
1061  * RETURN:      None
1062  *
1063  * DESCRIPTION: Format the contents of a MADT. This table type consists
1064  *              of an open-ended number of subtables.
1065  *
1066  ******************************************************************************/
1067 
1068 void
1069 AcpiDmDumpMadt (
1070     ACPI_TABLE_HEADER       *Table)
1071 {
1072     ACPI_STATUS             Status;
1073     ACPI_SUBTABLE_HEADER    *SubTable;
1074     UINT32                  Length = Table->Length;
1075     UINT32                  Offset = sizeof (ACPI_TABLE_MADT);
1076     ACPI_DMTABLE_INFO       *InfoTable;
1077 
1078 
1079     /* Main table */
1080 
1081     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoMadt);
1082     if (ACPI_FAILURE (Status))
1083     {
1084         return;
1085     }
1086 
1087     /* Sub-tables */
1088 
1089     SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
1090     while (Offset < Table->Length)
1091     {
1092         /* Common sub-table header */
1093 
1094         AcpiOsPrintf ("\n");
1095         Status = AcpiDmDumpTable (Length, Offset, SubTable,
1096                     SubTable->Length, AcpiDmTableInfoMadtHdr);
1097         if (ACPI_FAILURE (Status))
1098         {
1099             return;
1100         }
1101 
1102         switch (SubTable->Type)
1103         {
1104         case ACPI_MADT_TYPE_LOCAL_APIC:
1105             InfoTable = AcpiDmTableInfoMadt0;
1106             break;
1107         case ACPI_MADT_TYPE_IO_APIC:
1108             InfoTable = AcpiDmTableInfoMadt1;
1109             break;
1110         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1111             InfoTable = AcpiDmTableInfoMadt2;
1112             break;
1113         case ACPI_MADT_TYPE_NMI_SOURCE:
1114             InfoTable = AcpiDmTableInfoMadt3;
1115             break;
1116         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1117             InfoTable = AcpiDmTableInfoMadt4;
1118             break;
1119         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1120             InfoTable = AcpiDmTableInfoMadt5;
1121             break;
1122         case ACPI_MADT_TYPE_IO_SAPIC:
1123             InfoTable = AcpiDmTableInfoMadt6;
1124             break;
1125         case ACPI_MADT_TYPE_LOCAL_SAPIC:
1126             InfoTable = AcpiDmTableInfoMadt7;
1127             break;
1128         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1129             InfoTable = AcpiDmTableInfoMadt8;
1130             break;
1131         case ACPI_MADT_TYPE_LOCAL_X2APIC:
1132             InfoTable = AcpiDmTableInfoMadt9;
1133             break;
1134         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1135             InfoTable = AcpiDmTableInfoMadt10;
1136             break;
1137         default:
1138             AcpiOsPrintf ("\n**** Unknown MADT sub-table type 0x%X\n\n", SubTable->Type);
1139 
1140             /* Attempt to continue */
1141 
1142             if (!SubTable->Length)
1143             {
1144                 AcpiOsPrintf ("Invalid zero length subtable\n");
1145                 return;
1146             }
1147             goto NextSubTable;
1148         }
1149 
1150         Status = AcpiDmDumpTable (Length, Offset, SubTable,
1151                     SubTable->Length, InfoTable);
1152         if (ACPI_FAILURE (Status))
1153         {
1154             return;
1155         }
1156 
1157 NextSubTable:
1158         /* Point to next sub-table */
1159 
1160         Offset += SubTable->Length;
1161         SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length);
1162     }
1163 }
1164 
1165 
1166 /*******************************************************************************
1167  *
1168  * FUNCTION:    AcpiDmDumpMcfg
1169  *
1170  * PARAMETERS:  Table               - A MCFG Table
1171  *
1172  * RETURN:      None
1173  *
1174  * DESCRIPTION: Format the contents of a MCFG table
1175  *
1176  ******************************************************************************/
1177 
1178 void
1179 AcpiDmDumpMcfg (
1180     ACPI_TABLE_HEADER       *Table)
1181 {
1182     ACPI_STATUS             Status;
1183     UINT32                  Offset = sizeof (ACPI_TABLE_MCFG);
1184     ACPI_MCFG_ALLOCATION    *SubTable;
1185 
1186 
1187     /* Main table */
1188 
1189     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMcfg);
1190     if (ACPI_FAILURE (Status))
1191     {
1192         return;
1193     }
1194 
1195     /* Sub-tables */
1196 
1197     SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
1198     while (Offset < Table->Length)
1199     {
1200         if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length)
1201         {
1202             AcpiOsPrintf ("Warning: there are %u invalid trailing bytes\n",
1203                 sizeof (ACPI_MCFG_ALLOCATION) - (Offset - Table->Length));
1204             return;
1205         }
1206 
1207         AcpiOsPrintf ("\n");
1208         Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1209                     sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0);
1210         if (ACPI_FAILURE (Status))
1211         {
1212             return;
1213         }
1214 
1215         /* Point to next sub-table (each subtable is of fixed length) */
1216 
1217         Offset += sizeof (ACPI_MCFG_ALLOCATION);
1218         SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, SubTable,
1219                         sizeof (ACPI_MCFG_ALLOCATION));
1220     }
1221 }
1222 
1223 
1224 /*******************************************************************************
1225  *
1226  * FUNCTION:    AcpiDmDumpMsct
1227  *
1228  * PARAMETERS:  Table               - A MSCT table
1229  *
1230  * RETURN:      None
1231  *
1232  * DESCRIPTION: Format the contents of a MSCT
1233  *
1234  ******************************************************************************/
1235 
1236 void
1237 AcpiDmDumpMsct (
1238     ACPI_TABLE_HEADER       *Table)
1239 {
1240     ACPI_STATUS             Status;
1241     UINT32                  Offset = sizeof (ACPI_TABLE_MSCT);
1242     ACPI_MSCT_PROXIMITY     *SubTable;
1243 
1244 
1245     /* Main table */
1246 
1247     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct);
1248     if (ACPI_FAILURE (Status))
1249     {
1250         return;
1251     }
1252 
1253     /* Sub-tables */
1254 
1255     SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
1256     while (Offset < Table->Length)
1257     {
1258         /* Common sub-table header */
1259 
1260         AcpiOsPrintf ("\n");
1261         Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1262                     sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0);
1263         if (ACPI_FAILURE (Status))
1264         {
1265             return;
1266         }
1267 
1268         /* Point to next sub-table */
1269 
1270         Offset += sizeof (ACPI_MSCT_PROXIMITY);
1271         SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, SubTable, sizeof (ACPI_MSCT_PROXIMITY));
1272     }
1273 }
1274 
1275 
1276 /*******************************************************************************
1277  *
1278  * FUNCTION:    AcpiDmDumpSlit
1279  *
1280  * PARAMETERS:  Table               - An SLIT
1281  *
1282  * RETURN:      None
1283  *
1284  * DESCRIPTION: Format the contents of a SLIT
1285  *
1286  ******************************************************************************/
1287 
1288 void
1289 AcpiDmDumpSlit (
1290     ACPI_TABLE_HEADER       *Table)
1291 {
1292     ACPI_STATUS             Status;
1293     UINT32                  Offset;
1294     UINT8                   *Row;
1295     UINT32                  Localities;
1296     UINT32                  i;
1297     UINT32                  j;
1298 
1299 
1300     /* Main table */
1301 
1302     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSlit);
1303     if (ACPI_FAILURE (Status))
1304     {
1305         return;
1306     }
1307 
1308     /* Display the Locality NxN Matrix */
1309 
1310     Localities = (UINT32) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->LocalityCount;
1311     Offset = ACPI_OFFSET (ACPI_TABLE_SLIT, Entry[0]);
1312     Row = (UINT8 *) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->Entry;
1313 
1314     for (i = 0; i < Localities; i++)
1315     {
1316         /* Display one row of the matrix */
1317 
1318         AcpiDmLineHeader2 (Offset, Localities, "Locality", i);
1319         for  (j = 0; j < Localities; j++)
1320         {
1321             /* Check for beyond EOT */
1322 
1323             if (Offset >= Table->Length)
1324             {
1325                 AcpiOsPrintf ("\n**** Not enough room in table for all localities\n");
1326                 return;
1327             }
1328 
1329             AcpiOsPrintf ("%2.2X", Row[j]);
1330             Offset++;
1331 
1332             /* Display up to 16 bytes per output row */
1333 
1334             if ((j+1) < Localities)
1335             {
1336                 AcpiOsPrintf (",");
1337 
1338                 if (j && (((j+1) % 16) == 0))
1339                 {
1340                     AcpiOsPrintf ("\n");
1341                     AcpiDmLineHeader (Offset, 0, "");
1342                 }
1343             }
1344         }
1345 
1346         /* Point to next row */
1347 
1348         AcpiOsPrintf ("\n");
1349         Row += Localities;
1350     }
1351 }
1352 
1353 
1354 /*******************************************************************************
1355  *
1356  * FUNCTION:    AcpiDmDumpSrat
1357  *
1358  * PARAMETERS:  Table               - A SRAT table
1359  *
1360  * RETURN:      None
1361  *
1362  * DESCRIPTION: Format the contents of a SRAT
1363  *
1364  ******************************************************************************/
1365 
1366 void
1367 AcpiDmDumpSrat (
1368     ACPI_TABLE_HEADER       *Table)
1369 {
1370     ACPI_STATUS             Status;
1371     UINT32                  Offset = sizeof (ACPI_TABLE_SRAT);
1372     ACPI_SUBTABLE_HEADER    *SubTable;
1373     ACPI_DMTABLE_INFO       *InfoTable;
1374 
1375 
1376     /* Main table */
1377 
1378     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSrat);
1379     if (ACPI_FAILURE (Status))
1380     {
1381         return;
1382     }
1383 
1384     /* Sub-tables */
1385 
1386     SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
1387     while (Offset < Table->Length)
1388     {
1389         /* Common sub-table header */
1390 
1391         AcpiOsPrintf ("\n");
1392         Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1393                     SubTable->Length, AcpiDmTableInfoSratHdr);
1394         if (ACPI_FAILURE (Status))
1395         {
1396             return;
1397         }
1398 
1399         switch (SubTable->Type)
1400         {
1401         case ACPI_SRAT_TYPE_CPU_AFFINITY:
1402             InfoTable = AcpiDmTableInfoSrat0;
1403             break;
1404         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1405             InfoTable = AcpiDmTableInfoSrat1;
1406             break;
1407         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1408             InfoTable = AcpiDmTableInfoSrat2;
1409             break;
1410         default:
1411             AcpiOsPrintf ("\n**** Unknown SRAT sub-table type 0x%X\n", SubTable->Type);
1412 
1413             /* Attempt to continue */
1414 
1415             if (!SubTable->Length)
1416             {
1417                 AcpiOsPrintf ("Invalid zero length subtable\n");
1418                 return;
1419             }
1420             goto NextSubTable;
1421         }
1422 
1423         AcpiOsPrintf ("\n");
1424         Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1425                     SubTable->Length, InfoTable);
1426         if (ACPI_FAILURE (Status))
1427         {
1428             return;
1429         }
1430 
1431 NextSubTable:
1432         /* Point to next sub-table */
1433 
1434         Offset += SubTable->Length;
1435         SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length);
1436     }
1437 }
1438 
1439 
1440 /*******************************************************************************
1441  *
1442  * FUNCTION:    AcpiDmDumpWdat
1443  *
1444  * PARAMETERS:  Table               - A WDAT table
1445  *
1446  * RETURN:      None
1447  *
1448  * DESCRIPTION: Format the contents of a WDAT
1449  *
1450  ******************************************************************************/
1451 
1452 void
1453 AcpiDmDumpWdat (
1454     ACPI_TABLE_HEADER       *Table)
1455 {
1456     ACPI_STATUS             Status;
1457     UINT32                  Offset = sizeof (ACPI_TABLE_WDAT);
1458     ACPI_WDAT_ENTRY         *SubTable;
1459 
1460 
1461     /* Main table */
1462 
1463     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoWdat);
1464     if (ACPI_FAILURE (Status))
1465     {
1466         return;
1467     }
1468 
1469     /* Sub-tables */
1470 
1471     SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset);
1472     while (Offset < Table->Length)
1473     {
1474         /* Common sub-table header */
1475 
1476         AcpiOsPrintf ("\n");
1477         Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
1478                     sizeof (ACPI_WDAT_ENTRY), AcpiDmTableInfoWdat0);
1479         if (ACPI_FAILURE (Status))
1480         {
1481             return;
1482         }
1483 
1484         /* Point to next sub-table */
1485 
1486         Offset += sizeof (ACPI_WDAT_ENTRY);
1487         SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, SubTable, sizeof (ACPI_WDAT_ENTRY));
1488     }
1489 }
1490