xref: /netbsd-src/sys/external/bsd/acpica/dist/common/dmtable.c (revision 46f5119e40af2e51998f686b2fdcc76b5488f7f3)
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 "acpi.h"
45 #include "accommon.h"
46 #include "acdisasm.h"
47 #include "actables.h"
48 #include "aslcompiler.h"
49 #include "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         case ACPI_DMT_BUF7:
645             ByteLength = 7;
646             break;
647         case ACPI_DMT_UINT64:
648         case ACPI_DMT_NAME8:
649             ByteLength = 8;
650             break;
651         case ACPI_DMT_BUF16:
652         case ACPI_DMT_UUID:
653             ByteLength = 16;
654             break;
655         case ACPI_DMT_STRING:
656             ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
657             break;
658         case ACPI_DMT_GAS:
659             if (!LastOutputBlankLine)
660             {
661                 AcpiOsPrintf ("\n");
662                 LastOutputBlankLine = TRUE;
663             }
664             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
665             break;
666         case ACPI_DMT_HESTNTFY:
667             if (!LastOutputBlankLine)
668             {
669                 AcpiOsPrintf ("\n");
670                 LastOutputBlankLine = TRUE;
671             }
672             ByteLength = sizeof (ACPI_HEST_NOTIFY);
673             break;
674         default:
675             ByteLength = 0;
676             break;
677         }
678 
679         if (CurrentOffset + ByteLength > TableLength)
680         {
681             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
682             return (AE_BAD_DATA);
683         }
684 
685         /* Start a new line and decode the opcode */
686 
687         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
688 
689         switch (Info->Opcode)
690         {
691         /* Single-bit Flag fields. Note: Opcode is the bit position */
692 
693         case ACPI_DMT_FLAG0:
694         case ACPI_DMT_FLAG1:
695         case ACPI_DMT_FLAG2:
696         case ACPI_DMT_FLAG3:
697         case ACPI_DMT_FLAG4:
698         case ACPI_DMT_FLAG5:
699         case ACPI_DMT_FLAG6:
700         case ACPI_DMT_FLAG7:
701 
702             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
703             break;
704 
705         /* 2-bit Flag fields */
706 
707         case ACPI_DMT_FLAGS0:
708 
709             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
710             break;
711 
712         case ACPI_DMT_FLAGS2:
713 
714             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
715             break;
716 
717         /* Standard Data Types */
718 
719         case ACPI_DMT_UINT8:
720 
721             AcpiOsPrintf ("%2.2X\n", *Target);
722             break;
723 
724         case ACPI_DMT_UINT16:
725 
726             AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
727             break;
728 
729         case ACPI_DMT_UINT24:
730 
731             AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
732                 *Target, *(Target + 1), *(Target + 2));
733             break;
734 
735         case ACPI_DMT_UINT32:
736 
737             AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
738             break;
739 
740         case ACPI_DMT_UINT56:
741 
742             for (Temp8 = 0; Temp8 < 7; Temp8++)
743             {
744                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
745             }
746             AcpiOsPrintf ("\n");
747             break;
748 
749         case ACPI_DMT_UINT64:
750 
751             AcpiOsPrintf ("%8.8X%8.8X\n",
752                 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
753             break;
754 
755         case ACPI_DMT_BUF7:
756         case ACPI_DMT_BUF16:
757 
758             /*
759              * Buffer: Size depends on the opcode and was set above.
760              * Each hex byte is separated with a space.
761              */
762             for (Temp8 = 0; Temp8 < ByteLength; Temp8++)
763             {
764                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
765                 if ((UINT32) (Temp8 + 1) < ByteLength)
766                 {
767                     AcpiOsPrintf (" ");
768                 }
769             }
770             AcpiOsPrintf ("\n");
771             break;
772 
773         case ACPI_DMT_UUID:
774 
775             /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
776 
777             (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
778 
779             AcpiOsPrintf ("%s\n", MsgBuffer);
780             break;
781 
782         case ACPI_DMT_STRING:
783 
784             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
785             break;
786 
787         /* Fixed length ASCII name fields */
788 
789         case ACPI_DMT_SIG:
790 
791             AcpiDmCheckAscii (Target, RepairedName, 4);
792             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
793             TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
794             if (TableData)
795             {
796                 AcpiOsPrintf ("/* %s */", TableData->Name);
797             }
798             AcpiOsPrintf ("\n");
799             break;
800 
801         case ACPI_DMT_NAME4:
802 
803             AcpiDmCheckAscii (Target, RepairedName, 4);
804             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
805             break;
806 
807         case ACPI_DMT_NAME6:
808 
809             AcpiDmCheckAscii (Target, RepairedName, 6);
810             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
811             break;
812 
813         case ACPI_DMT_NAME8:
814 
815             AcpiDmCheckAscii (Target, RepairedName, 8);
816             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
817             break;
818 
819         /* Special Data Types */
820 
821         case ACPI_DMT_CHKSUM:
822 
823             /* Checksum, display and validate */
824 
825             AcpiOsPrintf ("%2.2X", *Target);
826             Temp8 = AcpiDmGenerateChecksum (Table,
827                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
828                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
829             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
830             {
831                 AcpiOsPrintf (
832                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
833             }
834             AcpiOsPrintf ("\n");
835             break;
836 
837         case ACPI_DMT_SPACEID:
838 
839             /* Address Space ID */
840 
841             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target));
842             break;
843 
844         case ACPI_DMT_ACCWIDTH:
845 
846             /* Encoded Access Width */
847 
848             Temp8 = *Target;
849             if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
850             {
851                 Temp8 = ACPI_GAS_WIDTH_RESERVED;
852             }
853 
854             AcpiOsPrintf ("%2.2X (%s)\n", Temp8, AcpiDmGasAccessWidth[Temp8]);
855             break;
856 
857         case ACPI_DMT_GAS:
858 
859             /* Generic Address Structure */
860 
861             AcpiOsPrintf ("<Generic Address Structure>\n");
862             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
863                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
864             AcpiOsPrintf ("\n");
865             LastOutputBlankLine = TRUE;
866             break;
867 
868         case ACPI_DMT_ASF:
869 
870             /* ASF subtable types */
871 
872             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
873             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
874             {
875                 Temp16 = ACPI_ASF_TYPE_RESERVED;
876             }
877 
878             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmAsfSubnames[Temp16]);
879             break;
880 
881         case ACPI_DMT_DMAR:
882 
883             /* DMAR subtable types */
884 
885             Temp16 = ACPI_GET16 (Target);
886             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
887             {
888                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
889             }
890 
891             AcpiOsPrintf ("%4.4X <%s>\n", ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
892             break;
893 
894         case ACPI_DMT_EINJACT:
895 
896             /* EINJ Action types */
897 
898             Temp8 = *Target;
899             if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
900             {
901                 Temp8 = ACPI_EINJ_ACTION_RESERVED;
902             }
903 
904             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjActions[Temp8]);
905             break;
906 
907         case ACPI_DMT_EINJINST:
908 
909             /* EINJ Instruction types */
910 
911             Temp8 = *Target;
912             if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
913             {
914                 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
915             }
916 
917             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjInstructions[Temp8]);
918             break;
919 
920         case ACPI_DMT_ERSTACT:
921 
922             /* ERST Action types */
923 
924             Temp8 = *Target;
925             if (Temp8 > ACPI_ERST_ACTION_RESERVED)
926             {
927                 Temp8 = ACPI_ERST_ACTION_RESERVED;
928             }
929 
930             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstActions[Temp8]);
931             break;
932 
933         case ACPI_DMT_ERSTINST:
934 
935             /* ERST Instruction types */
936 
937             Temp8 = *Target;
938             if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
939             {
940                 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
941             }
942 
943             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstInstructions[Temp8]);
944             break;
945 
946         case ACPI_DMT_HEST:
947 
948             /* HEST subtable types */
949 
950             Temp16 = ACPI_GET16 (Target);
951             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
952             {
953                 Temp16 = ACPI_HEST_TYPE_RESERVED;
954             }
955 
956             AcpiOsPrintf ("%4.4X (%s)\n", ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
957             break;
958 
959         case ACPI_DMT_HESTNTFY:
960 
961             AcpiOsPrintf ("<Hardware Error Notification Structure>\n");
962             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
963                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
964             AcpiOsPrintf ("\n");
965             LastOutputBlankLine = TRUE;
966             break;
967 
968         case ACPI_DMT_HESTNTYP:
969 
970             /* HEST Notify types */
971 
972             Temp8 = *Target;
973             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
974             {
975                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
976             }
977 
978             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmHestNotifySubnames[Temp8]);
979             break;
980 
981         case ACPI_DMT_MADT:
982 
983             /* MADT subtable types */
984 
985             Temp8 = *Target;
986             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
987             {
988                 Temp8 = ACPI_MADT_TYPE_RESERVED;
989             }
990 
991             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]);
992             break;
993 
994         case ACPI_DMT_SRAT:
995 
996             /* SRAT subtable types */
997 
998             Temp8 = *Target;
999             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1000             {
1001                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
1002             }
1003 
1004             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]);
1005             break;
1006 
1007         case ACPI_DMT_FADTPM:
1008 
1009             /* FADT Preferred PM Profile names */
1010 
1011             Temp8 = *Target;
1012             if (Temp8 > ACPI_FADT_PM_RESERVED)
1013             {
1014                 Temp8 = ACPI_FADT_PM_RESERVED;
1015             }
1016 
1017             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]);
1018             break;
1019 
1020         case ACPI_DMT_IVRS:
1021 
1022             /* IVRS subtable types */
1023 
1024             Temp8 = *Target;
1025             switch (Temp8)
1026             {
1027             case ACPI_IVRS_TYPE_HARDWARE:
1028                 Name = AcpiDmIvrsSubnames[0];
1029                 break;
1030 
1031             case ACPI_IVRS_TYPE_MEMORY1:
1032             case ACPI_IVRS_TYPE_MEMORY2:
1033             case ACPI_IVRS_TYPE_MEMORY3:
1034                 Name = AcpiDmIvrsSubnames[1];
1035                 break;
1036 
1037             default:
1038                 Name = AcpiDmIvrsSubnames[2];
1039                 break;
1040             }
1041 
1042             AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name);
1043             break;
1044 
1045         case ACPI_DMT_EXIT:
1046             return (AE_OK);
1047 
1048         default:
1049             ACPI_ERROR ((AE_INFO,
1050                 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1051             return (AE_SUPPORT);
1052         }
1053     }
1054 
1055     if (TableOffset && !SubtableLength)
1056     {
1057         /* If this table is not the main table, subtable must have valid length */
1058 
1059         AcpiOsPrintf ("Invalid zero length subtable\n");
1060         return (AE_BAD_DATA);
1061     }
1062 
1063     return (AE_OK);
1064 }
1065 
1066 
1067 /*******************************************************************************
1068  *
1069  * FUNCTION:    AcpiDmCheckAscii
1070  *
1071  * PARAMETERS:  Name                - Ascii string
1072  *              Count               - Number of characters to check
1073  *
1074  * RETURN:      None
1075  *
1076  * DESCRIPTION: Ensure that the requested number of characters are printable
1077  *              Ascii characters. Sets non-printable and null chars to <space>.
1078  *
1079  ******************************************************************************/
1080 
1081 static void
1082 AcpiDmCheckAscii (
1083     UINT8                   *Name,
1084     char                    *RepairedName,
1085     UINT32                  Count)
1086 {
1087     UINT32                  i;
1088 
1089 
1090     for (i = 0; i < Count; i++)
1091     {
1092         RepairedName[i] = (char) Name[i];
1093 
1094         if (!Name[i])
1095         {
1096             return;
1097         }
1098         if (!isprint (Name[i]))
1099         {
1100             RepairedName[i] = ' ';
1101         }
1102     }
1103 }
1104