xref: /freebsd/sys/contrib/dev/acpica/common/dmtable.c (revision 8f861da99cb9865b2f1ef6098ad074150f368c23)
1 /******************************************************************************
2  *
3  * Module Name: dmtable - Support for ACPI 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 #include <contrib/dev/acpica/compiler/aslcompiler.h>
49 #include <contrib/dev/acpica/compiler/dtcompiler.h>
50 
51 /* This module used for application-level code only */
52 
53 #define _COMPONENT          ACPI_CA_DISASSEMBLER
54         ACPI_MODULE_NAME    ("dmtable")
55 
56 /* Local Prototypes */
57 
58 static void
59 AcpiDmCheckAscii (
60     UINT8                   *Target,
61     char                    *RepairedName,
62     UINT32                  Count);
63 
64 
65 /* These tables map a subtable type to a description string */
66 
67 static const char           *AcpiDmAsfSubnames[] =
68 {
69     "ASF Information",
70     "ASF Alerts",
71     "ASF Remote Control",
72     "ASF RMCP Boot Options",
73     "ASF Address",
74     "Unknown SubTable Type"         /* Reserved */
75 };
76 
77 static const char           *AcpiDmDmarSubnames[] =
78 {
79     "Hardware Unit Definition",
80     "Reserved Memory Region",
81     "Root Port ATS Capability",
82     "Remapping Hardware Static Affinity",
83     "Unknown SubTable Type"         /* Reserved */
84 };
85 
86 static const char           *AcpiDmEinjActions[] =
87 {
88     "Begin Operation",
89     "Get Trigger Table",
90     "Set Error Type",
91     "Get Error Type",
92     "End Operation",
93     "Execute Operation",
94     "Check Busy Status",
95     "Get Command Status",
96     "Unknown Action"
97 };
98 
99 static const char           *AcpiDmEinjInstructions[] =
100 {
101     "Read Register",
102     "Read Register Value",
103     "Write Register",
104     "Write Register Value",
105     "Noop",
106     "Unknown Instruction"
107 };
108 
109 static const char           *AcpiDmErstActions[] =
110 {
111     "Begin Write Operation",
112     "Begin Read Operation",
113     "Begin Clear Operation",
114     "End Operation",
115     "Set Record Offset",
116     "Execute Operation",
117     "Check Busy Status",
118     "Get Command Status",
119     "Get Record Identifier",
120     "Set Record Identifier",
121     "Get Record Count",
122     "Begin Dummy Write",
123     "Unused/Unknown Action",
124     "Get Error Address Range",
125     "Get Error Address Length",
126     "Get Error Attributes",
127     "Unknown Action"
128 };
129 
130 static const char           *AcpiDmErstInstructions[] =
131 {
132     "Read Register",
133     "Read Register Value",
134     "Write Register",
135     "Write Register Value",
136     "Noop",
137     "Load Var1",
138     "Load Var2",
139     "Store Var1",
140     "Add",
141     "Subtract",
142     "Add Value",
143     "Subtract Value",
144     "Stall",
145     "Stall While True",
146     "Skip Next If True",
147     "GoTo",
148     "Set Source Address",
149     "Set Destination Address",
150     "Move Data",
151     "Unknown Instruction"
152 };
153 
154 static const char           *AcpiDmHestSubnames[] =
155 {
156     "IA-32 Machine Check Exception",
157     "IA-32 Corrected Machine Check",
158     "IA-32 Non-Maskable Interrupt",
159     "Unknown SubTable Type",        /* 3 - Reserved */
160     "Unknown SubTable Type",        /* 4 - Reserved */
161     "Unknown SubTable Type",        /* 5 - Reserved */
162     "PCI Express Root Port AER",
163     "PCI Express AER (AER Endpoint)",
164     "PCI Express/PCI-X Bridge AER",
165     "Generic Hardware Error Source",
166     "Unknown SubTable Type"         /* Reserved */
167 };
168 
169 static const char           *AcpiDmHestNotifySubnames[] =
170 {
171     "Polled",
172     "External Interrupt",
173     "Local Interrupt",
174     "SCI",
175     "NMI",
176     "Unknown Notify Type"           /* Reserved */
177 };
178 
179 static const char           *AcpiDmMadtSubnames[] =
180 {
181     "Processor Local APIC",         /* ACPI_MADT_TYPE_LOCAL_APIC */
182     "I/O APIC",                     /* ACPI_MADT_TYPE_IO_APIC */
183     "Interrupt Source Override",    /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */
184     "NMI Source",                   /* ACPI_MADT_TYPE_NMI_SOURCE */
185     "Local APIC NMI",               /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */
186     "Local APIC Address Override",  /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */
187     "I/O SAPIC",                    /* ACPI_MADT_TYPE_IO_SAPIC */
188     "Local SAPIC",                  /* ACPI_MADT_TYPE_LOCAL_SAPIC */
189     "Platform Interrupt Sources",   /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
190     "Processor Local x2APIC",       /* ACPI_MADT_TYPE_LOCAL_X2APIC */
191     "Local x2APIC NMI",             /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
192     "Unknown SubTable Type"         /* Reserved */
193 };
194 
195 static const char           *AcpiDmSratSubnames[] =
196 {
197     "Processor Local APIC/SAPIC Affinity",
198     "Memory Affinity",
199     "Processor Local x2APIC Affinity",
200     "Unknown SubTable Type"         /* Reserved */
201 };
202 
203 static const char           *AcpiDmIvrsSubnames[] =
204 {
205     "Hardware Definition Block",
206     "Memory Definition Block",
207     "Unknown SubTable Type"         /* Reserved */
208 };
209 
210 
211 #define ACPI_FADT_PM_RESERVED       8
212 
213 static const char           *AcpiDmFadtProfiles[] =
214 {
215     "Unspecified",
216     "Desktop",
217     "Mobile",
218     "Workstation",
219     "Enterprise Server",
220     "SOHO Server",
221     "Appliance PC",
222     "Performance Server",
223     "Unknown Profile Type"
224 };
225 
226 #define ACPI_GAS_WIDTH_RESERVED     5
227 
228 static const char           *AcpiDmGasAccessWidth[] =
229 {
230     "Undefined/Legacy",
231     "Byte Access:8",
232     "Word Access:16",
233     "DWord Access:32",
234     "QWord Access:64",
235     "Unknown Width Encoding"
236 };
237 
238 
239 /*******************************************************************************
240  *
241  * ACPI Table Data, indexed by signature.
242  *
243  * Each entry contains: Signature, Table Info, Handler, DtHandler,
244  *  Template, Description
245  *
246  * Simple tables have only a TableInfo structure, complex tables have a
247  * handler. This table must be NULL terminated. RSDP and FACS are
248  * special-cased elsewhere.
249  *
250  ******************************************************************************/
251 
252 ACPI_DMTABLE_DATA    AcpiDmTableData[] =
253 {
254     {ACPI_SIG_ASF,  NULL,                   AcpiDmDumpAsf,  DtCompileAsf,   TemplateAsf,    "Alert Standard Format table"},
255     {ACPI_SIG_BOOT, AcpiDmTableInfoBoot,    NULL,           NULL,           TemplateBoot,   "Simple Boot Flag Table"},
256     {ACPI_SIG_BERT, AcpiDmTableInfoBert,    NULL,           NULL,           TemplateBert,   "Boot Error Record Table"},
257     {ACPI_SIG_CPEP, NULL,                   AcpiDmDumpCpep, DtCompileCpep,  TemplateCpep,   "Corrected Platform Error Polling table"},
258     {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp,    NULL,           NULL,           TemplateDbgp,   "Debug Port table"},
259     {ACPI_SIG_DMAR, NULL,                   AcpiDmDumpDmar, DtCompileDmar,  TemplateDmar,   "DMA Remapping table"},
260     {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt,    NULL,           NULL,           TemplateEcdt,   "Embedded Controller Boot Resources Table"},
261     {ACPI_SIG_EINJ, NULL,                   AcpiDmDumpEinj, DtCompileEinj,  TemplateEinj,   "Error Injection table"},
262     {ACPI_SIG_ERST, NULL,                   AcpiDmDumpErst, DtCompileErst,  TemplateErst,   "Error Record Serialization Table"},
263     {ACPI_SIG_FADT, NULL,                   AcpiDmDumpFadt, DtCompileFadt,  TemplateFadt,   "Fixed ACPI Description Table"},
264     {ACPI_SIG_HEST, NULL,                   AcpiDmDumpHest, DtCompileHest,  TemplateHest,   "Hardware Error Source Table"},
265     {ACPI_SIG_HPET, AcpiDmTableInfoHpet,    NULL,           NULL,           TemplateHpet,   "High Precision Event Timer table"},
266     {ACPI_SIG_IVRS, NULL,                   AcpiDmDumpIvrs, DtCompileIvrs,  TemplateIvrs,   "I/O Virtualization Reporting Structure"},
267     {ACPI_SIG_MADT, NULL,                   AcpiDmDumpMadt, DtCompileMadt,  TemplateMadt,   "Multiple APIC Description Table"},
268     {ACPI_SIG_MCFG, NULL,                   AcpiDmDumpMcfg, DtCompileMcfg,  TemplateMcfg,   "Memory Mapped Configuration table"},
269     {ACPI_SIG_MCHI, AcpiDmTableInfoMchi,    NULL,           NULL,           TemplateMchi,   "Management Controller Host Interface table"},
270     {ACPI_SIG_MSCT, NULL,                   AcpiDmDumpMsct, DtCompileMsct,  TemplateMsct,   "Maximum System Characteristics Table"},
271     {ACPI_SIG_RSDT, NULL,                   AcpiDmDumpRsdt, DtCompileRsdt,  TemplateRsdt,   "Root System Description Table"},
272     {ACPI_SIG_SBST, AcpiDmTableInfoSbst,    NULL,           NULL,           TemplateSbst,   "Smart Battery Specification Table"},
273     {ACPI_SIG_SLIC, AcpiDmTableInfoSlic,    NULL,           NULL,           NULL,           "Software Licensing Description Table"},
274     {ACPI_SIG_SLIT, NULL,                   AcpiDmDumpSlit, DtCompileSlit,  TemplateSlit,   "System Locality Information Table"},
275     {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr,    NULL,           NULL,           TemplateSpcr,   "Serial Port Console Redirection table"},
276     {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi,    NULL,           NULL,           TemplateSpmi,   "Server Platform Management Interface table"},
277     {ACPI_SIG_SRAT, NULL,                   AcpiDmDumpSrat, DtCompileSrat,  TemplateSrat,   "System Resource Affinity Table"},
278     {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa,    NULL,           NULL,           TemplateTcpa,   "Trusted Computing Platform Alliance table"},
279     {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           DtCompileUefi,  TemplateUefi,   "UEFI Boot Optimization Table"},
280     {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           NULL,           TemplateWaet,   "Windows ACPI Emulated Devices Table"},
281     {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, DtCompileWdat,  TemplateWdat,   "Watchdog Action Table"},
282     {ACPI_SIG_WDDT, AcpiDmTableInfoWddt,    NULL,           NULL,           TemplateWddt,   "Watchdog Description Table"},
283     {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           NULL,           TemplateWdrt,   "Watchdog Resource Table"},
284     {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, DtCompileXsdt,  TemplateXsdt,   "Extended System Description Table"},
285     {NULL,          NULL,                   NULL,           NULL,           NULL,           NULL}
286 };
287 
288 
289 /*******************************************************************************
290  *
291  * FUNCTION:    AcpiDmGenerateChecksum
292  *
293  * PARAMETERS:  Table               - Pointer to table to be checksummed
294  *              Length              - Length of the table
295  *              OriginalChecksum    - Value of the checksum field
296  *
297  * RETURN:      8 bit checksum of buffer
298  *
299  * DESCRIPTION: Computes an 8 bit checksum of the table.
300  *
301  ******************************************************************************/
302 
303 UINT8
304 AcpiDmGenerateChecksum (
305     void                    *Table,
306     UINT32                  Length,
307     UINT8                   OriginalChecksum)
308 {
309     UINT8                   Checksum;
310 
311 
312     /* Sum the entire table as-is */
313 
314     Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
315 
316     /* Subtract off the existing checksum value in the table */
317 
318     Checksum = (UINT8) (Checksum - OriginalChecksum);
319 
320     /* Compute the final checksum */
321 
322     Checksum = (UINT8) (0 - Checksum);
323     return (Checksum);
324 }
325 
326 
327 /*******************************************************************************
328  *
329  * FUNCTION:    AcpiDmGetTableData
330  *
331  * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
332  *
333  * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
334  *
335  * DESCRIPTION: Find a match in the global table of supported ACPI tables
336  *
337  ******************************************************************************/
338 
339 ACPI_DMTABLE_DATA *
340 AcpiDmGetTableData (
341     char                    *Signature)
342 {
343     ACPI_DMTABLE_DATA       *TableData;
344 
345 
346     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
347     {
348         if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
349         {
350             return (TableData);
351         }
352     }
353 
354     return (NULL);
355 }
356 
357 
358 /*******************************************************************************
359  *
360  * FUNCTION:    AcpiDmDumpDataTable
361  *
362  * PARAMETERS:  Table               - An ACPI table
363  *
364  * RETURN:      None.
365  *
366  * DESCRIPTION: Format the contents of an ACPI data table (any table other
367  *              than an SSDT or DSDT that does not contain executable AML code)
368  *
369  ******************************************************************************/
370 
371 void
372 AcpiDmDumpDataTable (
373     ACPI_TABLE_HEADER       *Table)
374 {
375     ACPI_STATUS             Status;
376     ACPI_DMTABLE_DATA       *TableData;
377     UINT32                  Length;
378 
379 
380     /* Ignore tables that contain AML */
381 
382     if (AcpiUtIsAmlTable (Table))
383     {
384         return;
385     }
386 
387     /*
388      * Handle tables that don't use the common ACPI table header structure.
389      * Currently, these are the FACS and RSDP.
390      */
391     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
392     {
393         Length = Table->Length;
394         AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
395     }
396     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
397     {
398         Length = AcpiDmDumpRsdp (Table);
399     }
400     else
401     {
402         /*
403          * All other tables must use the common ACPI table header, dump it now
404          */
405         Length = Table->Length;
406         Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
407         if (ACPI_FAILURE (Status))
408         {
409             return;
410         }
411         AcpiOsPrintf ("\n");
412 
413         /* Match signature and dispatch appropriately */
414 
415         TableData = AcpiDmGetTableData (Table->Signature);
416         if (!TableData)
417         {
418             if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
419             {
420                 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
421                     Table->Signature);
422             }
423             else
424             {
425                 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
426                     Table->Signature);
427             }
428         }
429         else if (TableData->TableHandler)
430         {
431             /* Complex table, has a handler */
432 
433             TableData->TableHandler (Table);
434         }
435         else if (TableData->TableInfo)
436         {
437             /* Simple table, just walk the info table */
438 
439             AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
440         }
441     }
442 
443     if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
444     {
445         /* Dump the raw table data */
446 
447         AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
448             ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
449         AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
450     }
451 }
452 
453 
454 /*******************************************************************************
455  *
456  * FUNCTION:    AcpiDmLineHeader
457  *
458  * PARAMETERS:  Offset              - Current byte offset, from table start
459  *              ByteLength          - Length of the field in bytes, 0 for flags
460  *              Name                - Name of this field
461  *              Value               - Optional value, displayed on left of ':'
462  *
463  * RETURN:      None
464  *
465  * DESCRIPTION: Utility routines for formatting output lines. Displays the
466  *              current table offset in hex and decimal, the field length,
467  *              and the field name.
468  *
469  ******************************************************************************/
470 
471 void
472 AcpiDmLineHeader (
473     UINT32                  Offset,
474     UINT32                  ByteLength,
475     char                    *Name)
476 {
477 
478     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
479     {
480         if (ByteLength)
481         {
482             AcpiOsPrintf ("[%.3d] %34s : ",
483                 ByteLength, Name);
484         }
485         else
486         {
487             AcpiOsPrintf ("%40s : ",
488                 Name);
489         }
490     }
491     else /* Normal disassembler or verbose template */
492     {
493         if (ByteLength)
494         {
495             AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %28s : ",
496                 Offset, Offset, ByteLength, Name);
497         }
498         else
499         {
500             AcpiOsPrintf ("%43s : ",
501                 Name);
502         }
503     }
504 }
505 
506 void
507 AcpiDmLineHeader2 (
508     UINT32                  Offset,
509     UINT32                  ByteLength,
510     char                    *Name,
511     UINT32                  Value)
512 {
513 
514     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
515     {
516         if (ByteLength)
517         {
518             AcpiOsPrintf ("[%.3d] %30s % 3d : ",
519                 ByteLength, Name, Value);
520         }
521         else
522         {
523             AcpiOsPrintf ("%36s % 3d : ",
524                 Name, Value);
525         }
526     }
527     else /* Normal disassembler or verbose template */
528     {
529         if (ByteLength)
530         {
531             AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %24s % 3d : ",
532                 Offset, Offset, ByteLength, Name, Value);
533         }
534         else
535         {
536             AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s % 3d : ",
537                 Offset, Offset, Name, Value);
538         }
539     }
540 }
541 
542 
543 /*******************************************************************************
544  *
545  * FUNCTION:    AcpiDmDumpTable
546  *
547  * PARAMETERS:  TableLength         - Length of the entire ACPI table
548  *              TableOffset         - Starting offset within the table for this
549  *                                    sub-descriptor (0 if main table)
550  *              Table               - The ACPI table
551  *              SubtableLength      - Length of this sub-descriptor
552  *              Info                - Info table for this ACPI table
553  *
554  * RETURN:      None
555  *
556  * DESCRIPTION: Display ACPI table contents by walking the Info table.
557  *
558  * Note: This function must remain in sync with DtGetFieldLength.
559  *
560  ******************************************************************************/
561 
562 ACPI_STATUS
563 AcpiDmDumpTable (
564     UINT32                  TableLength,
565     UINT32                  TableOffset,
566     void                    *Table,
567     UINT32                  SubtableLength,
568     ACPI_DMTABLE_INFO       *Info)
569 {
570     UINT8                   *Target;
571     UINT32                  CurrentOffset;
572     UINT32                  ByteLength;
573     UINT8                   Temp8;
574     UINT16                  Temp16;
575     ACPI_DMTABLE_DATA       *TableData;
576     const char              *Name;
577     BOOLEAN                 LastOutputBlankLine = FALSE;
578     char                    RepairedName[8];
579 
580 
581     if (!Info)
582     {
583         AcpiOsPrintf ("Display not implemented\n");
584         return (AE_NOT_IMPLEMENTED);
585     }
586 
587     /* Walk entire Info table; Null name terminates */
588 
589     for (; Info->Name; Info++)
590     {
591         /*
592          * Target points to the field within the ACPI Table. CurrentOffset is
593          * the offset of the field from the start of the main table.
594          */
595         Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
596         CurrentOffset = TableOffset + Info->Offset;
597 
598         /* Check for beyond EOT or beyond subtable end */
599 
600         if ((CurrentOffset >= TableLength) ||
601             (SubtableLength && (Info->Offset >= SubtableLength)))
602         {
603             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
604             return (AE_BAD_DATA);
605         }
606 
607         /* Generate the byte length for this field */
608 
609         switch (Info->Opcode)
610         {
611         case ACPI_DMT_UINT8:
612         case ACPI_DMT_CHKSUM:
613         case ACPI_DMT_SPACEID:
614         case ACPI_DMT_ACCWIDTH:
615         case ACPI_DMT_IVRS:
616         case ACPI_DMT_MADT:
617         case ACPI_DMT_SRAT:
618         case ACPI_DMT_ASF:
619         case ACPI_DMT_HESTNTYP:
620         case ACPI_DMT_FADTPM:
621         case ACPI_DMT_EINJACT:
622         case ACPI_DMT_EINJINST:
623         case ACPI_DMT_ERSTACT:
624         case ACPI_DMT_ERSTINST:
625             ByteLength = 1;
626             break;
627         case ACPI_DMT_UINT16:
628         case ACPI_DMT_DMAR:
629         case ACPI_DMT_HEST:
630             ByteLength = 2;
631             break;
632         case ACPI_DMT_UINT24:
633             ByteLength = 3;
634             break;
635         case ACPI_DMT_UINT32:
636         case ACPI_DMT_NAME4:
637         case ACPI_DMT_SIG:
638             ByteLength = 4;
639             break;
640         case ACPI_DMT_NAME6:
641             ByteLength = 6;
642             break;
643         case ACPI_DMT_UINT56:
644             ByteLength = 7;
645             break;
646         case ACPI_DMT_UINT64:
647         case ACPI_DMT_NAME8:
648             ByteLength = 8;
649             break;
650         case ACPI_DMT_BUF16:
651         case ACPI_DMT_UUID:
652             ByteLength = 16;
653             break;
654         case ACPI_DMT_STRING:
655             ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
656             break;
657         case ACPI_DMT_GAS:
658             if (!LastOutputBlankLine)
659             {
660                 AcpiOsPrintf ("\n");
661                 LastOutputBlankLine = TRUE;
662             }
663             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
664             break;
665         case ACPI_DMT_HESTNTFY:
666             if (!LastOutputBlankLine)
667             {
668                 AcpiOsPrintf ("\n");
669                 LastOutputBlankLine = TRUE;
670             }
671             ByteLength = sizeof (ACPI_HEST_NOTIFY);
672             break;
673         default:
674             ByteLength = 0;
675             break;
676         }
677 
678         if (CurrentOffset + ByteLength > TableLength)
679         {
680             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
681             return (AE_BAD_DATA);
682         }
683 
684         /* Start a new line and decode the opcode */
685 
686         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
687 
688         switch (Info->Opcode)
689         {
690         /* Single-bit Flag fields. Note: Opcode is the bit position */
691 
692         case ACPI_DMT_FLAG0:
693         case ACPI_DMT_FLAG1:
694         case ACPI_DMT_FLAG2:
695         case ACPI_DMT_FLAG3:
696         case ACPI_DMT_FLAG4:
697         case ACPI_DMT_FLAG5:
698         case ACPI_DMT_FLAG6:
699         case ACPI_DMT_FLAG7:
700 
701             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
702             break;
703 
704         /* 2-bit Flag fields */
705 
706         case ACPI_DMT_FLAGS0:
707 
708             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
709             break;
710 
711         case ACPI_DMT_FLAGS2:
712 
713             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
714             break;
715 
716         /* Standard Data Types */
717 
718         case ACPI_DMT_UINT8:
719 
720             AcpiOsPrintf ("%2.2X\n", *Target);
721             break;
722 
723         case ACPI_DMT_UINT16:
724 
725             AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
726             break;
727 
728         case ACPI_DMT_UINT24:
729 
730             AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
731                 *Target, *(Target + 1), *(Target + 2));
732             break;
733 
734         case ACPI_DMT_UINT32:
735 
736             AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
737             break;
738 
739         case ACPI_DMT_UINT56:
740 
741             for (Temp8 = 0; Temp8 < 7; Temp8++)
742             {
743                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
744             }
745             AcpiOsPrintf ("\n");
746             break;
747 
748         case ACPI_DMT_UINT64:
749 
750             AcpiOsPrintf ("%8.8X%8.8X\n",
751                 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
752             break;
753 
754         case ACPI_DMT_BUF16:
755 
756             /* Buffer of length 16 */
757 
758             for (Temp8 = 0; Temp8 < 16; Temp8++)
759             {
760                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
761                 if ((Temp8 + 1) < 16)
762                 {
763                     AcpiOsPrintf (",");
764                 }
765             }
766             AcpiOsPrintf ("\n");
767             break;
768 
769         case ACPI_DMT_UUID:
770 
771             /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
772 
773             (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
774 
775             AcpiOsPrintf ("%s\n", MsgBuffer);
776             break;
777 
778         case ACPI_DMT_STRING:
779 
780             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
781             break;
782 
783         /* Fixed length ASCII name fields */
784 
785         case ACPI_DMT_SIG:
786 
787             AcpiDmCheckAscii (Target, RepairedName, 4);
788             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
789             TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
790             if (TableData)
791             {
792                 AcpiOsPrintf ("/* %s */", TableData->Name);
793             }
794             AcpiOsPrintf ("\n");
795             break;
796 
797         case ACPI_DMT_NAME4:
798 
799             AcpiDmCheckAscii (Target, RepairedName, 4);
800             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
801             break;
802 
803         case ACPI_DMT_NAME6:
804 
805             AcpiDmCheckAscii (Target, RepairedName, 6);
806             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
807             break;
808 
809         case ACPI_DMT_NAME8:
810 
811             AcpiDmCheckAscii (Target, RepairedName, 8);
812             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
813             break;
814 
815         /* Special Data Types */
816 
817         case ACPI_DMT_CHKSUM:
818 
819             /* Checksum, display and validate */
820 
821             AcpiOsPrintf ("%2.2X", *Target);
822             Temp8 = AcpiDmGenerateChecksum (Table,
823                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
824                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
825             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
826             {
827                 AcpiOsPrintf (
828                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
829             }
830             AcpiOsPrintf ("\n");
831             break;
832 
833         case ACPI_DMT_SPACEID:
834 
835             /* Address Space ID */
836 
837             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target));
838             break;
839 
840         case ACPI_DMT_ACCWIDTH:
841 
842             /* Encoded Access Width */
843 
844             Temp8 = *Target;
845             if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
846             {
847                 Temp8 = ACPI_GAS_WIDTH_RESERVED;
848             }
849 
850             AcpiOsPrintf ("%2.2X (%s)\n", Temp8, AcpiDmGasAccessWidth[Temp8]);
851             break;
852 
853         case ACPI_DMT_GAS:
854 
855             /* Generic Address Structure */
856 
857             AcpiOsPrintf ("<Generic Address Structure>\n");
858             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
859                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
860             AcpiOsPrintf ("\n");
861             LastOutputBlankLine = TRUE;
862             break;
863 
864         case ACPI_DMT_ASF:
865 
866             /* ASF subtable types */
867 
868             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
869             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
870             {
871                 Temp16 = ACPI_ASF_TYPE_RESERVED;
872             }
873 
874             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmAsfSubnames[Temp16]);
875             break;
876 
877         case ACPI_DMT_DMAR:
878 
879             /* DMAR subtable types */
880 
881             Temp16 = ACPI_GET16 (Target);
882             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
883             {
884                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
885             }
886 
887             AcpiOsPrintf ("%4.4X <%s>\n", ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
888             break;
889 
890         case ACPI_DMT_EINJACT:
891 
892             /* EINJ Action types */
893 
894             Temp8 = *Target;
895             if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
896             {
897                 Temp8 = ACPI_EINJ_ACTION_RESERVED;
898             }
899 
900             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjActions[Temp8]);
901             break;
902 
903         case ACPI_DMT_EINJINST:
904 
905             /* EINJ Instruction types */
906 
907             Temp8 = *Target;
908             if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
909             {
910                 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
911             }
912 
913             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjInstructions[Temp8]);
914             break;
915 
916         case ACPI_DMT_ERSTACT:
917 
918             /* ERST Action types */
919 
920             Temp8 = *Target;
921             if (Temp8 > ACPI_ERST_ACTION_RESERVED)
922             {
923                 Temp8 = ACPI_ERST_ACTION_RESERVED;
924             }
925 
926             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstActions[Temp8]);
927             break;
928 
929         case ACPI_DMT_ERSTINST:
930 
931             /* ERST Instruction types */
932 
933             Temp8 = *Target;
934             if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
935             {
936                 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
937             }
938 
939             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstInstructions[Temp8]);
940             break;
941 
942         case ACPI_DMT_HEST:
943 
944             /* HEST subtable types */
945 
946             Temp16 = ACPI_GET16 (Target);
947             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
948             {
949                 Temp16 = ACPI_HEST_TYPE_RESERVED;
950             }
951 
952             AcpiOsPrintf ("%4.4X (%s)\n", ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
953             break;
954 
955         case ACPI_DMT_HESTNTFY:
956 
957             AcpiOsPrintf ("<Hardware Error Notification Structure>\n");
958             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
959                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
960             AcpiOsPrintf ("\n");
961             LastOutputBlankLine = TRUE;
962             break;
963 
964         case ACPI_DMT_HESTNTYP:
965 
966             /* HEST Notify types */
967 
968             Temp8 = *Target;
969             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
970             {
971                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
972             }
973 
974             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmHestNotifySubnames[Temp8]);
975             break;
976 
977         case ACPI_DMT_MADT:
978 
979             /* MADT subtable types */
980 
981             Temp8 = *Target;
982             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
983             {
984                 Temp8 = ACPI_MADT_TYPE_RESERVED;
985             }
986 
987             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]);
988             break;
989 
990         case ACPI_DMT_SRAT:
991 
992             /* SRAT subtable types */
993 
994             Temp8 = *Target;
995             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
996             {
997                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
998             }
999 
1000             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]);
1001             break;
1002 
1003         case ACPI_DMT_FADTPM:
1004 
1005             /* FADT Preferred PM Profile names */
1006 
1007             Temp8 = *Target;
1008             if (Temp8 > ACPI_FADT_PM_RESERVED)
1009             {
1010                 Temp8 = ACPI_FADT_PM_RESERVED;
1011             }
1012 
1013             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]);
1014             break;
1015 
1016         case ACPI_DMT_IVRS:
1017 
1018             /* IVRS subtable types */
1019 
1020             Temp8 = *Target;
1021             switch (Temp8)
1022             {
1023             case ACPI_IVRS_TYPE_HARDWARE:
1024                 Name = AcpiDmIvrsSubnames[0];
1025                 break;
1026 
1027             case ACPI_IVRS_TYPE_MEMORY1:
1028             case ACPI_IVRS_TYPE_MEMORY2:
1029             case ACPI_IVRS_TYPE_MEMORY3:
1030                 Name = AcpiDmIvrsSubnames[1];
1031                 break;
1032 
1033             default:
1034                 Name = AcpiDmIvrsSubnames[2];
1035                 break;
1036             }
1037 
1038             AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name);
1039             break;
1040 
1041         case ACPI_DMT_EXIT:
1042             return (AE_OK);
1043 
1044         default:
1045             ACPI_ERROR ((AE_INFO,
1046                 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1047             return (AE_SUPPORT);
1048         }
1049     }
1050 
1051     if (TableOffset && !SubtableLength)
1052     {
1053         /* If this table is not the main table, subtable must have valid length */
1054 
1055         AcpiOsPrintf ("Invalid zero length subtable\n");
1056         return (AE_BAD_DATA);
1057     }
1058 
1059     return (AE_OK);
1060 }
1061 
1062 
1063 /*******************************************************************************
1064  *
1065  * FUNCTION:    AcpiDmCheckAscii
1066  *
1067  * PARAMETERS:  Name                - Ascii string
1068  *              Count               - Number of characters to check
1069  *
1070  * RETURN:      None
1071  *
1072  * DESCRIPTION: Ensure that the requested number of characters are printable
1073  *              Ascii characters. Sets non-printable and null chars to <space>.
1074  *
1075  ******************************************************************************/
1076 
1077 static void
1078 AcpiDmCheckAscii (
1079     UINT8                   *Name,
1080     char                    *RepairedName,
1081     UINT32                  Count)
1082 {
1083     UINT32                  i;
1084 
1085 
1086     for (i = 0; i < Count; i++)
1087     {
1088         RepairedName[i] = (char) Name[i];
1089 
1090         if (!Name[i])
1091         {
1092             return;
1093         }
1094         if (!isprint (Name[i]))
1095         {
1096             RepairedName[i] = ' ';
1097         }
1098     }
1099 }
1100