]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/contrib/dev/acpica/common/dmtable.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / contrib / dev / acpica / common / dmtable.c
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 }