Bring in acpica 20110211, still not ok anyway
[dragonfly.git] / sys / contrib / dev / acpica-unix / common / dmtable.c
1 /******************************************************************************
2  *
3  * Module Name: dmtable - Support for ACPI tables that contain no AML code
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115
116 #include "acpi.h"
117 #include "accommon.h"
118 #include "acdisasm.h"
119 #include "actables.h"
120 #include "aslcompiler.h"
121 #include "dtcompiler.h"
122
123 /* This module used for application-level code only */
124
125 #define _COMPONENT          ACPI_CA_DISASSEMBLER
126         ACPI_MODULE_NAME    ("dmtable")
127
128 /* Local Prototypes */
129
130 static void
131 AcpiDmCheckAscii (
132     UINT8                   *Target,
133     char                    *RepairedName,
134     UINT32                  Count);
135
136
137 /* These tables map a subtable type to a description string */
138
139 static const char           *AcpiDmAsfSubnames[] =
140 {
141     "ASF Information",
142     "ASF Alerts",
143     "ASF Remote Control",
144     "ASF RMCP Boot Options",
145     "ASF Address",
146     "Unknown SubTable Type"         /* Reserved */
147 };
148
149 static const char           *AcpiDmDmarSubnames[] =
150 {
151     "Hardware Unit Definition",
152     "Reserved Memory Region",
153     "Root Port ATS Capability",
154     "Remapping Hardware Static Affinity",
155     "Unknown SubTable Type"         /* Reserved */
156 };
157
158 static const char           *AcpiDmEinjActions[] =
159 {
160     "Begin Operation",
161     "Get Trigger Table",
162     "Set Error Type",
163     "Get Error Type",
164     "End Operation",
165     "Execute Operation",
166     "Check Busy Status",
167     "Get Command Status",
168     "Unknown Action"
169 };
170
171 static const char           *AcpiDmEinjInstructions[] =
172 {
173     "Read Register",
174     "Read Register Value",
175     "Write Register",
176     "Write Register Value",
177     "Noop",
178     "Unknown Instruction"
179 };
180
181 static const char           *AcpiDmErstActions[] =
182 {
183     "Begin Write Operation",
184     "Begin Read Operation",
185     "Begin Clear Operation",
186     "End Operation",
187     "Set Record Offset",
188     "Execute Operation",
189     "Check Busy Status",
190     "Get Command Status",
191     "Get Record Identifier",
192     "Set Record Identifier",
193     "Get Record Count",
194     "Begin Dummy Write",
195     "Unused/Unknown Action",
196     "Get Error Address Range",
197     "Get Error Address Length",
198     "Get Error Attributes",
199     "Unknown Action"
200 };
201
202 static const char           *AcpiDmErstInstructions[] =
203 {
204     "Read Register",
205     "Read Register Value",
206     "Write Register",
207     "Write Register Value",
208     "Noop",
209     "Load Var1",
210     "Load Var2",
211     "Store Var1",
212     "Add",
213     "Subtract",
214     "Add Value",
215     "Subtract Value",
216     "Stall",
217     "Stall While True",
218     "Skip Next If True",
219     "GoTo",
220     "Set Source Address",
221     "Set Destination Address",
222     "Move Data",
223     "Unknown Instruction"
224 };
225
226 static const char           *AcpiDmHestSubnames[] =
227 {
228     "IA-32 Machine Check Exception",
229     "IA-32 Corrected Machine Check",
230     "IA-32 Non-Maskable Interrupt",
231     "Unknown SubTable Type",        /* 3 - Reserved */
232     "Unknown SubTable Type",        /* 4 - Reserved */
233     "Unknown SubTable Type",        /* 5 - Reserved */
234     "PCI Express Root Port AER",
235     "PCI Express AER (AER Endpoint)",
236     "PCI Express/PCI-X Bridge AER",
237     "Generic Hardware Error Source",
238     "Unknown SubTable Type"         /* Reserved */
239 };
240
241 static const char           *AcpiDmHestNotifySubnames[] =
242 {
243     "Polled",
244     "External Interrupt",
245     "Local Interrupt",
246     "SCI",
247     "NMI",
248     "Unknown Notify Type"           /* Reserved */
249 };
250
251 static const char           *AcpiDmMadtSubnames[] =
252 {
253     "Processor Local APIC",         /* ACPI_MADT_TYPE_LOCAL_APIC */
254     "I/O APIC",                     /* ACPI_MADT_TYPE_IO_APIC */
255     "Interrupt Source Override",    /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */
256     "NMI Source",                   /* ACPI_MADT_TYPE_NMI_SOURCE */
257     "Local APIC NMI",               /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */
258     "Local APIC Address Override",  /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */
259     "I/O SAPIC",                    /* ACPI_MADT_TYPE_IO_SAPIC */
260     "Local SAPIC",                  /* ACPI_MADT_TYPE_LOCAL_SAPIC */
261     "Platform Interrupt Sources",   /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
262     "Processor Local x2APIC",       /* ACPI_MADT_TYPE_LOCAL_X2APIC */
263     "Local x2APIC NMI",             /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
264     "Unknown SubTable Type"         /* Reserved */
265 };
266
267 static const char           *AcpiDmSratSubnames[] =
268 {
269     "Processor Local APIC/SAPIC Affinity",
270     "Memory Affinity",
271     "Processor Local x2APIC Affinity",
272     "Unknown SubTable Type"         /* Reserved */
273 };
274
275 static const char           *AcpiDmIvrsSubnames[] =
276 {
277     "Hardware Definition Block",
278     "Memory Definition Block",
279     "Unknown SubTable Type"         /* Reserved */
280 };
281
282
283 #define ACPI_FADT_PM_RESERVED       8
284
285 static const char           *AcpiDmFadtProfiles[] =
286 {
287     "Unspecified",
288     "Desktop",
289     "Mobile",
290     "Workstation",
291     "Enterprise Server",
292     "SOHO Server",
293     "Appliance PC",
294     "Performance Server",
295     "Unknown Profile Type"
296 };
297
298 #define ACPI_GAS_WIDTH_RESERVED     5
299
300 static const char           *AcpiDmGasAccessWidth[] =
301 {
302     "Undefined/Legacy",
303     "Byte Access:8",
304     "Word Access:16",
305     "DWord Access:32",
306     "QWord Access:64",
307     "Unknown Width Encoding"
308 };
309
310
311 /*******************************************************************************
312  *
313  * ACPI Table Data, indexed by signature.
314  *
315  * Each entry contains: Signature, Table Info, Handler, DtHandler,
316  *  Template, Description
317  *
318  * Simple tables have only a TableInfo structure, complex tables have a
319  * handler. This table must be NULL terminated. RSDP and FACS are
320  * special-cased elsewhere.
321  *
322  ******************************************************************************/
323
324 ACPI_DMTABLE_DATA    AcpiDmTableData[] =
325 {
326     {ACPI_SIG_ASF,  NULL,                   AcpiDmDumpAsf,  DtCompileAsf,   TemplateAsf,    "Alert Standard Format table"},
327     {ACPI_SIG_BOOT, AcpiDmTableInfoBoot,    NULL,           NULL,           TemplateBoot,   "Simple Boot Flag Table"},
328     {ACPI_SIG_BERT, AcpiDmTableInfoBert,    NULL,           NULL,           TemplateBert,   "Boot Error Record Table"},
329     {ACPI_SIG_CPEP, NULL,                   AcpiDmDumpCpep, DtCompileCpep,  TemplateCpep,   "Corrected Platform Error Polling table"},
330     {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp,    NULL,           NULL,           TemplateDbgp,   "Debug Port table"},
331     {ACPI_SIG_DMAR, NULL,                   AcpiDmDumpDmar, DtCompileDmar,  TemplateDmar,   "DMA Remapping table"},
332     {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt,    NULL,           NULL,           TemplateEcdt,   "Embedded Controller Boot Resources Table"},
333     {ACPI_SIG_EINJ, NULL,                   AcpiDmDumpEinj, DtCompileEinj,  TemplateEinj,   "Error Injection table"},
334     {ACPI_SIG_ERST, NULL,                   AcpiDmDumpErst, DtCompileErst,  TemplateErst,   "Error Record Serialization Table"},
335     {ACPI_SIG_FADT, NULL,                   AcpiDmDumpFadt, DtCompileFadt,  TemplateFadt,   "Fixed ACPI Description Table"},
336     {ACPI_SIG_HEST, NULL,                   AcpiDmDumpHest, DtCompileHest,  TemplateHest,   "Hardware Error Source Table"},
337     {ACPI_SIG_HPET, AcpiDmTableInfoHpet,    NULL,           NULL,           TemplateHpet,   "High Precision Event Timer table"},
338     {ACPI_SIG_IVRS, NULL,                   AcpiDmDumpIvrs, DtCompileIvrs,  TemplateIvrs,   "I/O Virtualization Reporting Structure"},
339     {ACPI_SIG_MADT, NULL,                   AcpiDmDumpMadt, DtCompileMadt,  TemplateMadt,   "Multiple APIC Description Table"},
340     {ACPI_SIG_MCFG, NULL,                   AcpiDmDumpMcfg, DtCompileMcfg,  TemplateMcfg,   "Memory Mapped Configuration table"},
341     {ACPI_SIG_MCHI, AcpiDmTableInfoMchi,    NULL,           NULL,           TemplateMchi,   "Management Controller Host Interface table"},
342     {ACPI_SIG_MSCT, NULL,                   AcpiDmDumpMsct, DtCompileMsct,  TemplateMsct,   "Maximum System Characteristics Table"},
343     {ACPI_SIG_RSDT, NULL,                   AcpiDmDumpRsdt, DtCompileRsdt,  TemplateRsdt,   "Root System Description Table"},
344     {ACPI_SIG_SBST, AcpiDmTableInfoSbst,    NULL,           NULL,           TemplateSbst,   "Smart Battery Specification Table"},
345     {ACPI_SIG_SLIC, AcpiDmTableInfoSlic,    NULL,           NULL,           NULL,           "Software Licensing Description Table"},
346     {ACPI_SIG_SLIT, NULL,                   AcpiDmDumpSlit, DtCompileSlit,  TemplateSlit,   "System Locality Information Table"},
347     {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr,    NULL,           NULL,           TemplateSpcr,   "Serial Port Console Redirection table"},
348     {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi,    NULL,           NULL,           TemplateSpmi,   "Server Platform Management Interface table"},
349     {ACPI_SIG_SRAT, NULL,                   AcpiDmDumpSrat, DtCompileSrat,  TemplateSrat,   "System Resource Affinity Table"},
350     {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa,    NULL,           NULL,           TemplateTcpa,   "Trusted Computing Platform Alliance table"},
351     {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           DtCompileUefi,  TemplateUefi,   "UEFI Boot Optimization Table"},
352     {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           NULL,           TemplateWaet,   "Windows ACPI Emulated Devices Table"},
353     {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, DtCompileWdat,  TemplateWdat,   "Watchdog Action Table"},
354     {ACPI_SIG_WDDT, AcpiDmTableInfoWddt,    NULL,           NULL,           TemplateWddt,   "Watchdog Description Table"},
355     {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           NULL,           TemplateWdrt,   "Watchdog Resource Table"},
356     {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, DtCompileXsdt,  TemplateXsdt,   "Extended System Description Table"},
357     {NULL,          NULL,                   NULL,           NULL,           NULL,           NULL}
358 };
359
360
361 /*******************************************************************************
362  *
363  * FUNCTION:    AcpiDmGenerateChecksum
364  *
365  * PARAMETERS:  Table               - Pointer to table to be checksummed
366  *              Length              - Length of the table
367  *              OriginalChecksum    - Value of the checksum field
368  *
369  * RETURN:      8 bit checksum of buffer
370  *
371  * DESCRIPTION: Computes an 8 bit checksum of the table.
372  *
373  ******************************************************************************/
374
375 UINT8
376 AcpiDmGenerateChecksum (
377     void                    *Table,
378     UINT32                  Length,
379     UINT8                   OriginalChecksum)
380 {
381     UINT8                   Checksum;
382
383
384     /* Sum the entire table as-is */
385
386     Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
387
388     /* Subtract off the existing checksum value in the table */
389
390     Checksum = (UINT8) (Checksum - OriginalChecksum);
391
392     /* Compute the final checksum */
393
394     Checksum = (UINT8) (0 - Checksum);
395     return (Checksum);
396 }
397
398
399 /*******************************************************************************
400  *
401  * FUNCTION:    AcpiDmGetTableData
402  *
403  * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
404  *
405  * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
406  *
407  * DESCRIPTION: Find a match in the global table of supported ACPI tables
408  *
409  ******************************************************************************/
410
411 ACPI_DMTABLE_DATA *
412 AcpiDmGetTableData (
413     char                    *Signature)
414 {
415     ACPI_DMTABLE_DATA       *TableData;
416
417
418     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
419     {
420         if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
421         {
422             return (TableData);
423         }
424     }
425
426     return (NULL);
427 }
428
429
430 /*******************************************************************************
431  *
432  * FUNCTION:    AcpiDmDumpDataTable
433  *
434  * PARAMETERS:  Table               - An ACPI table
435  *
436  * RETURN:      None.
437  *
438  * DESCRIPTION: Format the contents of an ACPI data table (any table other
439  *              than an SSDT or DSDT that does not contain executable AML code)
440  *
441  ******************************************************************************/
442
443 void
444 AcpiDmDumpDataTable (
445     ACPI_TABLE_HEADER       *Table)
446 {
447     ACPI_STATUS             Status;
448     ACPI_DMTABLE_DATA       *TableData;
449     UINT32                  Length;
450
451
452     /* Ignore tables that contain AML */
453
454     if (AcpiUtIsAmlTable (Table))
455     {
456         return;
457     }
458
459     /*
460      * Handle tables that don't use the common ACPI table header structure.
461      * Currently, these are the FACS and RSDP.
462      */
463     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
464     {
465         Length = Table->Length;
466         AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
467     }
468     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
469     {
470         Length = AcpiDmDumpRsdp (Table);
471     }
472     else
473     {
474         /*
475          * All other tables must use the common ACPI table header, dump it now
476          */
477         Length = Table->Length;
478         Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
479         if (ACPI_FAILURE (Status))
480         {
481             return;
482         }
483         AcpiOsPrintf ("\n");
484
485         /* Match signature and dispatch appropriately */
486
487         TableData = AcpiDmGetTableData (Table->Signature);
488         if (!TableData)
489         {
490             if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
491             {
492                 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
493                     Table->Signature);
494             }
495             else
496             {
497                 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
498                     Table->Signature);
499             }
500         }
501         else if (TableData->TableHandler)
502         {
503             /* Complex table, has a handler */
504
505             TableData->TableHandler (Table);
506         }
507         else if (TableData->TableInfo)
508         {
509             /* Simple table, just walk the info table */
510
511             AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
512         }
513     }
514
515     if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
516     {
517         /* Dump the raw table data */
518
519         AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
520             ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
521         AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
522     }
523 }
524
525
526 /*******************************************************************************
527  *
528  * FUNCTION:    AcpiDmLineHeader
529  *
530  * PARAMETERS:  Offset              - Current byte offset, from table start
531  *              ByteLength          - Length of the field in bytes, 0 for flags
532  *              Name                - Name of this field
533  *              Value               - Optional value, displayed on left of ':'
534  *
535  * RETURN:      None
536  *
537  * DESCRIPTION: Utility routines for formatting output lines. Displays the
538  *              current table offset in hex and decimal, the field length,
539  *              and the field name.
540  *
541  ******************************************************************************/
542
543 void
544 AcpiDmLineHeader (
545     UINT32                  Offset,
546     UINT32                  ByteLength,
547     char                    *Name)
548 {
549
550     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
551     {
552         if (ByteLength)
553         {
554             AcpiOsPrintf ("[%.3d] %34s : ",
555                 ByteLength, Name);
556         }
557         else
558         {
559             AcpiOsPrintf ("%40s : ",
560                 Name);
561         }
562     }
563     else /* Normal disassembler or verbose template */
564     {
565         if (ByteLength)
566         {
567             AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %28s : ",
568                 Offset, Offset, ByteLength, Name);
569         }
570         else
571         {
572             AcpiOsPrintf ("%43s : ",
573                 Name);
574         }
575     }
576 }
577
578 void
579 AcpiDmLineHeader2 (
580     UINT32                  Offset,
581     UINT32                  ByteLength,
582     char                    *Name,
583     UINT32                  Value)
584 {
585
586     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
587     {
588         if (ByteLength)
589         {
590             AcpiOsPrintf ("[%.3d] %30s % 3d : ",
591                 ByteLength, Name, Value);
592         }
593         else
594         {
595             AcpiOsPrintf ("%36s % 3d : ",
596                 Name, Value);
597         }
598     }
599     else /* Normal disassembler or verbose template */
600     {
601         if (ByteLength)
602         {
603             AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %24s % 3d : ",
604                 Offset, Offset, ByteLength, Name, Value);
605         }
606         else
607         {
608             AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s % 3d : ",
609                 Offset, Offset, Name, Value);
610         }
611     }
612 }
613
614
615 /*******************************************************************************
616  *
617  * FUNCTION:    AcpiDmDumpTable
618  *
619  * PARAMETERS:  TableLength         - Length of the entire ACPI table
620  *              TableOffset         - Starting offset within the table for this
621  *                                    sub-descriptor (0 if main table)
622  *              Table               - The ACPI table
623  *              SubtableLength      - Length of this sub-descriptor
624  *              Info                - Info table for this ACPI table
625  *
626  * RETURN:      None
627  *
628  * DESCRIPTION: Display ACPI table contents by walking the Info table.
629  *
630  * Note: This function must remain in sync with DtGetFieldLength.
631  *
632  ******************************************************************************/
633
634 ACPI_STATUS
635 AcpiDmDumpTable (
636     UINT32                  TableLength,
637     UINT32                  TableOffset,
638     void                    *Table,
639     UINT32                  SubtableLength,
640     ACPI_DMTABLE_INFO       *Info)
641 {
642     UINT8                   *Target;
643     UINT32                  CurrentOffset;
644     UINT32                  ByteLength;
645     UINT8                   Temp8;
646     UINT16                  Temp16;
647     ACPI_DMTABLE_DATA       *TableData;
648     const char              *Name;
649     BOOLEAN                 LastOutputBlankLine = FALSE;
650     char                    RepairedName[8];
651
652
653     if (!Info)
654     {
655         AcpiOsPrintf ("Display not implemented\n");
656         return (AE_NOT_IMPLEMENTED);
657     }
658
659     /* Walk entire Info table; Null name terminates */
660
661     for (; Info->Name; Info++)
662     {
663         /*
664          * Target points to the field within the ACPI Table. CurrentOffset is
665          * the offset of the field from the start of the main table.
666          */
667         Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
668         CurrentOffset = TableOffset + Info->Offset;
669
670         /* Check for beyond EOT or beyond subtable end */
671
672         if ((CurrentOffset >= TableLength) ||
673             (SubtableLength && (Info->Offset >= SubtableLength)))
674         {
675             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
676             return (AE_BAD_DATA);
677         }
678
679         /* Generate the byte length for this field */
680
681         switch (Info->Opcode)
682         {
683         case ACPI_DMT_UINT8:
684         case ACPI_DMT_CHKSUM:
685         case ACPI_DMT_SPACEID:
686         case ACPI_DMT_ACCWIDTH:
687         case ACPI_DMT_IVRS:
688         case ACPI_DMT_MADT:
689         case ACPI_DMT_SRAT:
690         case ACPI_DMT_ASF:
691         case ACPI_DMT_HESTNTYP:
692         case ACPI_DMT_FADTPM:
693         case ACPI_DMT_EINJACT:
694         case ACPI_DMT_EINJINST:
695         case ACPI_DMT_ERSTACT:
696         case ACPI_DMT_ERSTINST:
697             ByteLength = 1;
698             break;
699         case ACPI_DMT_UINT16:
700         case ACPI_DMT_DMAR:
701         case ACPI_DMT_HEST:
702             ByteLength = 2;
703             break;
704         case ACPI_DMT_UINT24:
705             ByteLength = 3;
706             break;
707         case ACPI_DMT_UINT32:
708         case ACPI_DMT_NAME4:
709         case ACPI_DMT_SIG:
710             ByteLength = 4;
711             break;
712         case ACPI_DMT_NAME6:
713             ByteLength = 6;
714             break;
715         case ACPI_DMT_UINT56:
716         case ACPI_DMT_BUF7:
717             ByteLength = 7;
718             break;
719         case ACPI_DMT_UINT64:
720         case ACPI_DMT_NAME8:
721             ByteLength = 8;
722             break;
723         case ACPI_DMT_BUF16:
724         case ACPI_DMT_UUID:
725             ByteLength = 16;
726             break;
727         case ACPI_DMT_STRING:
728             ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
729             break;
730         case ACPI_DMT_GAS:
731             if (!LastOutputBlankLine)
732             {
733                 AcpiOsPrintf ("\n");
734                 LastOutputBlankLine = TRUE;
735             }
736             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
737             break;
738         case ACPI_DMT_HESTNTFY:
739             if (!LastOutputBlankLine)
740             {
741                 AcpiOsPrintf ("\n");
742                 LastOutputBlankLine = TRUE;
743             }
744             ByteLength = sizeof (ACPI_HEST_NOTIFY);
745             break;
746         default:
747             ByteLength = 0;
748             break;
749         }
750
751         if (CurrentOffset + ByteLength > TableLength)
752         {
753             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
754             return (AE_BAD_DATA);
755         }
756
757         /* Start a new line and decode the opcode */
758
759         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
760
761         switch (Info->Opcode)
762         {
763         /* Single-bit Flag fields. Note: Opcode is the bit position */
764
765         case ACPI_DMT_FLAG0:
766         case ACPI_DMT_FLAG1:
767         case ACPI_DMT_FLAG2:
768         case ACPI_DMT_FLAG3:
769         case ACPI_DMT_FLAG4:
770         case ACPI_DMT_FLAG5:
771         case ACPI_DMT_FLAG6:
772         case ACPI_DMT_FLAG7:
773
774             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
775             break;
776
777         /* 2-bit Flag fields */
778
779         case ACPI_DMT_FLAGS0:
780
781             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
782             break;
783
784         case ACPI_DMT_FLAGS2:
785
786             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
787             break;
788
789         /* Standard Data Types */
790
791         case ACPI_DMT_UINT8:
792
793             AcpiOsPrintf ("%2.2X\n", *Target);
794             break;
795
796         case ACPI_DMT_UINT16:
797
798             AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
799             break;
800
801         case ACPI_DMT_UINT24:
802
803             AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
804                 *Target, *(Target + 1), *(Target + 2));
805             break;
806
807         case ACPI_DMT_UINT32:
808
809             AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
810             break;
811
812         case ACPI_DMT_UINT56:
813
814             for (Temp8 = 0; Temp8 < 7; Temp8++)
815             {
816                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
817             }
818             AcpiOsPrintf ("\n");
819             break;
820
821         case ACPI_DMT_UINT64:
822
823             AcpiOsPrintf ("%8.8X%8.8X\n",
824                 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
825             break;
826
827         case ACPI_DMT_BUF7:
828         case ACPI_DMT_BUF16:
829
830             /*
831              * Buffer: Size depends on the opcode and was set above.
832              * Each hex byte is separated with a space.
833              */
834             for (Temp8 = 0; Temp8 < ByteLength; Temp8++)
835             {
836                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
837                 if ((UINT32) (Temp8 + 1) < ByteLength)
838                 {
839                     AcpiOsPrintf (" ");
840                 }
841             }
842             AcpiOsPrintf ("\n");
843             break;
844
845         case ACPI_DMT_UUID:
846
847             /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
848
849             (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
850
851             AcpiOsPrintf ("%s\n", MsgBuffer);
852             break;
853
854         case ACPI_DMT_STRING:
855
856             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
857             break;
858
859         /* Fixed length ASCII name fields */
860
861         case ACPI_DMT_SIG:
862
863             AcpiDmCheckAscii (Target, RepairedName, 4);
864             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
865             TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
866             if (TableData)
867             {
868                 AcpiOsPrintf ("/* %s */", TableData->Name);
869             }
870             AcpiOsPrintf ("\n");
871             break;
872
873         case ACPI_DMT_NAME4:
874
875             AcpiDmCheckAscii (Target, RepairedName, 4);
876             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
877             break;
878
879         case ACPI_DMT_NAME6:
880
881             AcpiDmCheckAscii (Target, RepairedName, 6);
882             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
883             break;
884
885         case ACPI_DMT_NAME8:
886
887             AcpiDmCheckAscii (Target, RepairedName, 8);
888             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
889             break;
890
891         /* Special Data Types */
892
893         case ACPI_DMT_CHKSUM:
894
895             /* Checksum, display and validate */
896
897             AcpiOsPrintf ("%2.2X", *Target);
898             Temp8 = AcpiDmGenerateChecksum (Table,
899                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
900                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
901             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
902             {
903                 AcpiOsPrintf (
904                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
905             }
906             AcpiOsPrintf ("\n");
907             break;
908
909         case ACPI_DMT_SPACEID:
910
911             /* Address Space ID */
912
913             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target));
914             break;
915
916         case ACPI_DMT_ACCWIDTH:
917
918             /* Encoded Access Width */
919
920             Temp8 = *Target;
921             if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
922             {
923                 Temp8 = ACPI_GAS_WIDTH_RESERVED;
924             }
925
926             AcpiOsPrintf ("%2.2X (%s)\n", Temp8, AcpiDmGasAccessWidth[Temp8]);
927             break;
928
929         case ACPI_DMT_GAS:
930
931             /* Generic Address Structure */
932
933             AcpiOsPrintf ("<Generic Address Structure>\n");
934             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
935                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
936             AcpiOsPrintf ("\n");
937             LastOutputBlankLine = TRUE;
938             break;
939
940         case ACPI_DMT_ASF:
941
942             /* ASF subtable types */
943
944             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
945             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
946             {
947                 Temp16 = ACPI_ASF_TYPE_RESERVED;
948             }
949
950             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmAsfSubnames[Temp16]);
951             break;
952
953         case ACPI_DMT_DMAR:
954
955             /* DMAR subtable types */
956
957             Temp16 = ACPI_GET16 (Target);
958             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
959             {
960                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
961             }
962
963             AcpiOsPrintf ("%4.4X <%s>\n", ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
964             break;
965
966         case ACPI_DMT_EINJACT:
967
968             /* EINJ Action types */
969
970             Temp8 = *Target;
971             if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
972             {
973                 Temp8 = ACPI_EINJ_ACTION_RESERVED;
974             }
975
976             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjActions[Temp8]);
977             break;
978
979         case ACPI_DMT_EINJINST:
980
981             /* EINJ Instruction types */
982
983             Temp8 = *Target;
984             if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
985             {
986                 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
987             }
988
989             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjInstructions[Temp8]);
990             break;
991
992         case ACPI_DMT_ERSTACT:
993
994             /* ERST Action types */
995
996             Temp8 = *Target;
997             if (Temp8 > ACPI_ERST_ACTION_RESERVED)
998             {
999                 Temp8 = ACPI_ERST_ACTION_RESERVED;
1000             }
1001
1002             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstActions[Temp8]);
1003             break;
1004
1005         case ACPI_DMT_ERSTINST:
1006
1007             /* ERST Instruction types */
1008
1009             Temp8 = *Target;
1010             if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
1011             {
1012                 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
1013             }
1014
1015             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstInstructions[Temp8]);
1016             break;
1017
1018         case ACPI_DMT_HEST:
1019
1020             /* HEST subtable types */
1021
1022             Temp16 = ACPI_GET16 (Target);
1023             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
1024             {
1025                 Temp16 = ACPI_HEST_TYPE_RESERVED;
1026             }
1027
1028             AcpiOsPrintf ("%4.4X (%s)\n", ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
1029             break;
1030
1031         case ACPI_DMT_HESTNTFY:
1032
1033             AcpiOsPrintf ("<Hardware Error Notification Structure>\n");
1034             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1035                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
1036             AcpiOsPrintf ("\n");
1037             LastOutputBlankLine = TRUE;
1038             break;
1039
1040         case ACPI_DMT_HESTNTYP:
1041
1042             /* HEST Notify types */
1043
1044             Temp8 = *Target;
1045             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1046             {
1047                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1048             }
1049
1050             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmHestNotifySubnames[Temp8]);
1051             break;
1052
1053         case ACPI_DMT_MADT:
1054
1055             /* MADT subtable types */
1056
1057             Temp8 = *Target;
1058             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1059             {
1060                 Temp8 = ACPI_MADT_TYPE_RESERVED;
1061             }
1062
1063             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]);
1064             break;
1065
1066         case ACPI_DMT_SRAT:
1067
1068             /* SRAT subtable types */
1069
1070             Temp8 = *Target;
1071             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1072             {
1073                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
1074             }
1075
1076             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]);
1077             break;
1078
1079         case ACPI_DMT_FADTPM:
1080
1081             /* FADT Preferred PM Profile names */
1082
1083             Temp8 = *Target;
1084             if (Temp8 > ACPI_FADT_PM_RESERVED)
1085             {
1086                 Temp8 = ACPI_FADT_PM_RESERVED;
1087             }
1088
1089             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]);
1090             break;
1091
1092         case ACPI_DMT_IVRS:
1093
1094             /* IVRS subtable types */
1095
1096             Temp8 = *Target;
1097             switch (Temp8)
1098             {
1099             case ACPI_IVRS_TYPE_HARDWARE:
1100                 Name = AcpiDmIvrsSubnames[0];
1101                 break;
1102
1103             case ACPI_IVRS_TYPE_MEMORY1:
1104             case ACPI_IVRS_TYPE_MEMORY2:
1105             case ACPI_IVRS_TYPE_MEMORY3:
1106                 Name = AcpiDmIvrsSubnames[1];
1107                 break;
1108
1109             default:
1110                 Name = AcpiDmIvrsSubnames[2];
1111                 break;
1112             }
1113
1114             AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name);
1115             break;
1116
1117         case ACPI_DMT_EXIT:
1118             return (AE_OK);
1119
1120         default:
1121             ACPI_ERROR ((AE_INFO,
1122                 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1123             return (AE_SUPPORT);
1124         }
1125     }
1126
1127     if (TableOffset && !SubtableLength)
1128     {
1129         /* If this table is not the main table, subtable must have valid length */
1130
1131         AcpiOsPrintf ("Invalid zero length subtable\n");
1132         return (AE_BAD_DATA);
1133     }
1134
1135     return (AE_OK);
1136 }
1137
1138
1139 /*******************************************************************************
1140  *
1141  * FUNCTION:    AcpiDmCheckAscii
1142  *
1143  * PARAMETERS:  Name                - Ascii string
1144  *              Count               - Number of characters to check
1145  *
1146  * RETURN:      None
1147  *
1148  * DESCRIPTION: Ensure that the requested number of characters are printable
1149  *              Ascii characters. Sets non-printable and null chars to <space>.
1150  *
1151  ******************************************************************************/
1152
1153 static void
1154 AcpiDmCheckAscii (
1155     UINT8                   *Name,
1156     char                    *RepairedName,
1157     UINT32                  Count)
1158 {
1159     UINT32                  i;
1160
1161
1162     for (i = 0; i < Count; i++)
1163     {
1164         RepairedName[i] = (char) Name[i];
1165
1166         if (!Name[i])
1167         {
1168             return;
1169         }
1170         if (!isprint (Name[i]))
1171         {
1172             RepairedName[i] = ' ';
1173         }
1174     }
1175 }