xref: /freebsd/sys/contrib/dev/acpica/common/dmtable.c (revision 8a166cafe0965f6bd72cd3d2f5372704f05cb5e8)
1 /******************************************************************************
2  *
3  * Module Name: dmtable - Support for ACPI tables that contain no AML code
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2013, 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, DtCompileCsrt,  TemplateCsrt,   "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_TPM2, AcpiDmTableInfoTpm2,    NULL,           NULL,           TemplateTpm2,   "Trusted Platform Module hardware interface table"},
314     {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           DtCompileUefi,  TemplateUefi,   "UEFI Boot Optimization Table"},
315     {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           NULL,           TemplateWaet,   "Windows ACPI Emulated Devices Table"},
316     {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, DtCompileWdat,  TemplateWdat,   "Watchdog Action Table"},
317     {ACPI_SIG_WDDT, AcpiDmTableInfoWddt,    NULL,           NULL,           TemplateWddt,   "Watchdog Description Table"},
318     {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           NULL,           TemplateWdrt,   "Watchdog Resource Table"},
319     {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, DtCompileXsdt,  TemplateXsdt,   "Extended System Description Table"},
320     {NULL,          NULL,                   NULL,           NULL,           NULL,           NULL}
321 };
322 
323 
324 /*******************************************************************************
325  *
326  * FUNCTION:    AcpiDmGenerateChecksum
327  *
328  * PARAMETERS:  Table               - Pointer to table to be checksummed
329  *              Length              - Length of the table
330  *              OriginalChecksum    - Value of the checksum field
331  *
332  * RETURN:      8 bit checksum of buffer
333  *
334  * DESCRIPTION: Computes an 8 bit checksum of the table.
335  *
336  ******************************************************************************/
337 
338 UINT8
339 AcpiDmGenerateChecksum (
340     void                    *Table,
341     UINT32                  Length,
342     UINT8                   OriginalChecksum)
343 {
344     UINT8                   Checksum;
345 
346 
347     /* Sum the entire table as-is */
348 
349     Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
350 
351     /* Subtract off the existing checksum value in the table */
352 
353     Checksum = (UINT8) (Checksum - OriginalChecksum);
354 
355     /* Compute the final checksum */
356 
357     Checksum = (UINT8) (0 - Checksum);
358     return (Checksum);
359 }
360 
361 
362 /*******************************************************************************
363  *
364  * FUNCTION:    AcpiDmGetTableData
365  *
366  * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
367  *
368  * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
369  *
370  * DESCRIPTION: Find a match in the global table of supported ACPI tables
371  *
372  ******************************************************************************/
373 
374 ACPI_DMTABLE_DATA *
375 AcpiDmGetTableData (
376     char                    *Signature)
377 {
378     ACPI_DMTABLE_DATA       *TableData;
379 
380 
381     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
382     {
383         if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
384         {
385             return (TableData);
386         }
387     }
388 
389     return (NULL);
390 }
391 
392 
393 /*******************************************************************************
394  *
395  * FUNCTION:    AcpiDmDumpDataTable
396  *
397  * PARAMETERS:  Table               - An ACPI table
398  *
399  * RETURN:      None.
400  *
401  * DESCRIPTION: Format the contents of an ACPI data table (any table other
402  *              than an SSDT or DSDT that does not contain executable AML code)
403  *
404  ******************************************************************************/
405 
406 void
407 AcpiDmDumpDataTable (
408     ACPI_TABLE_HEADER       *Table)
409 {
410     ACPI_STATUS             Status;
411     ACPI_DMTABLE_DATA       *TableData;
412     UINT32                  Length;
413 
414 
415     /* Ignore tables that contain AML */
416 
417     if (AcpiUtIsAmlTable (Table))
418     {
419         if (Gbl_VerboseTemplates)
420         {
421             /* Dump the raw table data */
422 
423             Length = Table->Length;
424 
425             AcpiOsPrintf ("\n/*\n%s: Length %d (0x%X)\n\n",
426                 ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
427             AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
428                 Length, DB_BYTE_DISPLAY, 0);
429             AcpiOsPrintf (" */\n");
430         }
431         return;
432     }
433 
434     /*
435      * Handle tables that don't use the common ACPI table header structure.
436      * Currently, these are the FACS, RSDP, and S3PT.
437      */
438     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
439     {
440         Length = Table->Length;
441         AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
442     }
443     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
444     {
445         Length = AcpiDmDumpRsdp (Table);
446     }
447     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT))
448     {
449         Length = AcpiDmDumpS3pt (Table);
450     }
451     else
452     {
453         /*
454          * All other tables must use the common ACPI table header, dump it now
455          */
456         Length = Table->Length;
457         Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
458         if (ACPI_FAILURE (Status))
459         {
460             return;
461         }
462         AcpiOsPrintf ("\n");
463 
464         /* Match signature and dispatch appropriately */
465 
466         TableData = AcpiDmGetTableData (Table->Signature);
467         if (!TableData)
468         {
469             if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
470             {
471                 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
472                     Table->Signature);
473             }
474             else
475             {
476                 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
477                     Table->Signature);
478             }
479         }
480         else if (TableData->TableHandler)
481         {
482             /* Complex table, has a handler */
483 
484             TableData->TableHandler (Table);
485         }
486         else if (TableData->TableInfo)
487         {
488             /* Simple table, just walk the info table */
489 
490             AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
491         }
492     }
493 
494     if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
495     {
496         /* Dump the raw table data */
497 
498         AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
499             ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
500         AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
501             Length, DB_BYTE_DISPLAY, 0);
502     }
503 }
504 
505 
506 /*******************************************************************************
507  *
508  * FUNCTION:    AcpiDmLineHeader
509  *
510  * PARAMETERS:  Offset              - Current byte offset, from table start
511  *              ByteLength          - Length of the field in bytes, 0 for flags
512  *              Name                - Name of this field
513  *              Value               - Optional value, displayed on left of ':'
514  *
515  * RETURN:      None
516  *
517  * DESCRIPTION: Utility routines for formatting output lines. Displays the
518  *              current table offset in hex and decimal, the field length,
519  *              and the field name.
520  *
521  ******************************************************************************/
522 
523 void
524 AcpiDmLineHeader (
525     UINT32                  Offset,
526     UINT32                  ByteLength,
527     char                    *Name)
528 {
529 
530     /* Allow a null name for fields that span multiple lines (large buffers) */
531 
532     if (!Name)
533     {
534         Name = "";
535     }
536 
537     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
538     {
539         if (ByteLength)
540         {
541             AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name);
542         }
543         else
544         {
545             if (*Name)
546             {
547                 AcpiOsPrintf ("%41s : ", Name);
548             }
549             else
550             {
551                 AcpiOsPrintf ("%41s   ", Name);
552             }
553         }
554     }
555     else /* Normal disassembler or verbose template */
556     {
557         if (ByteLength)
558         {
559             AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ",
560                 Offset, Offset, ByteLength, Name);
561         }
562         else
563         {
564             if (*Name)
565             {
566                 AcpiOsPrintf ("%44s : ", Name);
567             }
568             else
569             {
570                 AcpiOsPrintf ("%44s   ", Name);
571             }
572         }
573     }
574 }
575 
576 void
577 AcpiDmLineHeader2 (
578     UINT32                  Offset,
579     UINT32                  ByteLength,
580     char                    *Name,
581     UINT32                  Value)
582 {
583 
584     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
585     {
586         if (ByteLength)
587         {
588             AcpiOsPrintf ("[%.4d] %30s %3d : ",
589                 ByteLength, Name, Value);
590         }
591         else
592         {
593             AcpiOsPrintf ("%36s % 3d : ",
594                 Name, Value);
595         }
596     }
597     else /* Normal disassembler or verbose template */
598     {
599         if (ByteLength)
600         {
601             AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ",
602                 Offset, Offset, ByteLength, Name, Value);
603         }
604         else
605         {
606             AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s %3d : ",
607                 Offset, Offset, Name, Value);
608         }
609     }
610 }
611 
612 
613 /*******************************************************************************
614  *
615  * FUNCTION:    AcpiDmDumpTable
616  *
617  * PARAMETERS:  TableLength         - Length of the entire ACPI table
618  *              TableOffset         - Starting offset within the table for this
619  *                                    sub-descriptor (0 if main table)
620  *              Table               - The ACPI table
621  *              SubtableLength      - Length of this sub-descriptor
622  *              Info                - Info table for this ACPI table
623  *
624  * RETURN:      None
625  *
626  * DESCRIPTION: Display ACPI table contents by walking the Info table.
627  *
628  * Note: This function must remain in sync with DtGetFieldLength.
629  *
630  ******************************************************************************/
631 
632 ACPI_STATUS
633 AcpiDmDumpTable (
634     UINT32                  TableLength,
635     UINT32                  TableOffset,
636     void                    *Table,
637     UINT32                  SubtableLength,
638     ACPI_DMTABLE_INFO       *Info)
639 {
640     UINT8                   *Target;
641     UINT32                  CurrentOffset;
642     UINT32                  ByteLength;
643     UINT8                   Temp8;
644     UINT16                  Temp16;
645     ACPI_DMTABLE_DATA       *TableData;
646     const char              *Name;
647     BOOLEAN                 LastOutputBlankLine = FALSE;
648     char                    RepairedName[8];
649 
650 
651     if (!Info)
652     {
653         AcpiOsPrintf ("Display not implemented\n");
654         return (AE_NOT_IMPLEMENTED);
655     }
656 
657     /* Walk entire Info table; Null name terminates */
658 
659     for (; Info->Name; Info++)
660     {
661         /*
662          * Target points to the field within the ACPI Table. CurrentOffset is
663          * the offset of the field from the start of the main table.
664          */
665         Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
666         CurrentOffset = TableOffset + Info->Offset;
667 
668         /* Check for beyond EOT or beyond subtable end */
669 
670         if ((CurrentOffset >= TableLength) ||
671             (SubtableLength && (Info->Offset >= SubtableLength)))
672         {
673             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
674             return (AE_BAD_DATA);
675         }
676 
677         /* Generate the byte length for this field */
678 
679         switch (Info->Opcode)
680         {
681         case ACPI_DMT_UINT8:
682         case ACPI_DMT_CHKSUM:
683         case ACPI_DMT_SPACEID:
684         case ACPI_DMT_ACCWIDTH:
685         case ACPI_DMT_IVRS:
686         case ACPI_DMT_MADT:
687         case ACPI_DMT_PMTT:
688         case ACPI_DMT_SRAT:
689         case ACPI_DMT_ASF:
690         case ACPI_DMT_HESTNTYP:
691         case ACPI_DMT_FADTPM:
692         case ACPI_DMT_EINJACT:
693         case ACPI_DMT_EINJINST:
694         case ACPI_DMT_ERSTACT:
695         case ACPI_DMT_ERSTINST:
696             ByteLength = 1;
697             break;
698         case ACPI_DMT_UINT16:
699         case ACPI_DMT_DMAR:
700         case ACPI_DMT_HEST:
701             ByteLength = 2;
702             break;
703         case ACPI_DMT_UINT24:
704             ByteLength = 3;
705             break;
706         case ACPI_DMT_UINT32:
707         case ACPI_DMT_NAME4:
708         case ACPI_DMT_SIG:
709         case ACPI_DMT_SLIC:
710             ByteLength = 4;
711             break;
712         case ACPI_DMT_UINT40:
713             ByteLength = 5;
714             break;
715         case ACPI_DMT_UINT48:
716         case ACPI_DMT_NAME6:
717             ByteLength = 6;
718             break;
719         case ACPI_DMT_UINT56:
720         case ACPI_DMT_BUF7:
721             ByteLength = 7;
722             break;
723         case ACPI_DMT_UINT64:
724         case ACPI_DMT_NAME8:
725             ByteLength = 8;
726             break;
727         case ACPI_DMT_BUF16:
728         case ACPI_DMT_UUID:
729             ByteLength = 16;
730             break;
731         case ACPI_DMT_BUF128:
732             ByteLength = 128;
733             break;
734         case ACPI_DMT_STRING:
735             ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
736             break;
737         case ACPI_DMT_GAS:
738             if (!LastOutputBlankLine)
739             {
740                 AcpiOsPrintf ("\n");
741                 LastOutputBlankLine = TRUE;
742             }
743             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
744             break;
745         case ACPI_DMT_HESTNTFY:
746             if (!LastOutputBlankLine)
747             {
748                 AcpiOsPrintf ("\n");
749                 LastOutputBlankLine = TRUE;
750             }
751             ByteLength = sizeof (ACPI_HEST_NOTIFY);
752             break;
753         default:
754             ByteLength = 0;
755             break;
756         }
757 
758         if (CurrentOffset + ByteLength > TableLength)
759         {
760             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
761             return (AE_BAD_DATA);
762         }
763 
764         if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
765         {
766             AcpiOsPrintf ("%s", Info->Name);
767             continue;
768         }
769 
770         /* Start a new line and decode the opcode */
771 
772         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
773 
774         switch (Info->Opcode)
775         {
776         /* Single-bit Flag fields. Note: Opcode is the bit position */
777 
778         case ACPI_DMT_FLAG0:
779         case ACPI_DMT_FLAG1:
780         case ACPI_DMT_FLAG2:
781         case ACPI_DMT_FLAG3:
782         case ACPI_DMT_FLAG4:
783         case ACPI_DMT_FLAG5:
784         case ACPI_DMT_FLAG6:
785         case ACPI_DMT_FLAG7:
786 
787             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
788             break;
789 
790         /* 2-bit Flag fields */
791 
792         case ACPI_DMT_FLAGS0:
793 
794             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
795             break;
796 
797         case ACPI_DMT_FLAGS1:
798 
799             AcpiOsPrintf ("%1.1X\n", (*Target >> 1) & 0x03);
800             break;
801 
802         case ACPI_DMT_FLAGS2:
803 
804             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
805             break;
806 
807         case ACPI_DMT_FLAGS4:
808 
809             AcpiOsPrintf ("%1.1X\n", (*Target >> 4) & 0x03);
810             break;
811 
812         /* Integer Data Types */
813 
814         case ACPI_DMT_UINT8:
815         case ACPI_DMT_UINT16:
816         case ACPI_DMT_UINT24:
817         case ACPI_DMT_UINT32:
818         case ACPI_DMT_UINT40:
819         case ACPI_DMT_UINT48:
820         case ACPI_DMT_UINT56:
821         case ACPI_DMT_UINT64:
822             /*
823              * Dump bytes - high byte first, low byte last.
824              * Note: All ACPI tables are little-endian.
825              */
826             for (Temp8 = (UINT8) ByteLength; Temp8 > 0; Temp8--)
827             {
828                 AcpiOsPrintf ("%2.2X", Target[Temp8 - 1]);
829             }
830             AcpiOsPrintf ("\n");
831             break;
832 
833         case ACPI_DMT_BUF7:
834         case ACPI_DMT_BUF16:
835         case ACPI_DMT_BUF128:
836 
837             /*
838              * Buffer: Size depends on the opcode and was set above.
839              * Each hex byte is separated with a space.
840              * Multiple lines are separated by line continuation char.
841              */
842             for (Temp16 = 0; Temp16 < ByteLength; Temp16++)
843             {
844                 AcpiOsPrintf ("%2.2X", Target[Temp16]);
845                 if ((UINT32) (Temp16 + 1) < ByteLength)
846                 {
847                     if ((Temp16 > 0) && (!((Temp16+1) % 16)))
848                     {
849                         AcpiOsPrintf (" \\\n"); /* Line continuation */
850                         AcpiDmLineHeader (0, 0, NULL);
851                     }
852                     else
853                     {
854                         AcpiOsPrintf (" ");
855                     }
856                 }
857             }
858             AcpiOsPrintf ("\n");
859             break;
860 
861         case ACPI_DMT_UUID:
862 
863             /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
864 
865             (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
866 
867             AcpiOsPrintf ("%s\n", MsgBuffer);
868             break;
869 
870         case ACPI_DMT_STRING:
871 
872             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
873             break;
874 
875         /* Fixed length ASCII name fields */
876 
877         case ACPI_DMT_SIG:
878 
879             AcpiDmCheckAscii (Target, RepairedName, 4);
880             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
881             TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
882             if (TableData)
883             {
884                 AcpiOsPrintf (STRING_FORMAT, TableData->Name);
885             }
886             else
887             {
888                 AcpiOsPrintf ("\n");
889             }
890             break;
891 
892         case ACPI_DMT_NAME4:
893 
894             AcpiDmCheckAscii (Target, RepairedName, 4);
895             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
896             break;
897 
898         case ACPI_DMT_NAME6:
899 
900             AcpiDmCheckAscii (Target, RepairedName, 6);
901             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
902             break;
903 
904         case ACPI_DMT_NAME8:
905 
906             AcpiDmCheckAscii (Target, RepairedName, 8);
907             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
908             break;
909 
910         /* Special Data Types */
911 
912         case ACPI_DMT_CHKSUM:
913 
914             /* Checksum, display and validate */
915 
916             AcpiOsPrintf ("%2.2X", *Target);
917             Temp8 = AcpiDmGenerateChecksum (Table,
918                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
919                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
920             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
921             {
922                 AcpiOsPrintf (
923                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
924             }
925             AcpiOsPrintf ("\n");
926             break;
927 
928         case ACPI_DMT_SPACEID:
929 
930             /* Address Space ID */
931 
932             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target));
933             break;
934 
935         case ACPI_DMT_ACCWIDTH:
936 
937             /* Encoded Access Width */
938 
939             Temp8 = *Target;
940             if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
941             {
942                 Temp8 = ACPI_GAS_WIDTH_RESERVED;
943             }
944 
945             AcpiOsPrintf (UINT8_FORMAT, Temp8, AcpiDmGasAccessWidth[Temp8]);
946             break;
947 
948         case ACPI_DMT_GAS:
949 
950             /* Generic Address Structure */
951 
952             AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure");
953             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
954                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
955             AcpiOsPrintf ("\n");
956             LastOutputBlankLine = TRUE;
957             break;
958 
959         case ACPI_DMT_ASF:
960 
961             /* ASF subtable types */
962 
963             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
964             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
965             {
966                 Temp16 = ACPI_ASF_TYPE_RESERVED;
967             }
968 
969             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]);
970             break;
971 
972         case ACPI_DMT_DMAR:
973 
974             /* DMAR subtable types */
975 
976             Temp16 = ACPI_GET16 (Target);
977             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
978             {
979                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
980             }
981 
982             AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
983             break;
984 
985         case ACPI_DMT_EINJACT:
986 
987             /* EINJ Action types */
988 
989             Temp8 = *Target;
990             if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
991             {
992                 Temp8 = ACPI_EINJ_ACTION_RESERVED;
993             }
994 
995             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjActions[Temp8]);
996             break;
997 
998         case ACPI_DMT_EINJINST:
999 
1000             /* EINJ Instruction types */
1001 
1002             Temp8 = *Target;
1003             if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
1004             {
1005                 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
1006             }
1007 
1008             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjInstructions[Temp8]);
1009             break;
1010 
1011         case ACPI_DMT_ERSTACT:
1012 
1013             /* ERST Action types */
1014 
1015             Temp8 = *Target;
1016             if (Temp8 > ACPI_ERST_ACTION_RESERVED)
1017             {
1018                 Temp8 = ACPI_ERST_ACTION_RESERVED;
1019             }
1020 
1021             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstActions[Temp8]);
1022             break;
1023 
1024         case ACPI_DMT_ERSTINST:
1025 
1026             /* ERST Instruction types */
1027 
1028             Temp8 = *Target;
1029             if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
1030             {
1031                 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
1032             }
1033 
1034             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstInstructions[Temp8]);
1035             break;
1036 
1037         case ACPI_DMT_HEST:
1038 
1039             /* HEST subtable types */
1040 
1041             Temp16 = ACPI_GET16 (Target);
1042             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
1043             {
1044                 Temp16 = ACPI_HEST_TYPE_RESERVED;
1045             }
1046 
1047             AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
1048             break;
1049 
1050         case ACPI_DMT_HESTNTFY:
1051 
1052             AcpiOsPrintf (STRING_FORMAT, "Hardware Error Notification Structure");
1053             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1054                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
1055             AcpiOsPrintf ("\n");
1056             LastOutputBlankLine = TRUE;
1057             break;
1058 
1059         case ACPI_DMT_HESTNTYP:
1060 
1061             /* HEST Notify types */
1062 
1063             Temp8 = *Target;
1064             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1065             {
1066                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1067             }
1068 
1069             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmHestNotifySubnames[Temp8]);
1070             break;
1071 
1072         case ACPI_DMT_MADT:
1073 
1074             /* MADT subtable types */
1075 
1076             Temp8 = *Target;
1077             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1078             {
1079                 Temp8 = ACPI_MADT_TYPE_RESERVED;
1080             }
1081 
1082             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]);
1083             break;
1084 
1085         case ACPI_DMT_PMTT:
1086 
1087             /* PMTT subtable types */
1088 
1089             Temp8 = *Target;
1090             if (Temp8 > ACPI_PMTT_TYPE_RESERVED)
1091             {
1092                 Temp8 = ACPI_PMTT_TYPE_RESERVED;
1093             }
1094 
1095             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmPmttSubnames[Temp8]);
1096             break;
1097 
1098         case ACPI_DMT_SLIC:
1099 
1100             /* SLIC subtable types */
1101 
1102             Temp8 = *Target;
1103             if (Temp8 > ACPI_SLIC_TYPE_RESERVED)
1104             {
1105                 Temp8 = ACPI_SLIC_TYPE_RESERVED;
1106             }
1107 
1108             AcpiOsPrintf (UINT32_FORMAT, *Target, AcpiDmSlicSubnames[Temp8]);
1109             break;
1110 
1111         case ACPI_DMT_SRAT:
1112 
1113             /* SRAT subtable types */
1114 
1115             Temp8 = *Target;
1116             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1117             {
1118                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
1119             }
1120 
1121             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmSratSubnames[Temp8]);
1122             break;
1123 
1124         case ACPI_DMT_FADTPM:
1125 
1126             /* FADT Preferred PM Profile names */
1127 
1128             Temp8 = *Target;
1129             if (Temp8 > ACPI_FADT_PM_RESERVED)
1130             {
1131                 Temp8 = ACPI_FADT_PM_RESERVED;
1132             }
1133 
1134             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmFadtProfiles[Temp8]);
1135             break;
1136 
1137         case ACPI_DMT_IVRS:
1138 
1139             /* IVRS subtable types */
1140 
1141             Temp8 = *Target;
1142             switch (Temp8)
1143             {
1144             case ACPI_IVRS_TYPE_HARDWARE:
1145                 Name = AcpiDmIvrsSubnames[0];
1146                 break;
1147 
1148             case ACPI_IVRS_TYPE_MEMORY1:
1149             case ACPI_IVRS_TYPE_MEMORY2:
1150             case ACPI_IVRS_TYPE_MEMORY3:
1151                 Name = AcpiDmIvrsSubnames[1];
1152                 break;
1153 
1154             default:
1155                 Name = AcpiDmIvrsSubnames[2];
1156                 break;
1157             }
1158 
1159             AcpiOsPrintf (UINT8_FORMAT, *Target, Name);
1160             break;
1161 
1162         case ACPI_DMT_EXIT:
1163             return (AE_OK);
1164 
1165         default:
1166             ACPI_ERROR ((AE_INFO,
1167                 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1168             return (AE_SUPPORT);
1169         }
1170     }
1171 
1172     if (TableOffset && !SubtableLength)
1173     {
1174         /* If this table is not the main table, subtable must have valid length */
1175 
1176         AcpiOsPrintf ("Invalid zero length subtable\n");
1177         return (AE_BAD_DATA);
1178     }
1179 
1180     return (AE_OK);
1181 }
1182 
1183 
1184 /*******************************************************************************
1185  *
1186  * FUNCTION:    AcpiDmCheckAscii
1187  *
1188  * PARAMETERS:  Name                - Ascii string
1189  *              Count               - Number of characters to check
1190  *
1191  * RETURN:      None
1192  *
1193  * DESCRIPTION: Ensure that the requested number of characters are printable
1194  *              Ascii characters. Sets non-printable and null chars to <space>.
1195  *
1196  ******************************************************************************/
1197 
1198 static void
1199 AcpiDmCheckAscii (
1200     UINT8                   *Name,
1201     char                    *RepairedName,
1202     UINT32                  Count)
1203 {
1204     UINT32                  i;
1205 
1206 
1207     for (i = 0; i < Count; i++)
1208     {
1209         RepairedName[i] = (char) Name[i];
1210 
1211         if (!Name[i])
1212         {
1213             return;
1214         }
1215         if (!isprint (Name[i]))
1216         {
1217             RepairedName[i] = ' ';
1218         }
1219     }
1220 }
1221