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