xref: /freebsd/sys/contrib/dev/acpica/common/dmtable.c (revision bd96183d5e5761c849e857005ebc4a5a818a0a99)
1 /******************************************************************************
2  *
3  * Module Name: dmtable - Support for ACPI tables that contain no AML code
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 #include <contrib/dev/acpica/include/acpi.h>
117 #include <contrib/dev/acpica/include/accommon.h>
118 #include <contrib/dev/acpica/include/acdisasm.h>
119 #include <contrib/dev/acpica/include/actables.h>
120 
121 /* This module used for application-level code only */
122 
123 #define _COMPONENT          ACPI_CA_DISASSEMBLER
124         ACPI_MODULE_NAME    ("dmtable")
125 
126 /* Local Prototypes */
127 
128 static ACPI_DMTABLE_DATA *
129 AcpiDmGetTableData (
130     char                    *Signature);
131 
132 static void
133 AcpiDmCheckAscii (
134     UINT8                   *Target,
135     char                    *RepairedName,
136     UINT32                  Count);
137 
138 UINT8
139 AcpiTbGenerateChecksum (
140     ACPI_TABLE_HEADER       *Table);
141 
142 
143 /* These tables map a subtable type to a description string */
144 
145 static const char           *AcpiDmAsfSubnames[] =
146 {
147     "ASF Information",
148     "ASF Alerts",
149     "ASF Remote Control",
150     "ASF RMCP Boot Options",
151     "ASF Address",
152     "Unknown SubTable Type"         /* Reserved */
153 };
154 
155 static const char           *AcpiDmDmarSubnames[] =
156 {
157     "Hardware Unit Definition",
158     "Reserved Memory Region",
159     "Root Port ATS Capability",
160     "Remapping Hardware Static Affinity",
161     "Unknown SubTable Type"         /* Reserved */
162 };
163 
164 static const char           *AcpiDmHestSubnames[] =
165 {
166     "IA-32 Machine Check Exception",
167     "IA-32 Corrected Machine Check",
168     "IA-32 Non-Maskable Interrupt",
169     "Unknown SubTable Type",        /* 3 - Reserved */
170     "Unknown SubTable Type",        /* 4 - Reserved */
171     "Unknown SubTable Type",        /* 5 - Reserved */
172     "PCI Express Root Port AER",
173     "PCI Express AER (AER Endpoint)",
174     "PCI Express/PCI-X Bridge AER",
175     "Generic Hardware Error Source",
176     "Unknown SubTable Type"         /* Reserved */
177 };
178 
179 static const char           *AcpiDmHestNotifySubnames[] =
180 {
181     "Polled",
182     "External Interrupt",
183     "Local Interrupt",
184     "SCI",
185     "NMI",
186     "Unknown Notify Type"           /* Reserved */
187 };
188 
189 static const char           *AcpiDmMadtSubnames[] =
190 {
191     "Processor Local APIC",         /* ACPI_MADT_TYPE_LOCAL_APIC */
192     "I/O APIC",                     /* ACPI_MADT_TYPE_IO_APIC */
193     "Interrupt Source Override",    /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */
194     "NMI Source",                   /* ACPI_MADT_TYPE_NMI_SOURCE */
195     "Local APIC NMI",               /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */
196     "Local APIC Address Override",  /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */
197     "I/O SAPIC",                    /* ACPI_MADT_TYPE_IO_SAPIC */
198     "Local SAPIC",                  /* ACPI_MADT_TYPE_LOCAL_SAPIC */
199     "Platform Interrupt Sources",   /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
200     "Processor Local x2APIC",       /* ACPI_MADT_TYPE_LOCAL_X2APIC */
201     "Local x2APIC NMI",             /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
202     "Unknown SubTable Type"         /* Reserved */
203 };
204 
205 static const char           *AcpiDmSratSubnames[] =
206 {
207     "Processor Local APIC/SAPIC Affinity",
208     "Memory Affinity",
209     "Processor Local x2APIC Affinity",
210     "Unknown SubTable Type"         /* Reserved */
211 };
212 
213 static const char           *AcpiDmIvrsSubnames[] =
214 {
215     "Hardware Definition Block",
216     "Memory Definition Block",
217     "Unknown SubTable Type"         /* Reserved */
218 };
219 
220 
221 #define ACPI_FADT_PM_RESERVED       8
222 
223 static const char           *AcpiDmFadtProfiles[] =
224 {
225     "Unspecified",
226     "Desktop",
227     "Mobile",
228     "Workstation",
229     "Enterprise Server",
230     "SOHO Server",
231     "Appliance PC",
232     "Performance Server",
233     "Unknown Profile Type"
234 };
235 
236 /*******************************************************************************
237  *
238  * ACPI Table Data, indexed by signature.
239  *
240  * Each entry contains: Signature, Table Info, Handler, Description
241  *
242  * Simple tables have only a TableInfo structure, complex tables have a handler.
243  * This table must be NULL terminated. RSDP and FACS are special-cased
244  * elsewhere.
245  *
246  ******************************************************************************/
247 
248 static ACPI_DMTABLE_DATA    AcpiDmTableData[] =
249 {
250     {ACPI_SIG_ASF,  NULL,                   AcpiDmDumpAsf,  "Alert Standard Format table"},
251     {ACPI_SIG_BOOT, AcpiDmTableInfoBoot,    NULL,           "Simple Boot Flag Table"},
252     {ACPI_SIG_BERT, AcpiDmTableInfoBert,    NULL,           "Boot Error Record Table"},
253     {ACPI_SIG_CPEP, NULL,                   AcpiDmDumpCpep, "Corrected Platform Error Polling table"},
254     {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp,    NULL,           "Debug Port table"},
255     {ACPI_SIG_DMAR, NULL,                   AcpiDmDumpDmar, "DMA Remapping table"},
256     {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt,    NULL,           "Embedded Controller Boot Resources Table"},
257     {ACPI_SIG_EINJ, NULL,                   AcpiDmDumpEinj, "Error Injection table"},
258     {ACPI_SIG_ERST, NULL,                   AcpiDmDumpErst, "Error Record Serialization Table"},
259     {ACPI_SIG_FADT, NULL,                   AcpiDmDumpFadt, "Fixed ACPI Description Table"},
260     {ACPI_SIG_HEST, NULL,                   AcpiDmDumpHest, "Hardware Error Source Table"},
261     {ACPI_SIG_HPET, AcpiDmTableInfoHpet,    NULL,           "High Precision Event Timer table"},
262     {ACPI_SIG_IVRS, NULL,                   AcpiDmDumpIvrs, "I/O Virtualization Reporting Structure"},
263     {ACPI_SIG_MADT, NULL,                   AcpiDmDumpMadt, "Multiple APIC Description Table"},
264     {ACPI_SIG_MCFG, NULL,                   AcpiDmDumpMcfg, "Memory Mapped Configuration table"},
265     {ACPI_SIG_MSCT, NULL,                   AcpiDmDumpMsct, "Maximum System Characteristics Table"},
266     {ACPI_SIG_RSDT, NULL,                   AcpiDmDumpRsdt, "Root System Description Table"},
267     {ACPI_SIG_SBST, AcpiDmTableInfoSbst,    NULL,           "Smart Battery Specification Table"},
268     {ACPI_SIG_SLIC, AcpiDmTableInfoSlic,    NULL,           "Software Licensing Description Table"},
269     {ACPI_SIG_SLIT, NULL,                   AcpiDmDumpSlit, "System Locality Information Table"},
270     {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr,    NULL,           "Serial Port Console Redirection table"},
271     {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi,    NULL,           "Server Platform Management Interface table"},
272     {ACPI_SIG_SRAT, NULL,                   AcpiDmDumpSrat, "System Resource Affinity Table"},
273     {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa,    NULL,           "Trusted Computing Platform Alliance table"},
274     {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           "UEFI Boot Optimization Table"},
275     {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           "Windows ACPI Emulated Devices Table"},
276     {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, "Watchdog Action Table"},
277     {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           "Watchdog Resource Table"},
278     {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, "Extended System Description Table"},
279     {NULL,          NULL,                   NULL,           NULL}
280 };
281 
282 
283 /*******************************************************************************
284  *
285  * FUNCTION:    AcpiTbGenerateChecksum
286  *
287  * PARAMETERS:  Table               - Pointer to a valid ACPI table (with a
288  *                                    standard ACPI header)
289  *
290  * RETURN:      8 bit checksum of buffer
291  *
292  * DESCRIPTION: Computes an 8 bit checksum of the table.
293  *
294  ******************************************************************************/
295 
296 UINT8
297 AcpiTbGenerateChecksum (
298     ACPI_TABLE_HEADER       *Table)
299 {
300     UINT8                   Checksum;
301 
302 
303     /* Sum the entire table as-is */
304 
305     Checksum = AcpiTbChecksum ((UINT8 *) Table, Table->Length);
306 
307     /* Subtract off the existing checksum value in the table */
308 
309     Checksum = (UINT8) (Checksum - Table->Checksum);
310 
311     /* Compute the final checksum */
312 
313     Checksum = (UINT8) (0 - Checksum);
314     return (Checksum);
315 }
316 
317 
318 /*******************************************************************************
319  *
320  * FUNCTION:    AcpiDmGetTableData
321  *
322  * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
323  *
324  * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
325  *
326  * DESCRIPTION: Find a match in the global table of supported ACPI tables
327  *
328  ******************************************************************************/
329 
330 static ACPI_DMTABLE_DATA *
331 AcpiDmGetTableData (
332     char                    *Signature)
333 {
334     ACPI_DMTABLE_DATA       *TableData;
335 
336 
337     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
338     {
339         if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
340         {
341             return (TableData);
342         }
343     }
344 
345     return (NULL);
346 }
347 
348 
349 /*******************************************************************************
350  *
351  * FUNCTION:    AcpiDmDumpDataTable
352  *
353  * PARAMETERS:  Table               - An ACPI table
354  *
355  * RETURN:      None.
356  *
357  * DESCRIPTION: Format the contents of an ACPI data table (any table other
358  *              than an SSDT or DSDT that does not contain executable AML code)
359  *
360  ******************************************************************************/
361 
362 void
363 AcpiDmDumpDataTable (
364     ACPI_TABLE_HEADER       *Table)
365 {
366     ACPI_STATUS             Status;
367     ACPI_DMTABLE_DATA       *TableData;
368     UINT32                  Length;
369 
370 
371     /* Ignore tables that contain AML */
372 
373     if (AcpiUtIsAmlTable (Table))
374     {
375         return;
376     }
377 
378     /*
379      * Handle tables that don't use the common ACPI table header structure.
380      * Currently, these are the FACS and RSDP.
381      */
382     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
383     {
384         Length = Table->Length;
385         AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
386     }
387     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
388     {
389         Length = AcpiDmDumpRsdp (Table);
390     }
391     else
392     {
393         /*
394          * All other tables must use the common ACPI table header, dump it now
395          */
396         Length = Table->Length;
397         Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
398         if (ACPI_FAILURE (Status))
399         {
400             return;
401         }
402         AcpiOsPrintf ("\n");
403 
404         /* Match signature and dispatch appropriately */
405 
406         TableData = AcpiDmGetTableData (Table->Signature);
407         if (!TableData)
408         {
409             if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
410             {
411                 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
412                     Table->Signature);
413             }
414             else
415             {
416                 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
417                     Table->Signature);
418             }
419         }
420         else if (TableData->TableHandler)
421         {
422             /* Complex table, has a handler */
423 
424             TableData->TableHandler (Table);
425         }
426         else if (TableData->TableInfo)
427         {
428             /* Simple table, just walk the info table */
429 
430             AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
431         }
432     }
433 
434     /* Always dump the raw table data */
435 
436     AcpiOsPrintf ("\nRaw Table Data\n\n");
437     AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
438 }
439 
440 
441 /*******************************************************************************
442  *
443  * FUNCTION:    AcpiDmLineHeader
444  *
445  * PARAMETERS:  Offset              - Current byte offset, from table start
446  *              ByteLength          - Length of the field in bytes, 0 for flags
447  *              Name                - Name of this field
448  *              Value               - Optional value, displayed on left of ':'
449  *
450  * RETURN:      None
451  *
452  * DESCRIPTION: Utility routines for formatting output lines. Displays the
453  *              current table offset in hex and decimal, the field length,
454  *              and the field name.
455  *
456  ******************************************************************************/
457 
458 void
459 AcpiDmLineHeader (
460     UINT32                  Offset,
461     UINT32                  ByteLength,
462     char                    *Name)
463 {
464 
465     if (ByteLength)
466     {
467         AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %28s : ",
468             Offset, Offset, ByteLength, Name);
469     }
470     else
471     {
472         AcpiOsPrintf ("%43s : ",
473             Name);
474     }
475 }
476 
477 void
478 AcpiDmLineHeader2 (
479     UINT32                  Offset,
480     UINT32                  ByteLength,
481     char                    *Name,
482     UINT32                  Value)
483 {
484 
485     if (ByteLength)
486     {
487         AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %24s % 3d : ",
488             Offset, Offset, ByteLength, Name, Value);
489     }
490     else
491     {
492         AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s % 3d : ",
493             Offset, Offset, Name, Value);
494     }
495 }
496 
497 
498 /*******************************************************************************
499  *
500  * FUNCTION:    AcpiDmDumpTable
501  *
502  * PARAMETERS:  TableLength         - Length of the entire ACPI table
503  *              TableOffset         - Starting offset within the table for this
504  *                                    sub-descriptor (0 if main table)
505  *              Table               - The ACPI table
506  *              SubtableLength      - Length of this sub-descriptor
507  *              Info                - Info table for this ACPI table
508  *
509  * RETURN:      None
510  *
511  * DESCRIPTION: Display ACPI table contents by walking the Info table.
512  *
513  ******************************************************************************/
514 
515 ACPI_STATUS
516 AcpiDmDumpTable (
517     UINT32                  TableLength,
518     UINT32                  TableOffset,
519     void                    *Table,
520     UINT32                  SubtableLength,
521     ACPI_DMTABLE_INFO       *Info)
522 {
523     UINT8                   *Target;
524     UINT32                  CurrentOffset;
525     UINT32                  ByteLength;
526     UINT8                   Temp8;
527     UINT16                  Temp16;
528     ACPI_DMTABLE_DATA       *TableData;
529     const char              *Name;
530     BOOLEAN                 LastOutputBlankLine = FALSE;
531     char                    RepairedName[8];
532 
533 
534     if (!Info)
535     {
536         AcpiOsPrintf ("Display not implemented\n");
537         return (AE_NOT_IMPLEMENTED);
538     }
539 
540     /* Walk entire Info table; Null name terminates */
541 
542     for (; Info->Name; Info++)
543     {
544         /*
545          * Target points to the field within the ACPI Table. CurrentOffset is
546          * the offset of the field from the start of the main table.
547          */
548         Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
549         CurrentOffset = TableOffset + Info->Offset;
550 
551         /* Check for beyond EOT or beyond subtable end */
552 
553         if ((CurrentOffset >= TableLength) ||
554             (SubtableLength && (Info->Offset >= SubtableLength)))
555         {
556             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
557             return (AE_BAD_DATA);
558         }
559 
560         /* Generate the byte length for this field */
561 
562         switch (Info->Opcode)
563         {
564         case ACPI_DMT_UINT8:
565         case ACPI_DMT_CHKSUM:
566         case ACPI_DMT_SPACEID:
567         case ACPI_DMT_IVRS:
568         case ACPI_DMT_MADT:
569         case ACPI_DMT_SRAT:
570         case ACPI_DMT_ASF:
571         case ACPI_DMT_HESTNTYP:
572         case ACPI_DMT_FADTPM:
573             ByteLength = 1;
574             break;
575         case ACPI_DMT_UINT16:
576         case ACPI_DMT_DMAR:
577         case ACPI_DMT_HEST:
578             ByteLength = 2;
579             break;
580         case ACPI_DMT_UINT24:
581             ByteLength = 3;
582             break;
583         case ACPI_DMT_UINT32:
584         case ACPI_DMT_NAME4:
585         case ACPI_DMT_SIG:
586             ByteLength = 4;
587             break;
588         case ACPI_DMT_NAME6:
589             ByteLength = 6;
590             break;
591         case ACPI_DMT_UINT56:
592             ByteLength = 7;
593             break;
594         case ACPI_DMT_UINT64:
595         case ACPI_DMT_NAME8:
596             ByteLength = 8;
597             break;
598         case ACPI_DMT_BUF16:
599             ByteLength = 16;
600             break;
601         case ACPI_DMT_STRING:
602             ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
603             break;
604         case ACPI_DMT_GAS:
605             if (!LastOutputBlankLine)
606             {
607                 AcpiOsPrintf ("\n");
608                 LastOutputBlankLine = TRUE;
609             }
610             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
611             break;
612         case ACPI_DMT_HESTNTFY:
613             if (!LastOutputBlankLine)
614             {
615                 AcpiOsPrintf ("\n");
616                 LastOutputBlankLine = TRUE;
617             }
618             ByteLength = sizeof (ACPI_HEST_NOTIFY);
619             break;
620         default:
621             ByteLength = 0;
622             break;
623         }
624 
625         if (CurrentOffset + ByteLength > TableLength)
626         {
627             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
628             return (AE_BAD_DATA);
629         }
630 
631         /* Start a new line and decode the opcode */
632 
633         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
634 
635         switch (Info->Opcode)
636         {
637         /* Single-bit Flag fields. Note: Opcode is the bit position */
638 
639         case ACPI_DMT_FLAG0:
640         case ACPI_DMT_FLAG1:
641         case ACPI_DMT_FLAG2:
642         case ACPI_DMT_FLAG3:
643         case ACPI_DMT_FLAG4:
644         case ACPI_DMT_FLAG5:
645         case ACPI_DMT_FLAG6:
646         case ACPI_DMT_FLAG7:
647 
648             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
649             break;
650 
651         /* 2-bit Flag fields */
652 
653         case ACPI_DMT_FLAGS0:
654 
655             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
656             break;
657 
658         case ACPI_DMT_FLAGS2:
659 
660             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
661             break;
662 
663         /* Standard Data Types */
664 
665         case ACPI_DMT_UINT8:
666 
667             AcpiOsPrintf ("%2.2X\n", *Target);
668             break;
669 
670         case ACPI_DMT_UINT16:
671 
672             AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
673             break;
674 
675         case ACPI_DMT_UINT24:
676 
677             AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
678                 *Target, *(Target + 1), *(Target + 2));
679             break;
680 
681         case ACPI_DMT_UINT32:
682 
683             AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
684             break;
685 
686         case ACPI_DMT_UINT56:
687 
688             for (Temp8 = 0; Temp8 < 7; Temp8++)
689             {
690                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
691             }
692             AcpiOsPrintf ("\n");
693             break;
694 
695         case ACPI_DMT_UINT64:
696 
697             AcpiOsPrintf ("%8.8X%8.8X\n",
698                 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
699             break;
700 
701         case ACPI_DMT_BUF16:
702 
703             /* Buffer of length 16 */
704 
705             for (Temp8 = 0; Temp8 < 16; Temp8++)
706             {
707                 AcpiOsPrintf ("%2.2X,", Target[Temp8]);
708             }
709             AcpiOsPrintf ("\n");
710             break;
711 
712         case ACPI_DMT_STRING:
713 
714             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
715             break;
716 
717         /* Fixed length ASCII name fields */
718 
719         case ACPI_DMT_SIG:
720 
721             AcpiDmCheckAscii (Target, RepairedName, 4);
722             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
723             TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
724             if (TableData)
725             {
726                 AcpiOsPrintf ("/* %s */", TableData->Name);
727             }
728             AcpiOsPrintf ("\n");
729             break;
730 
731         case ACPI_DMT_NAME4:
732 
733             AcpiDmCheckAscii (Target, RepairedName, 4);
734             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
735             break;
736 
737         case ACPI_DMT_NAME6:
738 
739             AcpiDmCheckAscii (Target, RepairedName, 6);
740             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
741             break;
742 
743         case ACPI_DMT_NAME8:
744 
745             AcpiDmCheckAscii (Target, RepairedName, 8);
746             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
747             break;
748 
749         /* Special Data Types */
750 
751         case ACPI_DMT_CHKSUM:
752 
753             /* Checksum, display and validate */
754 
755             AcpiOsPrintf ("%2.2X", *Target);
756             Temp8 = AcpiTbGenerateChecksum (Table);
757             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
758             {
759                 AcpiOsPrintf (
760                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
761             }
762             AcpiOsPrintf ("\n");
763             break;
764 
765         case ACPI_DMT_SPACEID:
766 
767             /* Address Space ID */
768 
769             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target));
770             break;
771 
772         case ACPI_DMT_GAS:
773 
774             /* Generic Address Structure */
775 
776             AcpiOsPrintf ("<Generic Address Structure>\n");
777             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
778                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
779             AcpiOsPrintf ("\n");
780             LastOutputBlankLine = TRUE;
781             break;
782 
783         case ACPI_DMT_ASF:
784 
785             /* ASF subtable types */
786 
787             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
788             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
789             {
790                 Temp16 = ACPI_ASF_TYPE_RESERVED;
791             }
792 
793             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmAsfSubnames[Temp16]);
794             break;
795 
796         case ACPI_DMT_DMAR:
797 
798             /* DMAR subtable types */
799 
800             Temp16 = ACPI_GET16 (Target);
801             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
802             {
803                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
804             }
805 
806             AcpiOsPrintf ("%4.4X <%s>\n", ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
807             break;
808 
809         case ACPI_DMT_HEST:
810 
811             /* HEST subtable types */
812 
813             Temp16 = ACPI_GET16 (Target);
814             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
815             {
816                 Temp16 = ACPI_HEST_TYPE_RESERVED;
817             }
818 
819             AcpiOsPrintf ("%4.4X (%s)\n", ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
820             break;
821 
822         case ACPI_DMT_HESTNTFY:
823 
824             AcpiOsPrintf ("<Hardware Error Notification Structure>\n");
825             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
826                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
827             AcpiOsPrintf ("\n");
828             LastOutputBlankLine = TRUE;
829             break;
830 
831         case ACPI_DMT_HESTNTYP:
832 
833             /* HEST Notify types */
834 
835             Temp8 = *Target;
836             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
837             {
838                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
839             }
840 
841             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmHestNotifySubnames[Temp8]);
842             break;
843 
844 
845         case ACPI_DMT_MADT:
846 
847             /* MADT subtable types */
848 
849             Temp8 = *Target;
850             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
851             {
852                 Temp8 = ACPI_MADT_TYPE_RESERVED;
853             }
854 
855             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]);
856             break;
857 
858         case ACPI_DMT_SRAT:
859 
860             /* SRAT subtable types */
861 
862             Temp8 = *Target;
863             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
864             {
865                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
866             }
867 
868             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]);
869             break;
870 
871         case ACPI_DMT_FADTPM:
872 
873             /* FADT Preferred PM Profile names */
874 
875             Temp8 = *Target;
876             if (Temp8 > ACPI_FADT_PM_RESERVED)
877             {
878                 Temp8 = ACPI_FADT_PM_RESERVED;
879             }
880 
881             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]);
882             break;
883 
884         case ACPI_DMT_IVRS:
885 
886             /* IVRS subtable types */
887 
888             Temp8 = *Target;
889             switch (Temp8)
890             {
891             case ACPI_IVRS_TYPE_HARDWARE:
892                 Name = AcpiDmIvrsSubnames[0];
893                 break;
894 
895             case ACPI_IVRS_TYPE_MEMORY1:
896             case ACPI_IVRS_TYPE_MEMORY2:
897             case ACPI_IVRS_TYPE_MEMORY3:
898                 Name = AcpiDmIvrsSubnames[1];
899                 break;
900 
901             default:
902                 Name = AcpiDmIvrsSubnames[2];
903                 break;
904             }
905 
906             AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name);
907             break;
908 
909         case ACPI_DMT_EXIT:
910             return (AE_OK);
911 
912         default:
913             ACPI_ERROR ((AE_INFO,
914                 "**** Invalid table opcode [%X] ****\n", Info->Opcode));
915             return (AE_SUPPORT);
916         }
917     }
918 
919     if (TableOffset && !SubtableLength)
920     {
921         /* If this table is not the main table, subtable must have valid length */
922 
923         AcpiOsPrintf ("Invalid zero length subtable\n");
924         return (AE_BAD_DATA);
925     }
926 
927     return (AE_OK);
928 }
929 
930 
931 /*******************************************************************************
932  *
933  * FUNCTION:    AcpiDmCheckAscii
934  *
935  * PARAMETERS:  Name                - Ascii string
936  *              Count               - Number of characters to check
937  *
938  * RETURN:      None
939  *
940  * DESCRIPTION: Ensure that the requested number of characters are printable
941  *              Ascii characters. Sets non-printable and null chars to <space>.
942  *
943  ******************************************************************************/
944 
945 static void
946 AcpiDmCheckAscii (
947     UINT8                   *Name,
948     char                    *RepairedName,
949     UINT32                  Count)
950 {
951     UINT32                  i;
952 
953 
954     for (i = 0; i < Count; i++)
955     {
956         RepairedName[i] = (char) Name[i];
957 
958         if (!Name[i])
959         {
960             return;
961         }
962         if (!isprint (Name[i]))
963         {
964             RepairedName[i] = ' ';
965         }
966     }
967 }
968