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