]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/common/dmtable.c
Merge ACPICA 20101209.
[FreeBSD/FreeBSD.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  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2010, 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 <contrib/dev/acpica/include/acpi.h>
117 #include <contrib/dev/acpica/include/accommon.h>
118 #include <contrib/dev/acpica/include/acdisasm.h>
119 #include <contrib/dev/acpica/include/actables.h>
120 #include <contrib/dev/acpica/compiler/aslcompiler.h>
121 #include <contrib/dev/acpica/compiler/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,           NULL,           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 ("\nRaw Table Data\n\n");
520         AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
521     }
522 }
523
524
525 /*******************************************************************************
526  *
527  * FUNCTION:    AcpiDmLineHeader
528  *
529  * PARAMETERS:  Offset              - Current byte offset, from table start
530  *              ByteLength          - Length of the field in bytes, 0 for flags
531  *              Name                - Name of this field
532  *              Value               - Optional value, displayed on left of ':'
533  *
534  * RETURN:      None
535  *
536  * DESCRIPTION: Utility routines for formatting output lines. Displays the
537  *              current table offset in hex and decimal, the field length,
538  *              and the field name.
539  *
540  ******************************************************************************/
541
542 void
543 AcpiDmLineHeader (
544     UINT32                  Offset,
545     UINT32                  ByteLength,
546     char                    *Name)
547 {
548
549     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
550     {
551         if (ByteLength)
552         {
553             AcpiOsPrintf ("[%.3d] %34s : ",
554                 ByteLength, Name);
555         }
556         else
557         {
558             AcpiOsPrintf ("%40s : ",
559                 Name);
560         }
561     }
562     else /* Normal disassembler or verbose template */
563     {
564         if (ByteLength)
565         {
566             AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %28s : ",
567                 Offset, Offset, ByteLength, Name);
568         }
569         else
570         {
571             AcpiOsPrintf ("%43s : ",
572                 Name);
573         }
574     }
575 }
576
577 void
578 AcpiDmLineHeader2 (
579     UINT32                  Offset,
580     UINT32                  ByteLength,
581     char                    *Name,
582     UINT32                  Value)
583 {
584
585     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
586     {
587         if (ByteLength)
588         {
589             AcpiOsPrintf ("[%.3d] %30s % 3d : ",
590                 ByteLength, Name, Value);
591         }
592         else
593         {
594             AcpiOsPrintf ("%36s % 3d : ",
595                 Name, Value);
596         }
597     }
598     else /* Normal disassembler or verbose template */
599     {
600         if (ByteLength)
601         {
602             AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %24s % 3d : ",
603                 Offset, Offset, ByteLength, Name, Value);
604         }
605         else
606         {
607             AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s % 3d : ",
608                 Offset, Offset, Name, Value);
609         }
610     }
611 }
612
613
614 /*******************************************************************************
615  *
616  * FUNCTION:    AcpiDmDumpTable
617  *
618  * PARAMETERS:  TableLength         - Length of the entire ACPI table
619  *              TableOffset         - Starting offset within the table for this
620  *                                    sub-descriptor (0 if main table)
621  *              Table               - The ACPI table
622  *              SubtableLength      - Length of this sub-descriptor
623  *              Info                - Info table for this ACPI table
624  *
625  * RETURN:      None
626  *
627  * DESCRIPTION: Display ACPI table contents by walking the Info table.
628  *
629  * Note: This function must remain in sync with DtGetFieldLength.
630  *
631  ******************************************************************************/
632
633 ACPI_STATUS
634 AcpiDmDumpTable (
635     UINT32                  TableLength,
636     UINT32                  TableOffset,
637     void                    *Table,
638     UINT32                  SubtableLength,
639     ACPI_DMTABLE_INFO       *Info)
640 {
641     UINT8                   *Target;
642     UINT32                  CurrentOffset;
643     UINT32                  ByteLength;
644     UINT8                   Temp8;
645     UINT16                  Temp16;
646     ACPI_DMTABLE_DATA       *TableData;
647     const char              *Name;
648     BOOLEAN                 LastOutputBlankLine = FALSE;
649     char                    RepairedName[8];
650
651
652     if (!Info)
653     {
654         AcpiOsPrintf ("Display not implemented\n");
655         return (AE_NOT_IMPLEMENTED);
656     }
657
658     /* Walk entire Info table; Null name terminates */
659
660     for (; Info->Name; Info++)
661     {
662         /*
663          * Target points to the field within the ACPI Table. CurrentOffset is
664          * the offset of the field from the start of the main table.
665          */
666         Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
667         CurrentOffset = TableOffset + Info->Offset;
668
669         /* Check for beyond EOT or beyond subtable end */
670
671         if ((CurrentOffset >= TableLength) ||
672             (SubtableLength && (Info->Offset >= SubtableLength)))
673         {
674             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
675             return (AE_BAD_DATA);
676         }
677
678         /* Generate the byte length for this field */
679
680         switch (Info->Opcode)
681         {
682         case ACPI_DMT_UINT8:
683         case ACPI_DMT_CHKSUM:
684         case ACPI_DMT_SPACEID:
685         case ACPI_DMT_ACCWIDTH:
686         case ACPI_DMT_IVRS:
687         case ACPI_DMT_MADT:
688         case ACPI_DMT_SRAT:
689         case ACPI_DMT_ASF:
690         case ACPI_DMT_HESTNTYP:
691         case ACPI_DMT_FADTPM:
692         case ACPI_DMT_EINJACT:
693         case ACPI_DMT_EINJINST:
694         case ACPI_DMT_ERSTACT:
695         case ACPI_DMT_ERSTINST:
696             ByteLength = 1;
697             break;
698         case ACPI_DMT_UINT16:
699         case ACPI_DMT_DMAR:
700         case ACPI_DMT_HEST:
701             ByteLength = 2;
702             break;
703         case ACPI_DMT_UINT24:
704             ByteLength = 3;
705             break;
706         case ACPI_DMT_UINT32:
707         case ACPI_DMT_NAME4:
708         case ACPI_DMT_SIG:
709             ByteLength = 4;
710             break;
711         case ACPI_DMT_NAME6:
712             ByteLength = 6;
713             break;
714         case ACPI_DMT_UINT56:
715             ByteLength = 7;
716             break;
717         case ACPI_DMT_UINT64:
718         case ACPI_DMT_NAME8:
719             ByteLength = 8;
720             break;
721         case ACPI_DMT_BUF16:
722             ByteLength = 16;
723             break;
724         case ACPI_DMT_STRING:
725             ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
726             break;
727         case ACPI_DMT_GAS:
728             if (!LastOutputBlankLine)
729             {
730                 AcpiOsPrintf ("\n");
731                 LastOutputBlankLine = TRUE;
732             }
733             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
734             break;
735         case ACPI_DMT_HESTNTFY:
736             if (!LastOutputBlankLine)
737             {
738                 AcpiOsPrintf ("\n");
739                 LastOutputBlankLine = TRUE;
740             }
741             ByteLength = sizeof (ACPI_HEST_NOTIFY);
742             break;
743         default:
744             ByteLength = 0;
745             break;
746         }
747
748         if (CurrentOffset + ByteLength > TableLength)
749         {
750             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
751             return (AE_BAD_DATA);
752         }
753
754         /* Start a new line and decode the opcode */
755
756         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
757
758         switch (Info->Opcode)
759         {
760         /* Single-bit Flag fields. Note: Opcode is the bit position */
761
762         case ACPI_DMT_FLAG0:
763         case ACPI_DMT_FLAG1:
764         case ACPI_DMT_FLAG2:
765         case ACPI_DMT_FLAG3:
766         case ACPI_DMT_FLAG4:
767         case ACPI_DMT_FLAG5:
768         case ACPI_DMT_FLAG6:
769         case ACPI_DMT_FLAG7:
770
771             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
772             break;
773
774         /* 2-bit Flag fields */
775
776         case ACPI_DMT_FLAGS0:
777
778             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
779             break;
780
781         case ACPI_DMT_FLAGS2:
782
783             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
784             break;
785
786         /* Standard Data Types */
787
788         case ACPI_DMT_UINT8:
789
790             AcpiOsPrintf ("%2.2X\n", *Target);
791             break;
792
793         case ACPI_DMT_UINT16:
794
795             AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
796             break;
797
798         case ACPI_DMT_UINT24:
799
800             AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
801                 *Target, *(Target + 1), *(Target + 2));
802             break;
803
804         case ACPI_DMT_UINT32:
805
806             AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
807             break;
808
809         case ACPI_DMT_UINT56:
810
811             for (Temp8 = 0; Temp8 < 7; Temp8++)
812             {
813                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
814             }
815             AcpiOsPrintf ("\n");
816             break;
817
818         case ACPI_DMT_UINT64:
819
820             AcpiOsPrintf ("%8.8X%8.8X\n",
821                 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
822             break;
823
824         case ACPI_DMT_BUF16:
825
826             /* Buffer of length 16 */
827
828             for (Temp8 = 0; Temp8 < 16; Temp8++)
829             {
830                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
831                 if ((Temp8 + 1) < 16)
832                 {
833                     AcpiOsPrintf (",");
834                 }
835             }
836             AcpiOsPrintf ("\n");
837             break;
838
839         case ACPI_DMT_STRING:
840
841             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
842             break;
843
844         /* Fixed length ASCII name fields */
845
846         case ACPI_DMT_SIG:
847
848             AcpiDmCheckAscii (Target, RepairedName, 4);
849             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
850             TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
851             if (TableData)
852             {
853                 AcpiOsPrintf ("/* %s */", TableData->Name);
854             }
855             AcpiOsPrintf ("\n");
856             break;
857
858         case ACPI_DMT_NAME4:
859
860             AcpiDmCheckAscii (Target, RepairedName, 4);
861             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
862             break;
863
864         case ACPI_DMT_NAME6:
865
866             AcpiDmCheckAscii (Target, RepairedName, 6);
867             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
868             break;
869
870         case ACPI_DMT_NAME8:
871
872             AcpiDmCheckAscii (Target, RepairedName, 8);
873             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
874             break;
875
876         /* Special Data Types */
877
878         case ACPI_DMT_CHKSUM:
879
880             /* Checksum, display and validate */
881
882             AcpiOsPrintf ("%2.2X", *Target);
883             Temp8 = AcpiDmGenerateChecksum (Table,
884                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
885                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
886             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
887             {
888                 AcpiOsPrintf (
889                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
890             }
891             AcpiOsPrintf ("\n");
892             break;
893
894         case ACPI_DMT_SPACEID:
895
896             /* Address Space ID */
897
898             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target));
899             break;
900
901         case ACPI_DMT_ACCWIDTH:
902
903             /* Encoded Access Width */
904
905             Temp8 = *Target;
906             if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
907             {
908                 Temp8 = ACPI_GAS_WIDTH_RESERVED;
909             }
910
911             AcpiOsPrintf ("%2.2X (%s)\n", Temp8, AcpiDmGasAccessWidth[Temp8]);
912             break;
913
914         case ACPI_DMT_GAS:
915
916             /* Generic Address Structure */
917
918             AcpiOsPrintf ("<Generic Address Structure>\n");
919             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
920                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
921             AcpiOsPrintf ("\n");
922             LastOutputBlankLine = TRUE;
923             break;
924
925         case ACPI_DMT_ASF:
926
927             /* ASF subtable types */
928
929             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
930             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
931             {
932                 Temp16 = ACPI_ASF_TYPE_RESERVED;
933             }
934
935             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmAsfSubnames[Temp16]);
936             break;
937
938         case ACPI_DMT_DMAR:
939
940             /* DMAR subtable types */
941
942             Temp16 = ACPI_GET16 (Target);
943             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
944             {
945                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
946             }
947
948             AcpiOsPrintf ("%4.4X <%s>\n", ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
949             break;
950
951         case ACPI_DMT_EINJACT:
952
953             /* EINJ Action types */
954
955             Temp8 = *Target;
956             if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
957             {
958                 Temp8 = ACPI_EINJ_ACTION_RESERVED;
959             }
960
961             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjActions[Temp8]);
962             break;
963
964         case ACPI_DMT_EINJINST:
965
966             /* EINJ Instruction types */
967
968             Temp8 = *Target;
969             if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
970             {
971                 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
972             }
973
974             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjInstructions[Temp8]);
975             break;
976
977         case ACPI_DMT_ERSTACT:
978
979             /* ERST Action types */
980
981             Temp8 = *Target;
982             if (Temp8 > ACPI_ERST_ACTION_RESERVED)
983             {
984                 Temp8 = ACPI_ERST_ACTION_RESERVED;
985             }
986
987             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstActions[Temp8]);
988             break;
989
990         case ACPI_DMT_ERSTINST:
991
992             /* ERST Instruction types */
993
994             Temp8 = *Target;
995             if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
996             {
997                 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
998             }
999
1000             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstInstructions[Temp8]);
1001             break;
1002
1003         case ACPI_DMT_HEST:
1004
1005             /* HEST subtable types */
1006
1007             Temp16 = ACPI_GET16 (Target);
1008             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
1009             {
1010                 Temp16 = ACPI_HEST_TYPE_RESERVED;
1011             }
1012
1013             AcpiOsPrintf ("%4.4X (%s)\n", ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
1014             break;
1015
1016         case ACPI_DMT_HESTNTFY:
1017
1018             AcpiOsPrintf ("<Hardware Error Notification Structure>\n");
1019             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1020                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
1021             AcpiOsPrintf ("\n");
1022             LastOutputBlankLine = TRUE;
1023             break;
1024
1025         case ACPI_DMT_HESTNTYP:
1026
1027             /* HEST Notify types */
1028
1029             Temp8 = *Target;
1030             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1031             {
1032                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1033             }
1034
1035             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmHestNotifySubnames[Temp8]);
1036             break;
1037
1038         case ACPI_DMT_MADT:
1039
1040             /* MADT subtable types */
1041
1042             Temp8 = *Target;
1043             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1044             {
1045                 Temp8 = ACPI_MADT_TYPE_RESERVED;
1046             }
1047
1048             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]);
1049             break;
1050
1051         case ACPI_DMT_SRAT:
1052
1053             /* SRAT subtable types */
1054
1055             Temp8 = *Target;
1056             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1057             {
1058                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
1059             }
1060
1061             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]);
1062             break;
1063
1064         case ACPI_DMT_FADTPM:
1065
1066             /* FADT Preferred PM Profile names */
1067
1068             Temp8 = *Target;
1069             if (Temp8 > ACPI_FADT_PM_RESERVED)
1070             {
1071                 Temp8 = ACPI_FADT_PM_RESERVED;
1072             }
1073
1074             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]);
1075             break;
1076
1077         case ACPI_DMT_IVRS:
1078
1079             /* IVRS subtable types */
1080
1081             Temp8 = *Target;
1082             switch (Temp8)
1083             {
1084             case ACPI_IVRS_TYPE_HARDWARE:
1085                 Name = AcpiDmIvrsSubnames[0];
1086                 break;
1087
1088             case ACPI_IVRS_TYPE_MEMORY1:
1089             case ACPI_IVRS_TYPE_MEMORY2:
1090             case ACPI_IVRS_TYPE_MEMORY3:
1091                 Name = AcpiDmIvrsSubnames[1];
1092                 break;
1093
1094             default:
1095                 Name = AcpiDmIvrsSubnames[2];
1096                 break;
1097             }
1098
1099             AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name);
1100             break;
1101
1102         case ACPI_DMT_EXIT:
1103             return (AE_OK);
1104
1105         default:
1106             ACPI_ERROR ((AE_INFO,
1107                 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1108             return (AE_SUPPORT);
1109         }
1110     }
1111
1112     if (TableOffset && !SubtableLength)
1113     {
1114         /* If this table is not the main table, subtable must have valid length */
1115
1116         AcpiOsPrintf ("Invalid zero length subtable\n");
1117         return (AE_BAD_DATA);
1118     }
1119
1120     return (AE_OK);
1121 }
1122
1123
1124 /*******************************************************************************
1125  *
1126  * FUNCTION:    AcpiDmCheckAscii
1127  *
1128  * PARAMETERS:  Name                - Ascii string
1129  *              Count               - Number of characters to check
1130  *
1131  * RETURN:      None
1132  *
1133  * DESCRIPTION: Ensure that the requested number of characters are printable
1134  *              Ascii characters. Sets non-printable and null chars to <space>.
1135  *
1136  ******************************************************************************/
1137
1138 static void
1139 AcpiDmCheckAscii (
1140     UINT8                   *Name,
1141     char                    *RepairedName,
1142     UINT32                  Count)
1143 {
1144     UINT32                  i;
1145
1146
1147     for (i = 0; i < Count; i++)
1148     {
1149         RepairedName[i] = (char) Name[i];
1150
1151         if (!Name[i])
1152         {
1153             return;
1154         }
1155         if (!isprint (Name[i]))
1156         {
1157             RepairedName[i] = ' ';
1158         }
1159     }
1160 }