dmtable.c revision 216471
1261287Sdes/******************************************************************************
2261287Sdes *
3261287Sdes * Module Name: dmtable - Support for ACPI tables that contain no AML code
4261287Sdes *
5261287Sdes *****************************************************************************/
6261287Sdes
7261287Sdes/******************************************************************************
8261287Sdes *
9261287Sdes * 1. Copyright Notice
10261287Sdes *
11261287Sdes * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12261287Sdes * All rights reserved.
13261287Sdes *
14261287Sdes * 2. License
15261287Sdes *
16261287Sdes * 2.1. This is your license from Intel Corp. under its intellectual property
17261287Sdes * rights.  You may have additional license terms from the party that provided
18261287Sdes * you this software, covering your right to use that party's intellectual
19261287Sdes * property rights.
20261287Sdes *
21261287Sdes * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22261287Sdes * copy of the source code appearing in this file ("Covered Code") an
23261287Sdes * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24261287Sdes * base code distributed originally by Intel ("Original Intel Code") to copy,
25261287Sdes * make derivatives, distribute, use and display any portion of the Covered
26261287Sdes * Code in any form, with the right to sublicense such rights; and
27261287Sdes *
28261287Sdes * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29261287Sdes * license (with the right to sublicense), under only those claims of Intel
30261287Sdes * patents that are infringed by the Original Intel Code, to make, use, sell,
31261287Sdes * offer to sell, and import the Covered Code and derivative works thereof
32261287Sdes * solely to the minimum extent necessary to exercise the above copyright
33261287Sdes * license, and in no event shall the patent license extend to any additions
34261287Sdes * to or modifications of the Original Intel Code.  No other license or right
35261287Sdes * is granted directly or by implication, estoppel or otherwise;
36261287Sdes *
37261287Sdes * The above copyright and patent license is granted only if the following
38261287Sdes * conditions are met:
39261287Sdes *
40261287Sdes * 3. Conditions
41261287Sdes *
42261287Sdes * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43261287Sdes * Redistribution of source code of any substantial portion of the Covered
44261287Sdes * Code or modification with rights to further distribute source must include
45261287Sdes * the above Copyright Notice, the above License, this list of Conditions,
46261287Sdes * and the following Disclaimer and Export Compliance provision.  In addition,
47261287Sdes * Licensee must cause all Covered Code to which Licensee contributes to
48261287Sdes * contain a file documenting the changes Licensee made to create that Covered
49261287Sdes * Code and the date of any change.  Licensee must include in that file the
50261287Sdes * documentation of any changes made by any predecessor Licensee.  Licensee
51261287Sdes * must include a prominent statement that the modification is derived,
52261287Sdes * directly or indirectly, from Original Intel Code.
53261287Sdes *
54261287Sdes * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55261287Sdes * Redistribution of source code of any substantial portion of the Covered
56261287Sdes * Code or modification without rights to further distribute source must
57261287Sdes * include the following Disclaimer and Export Compliance provision in the
58261287Sdes * documentation and/or other materials provided with distribution.  In
59261287Sdes * addition, Licensee may not authorize further sublicense of source of any
60261287Sdes * portion of the Covered Code, and must include terms to the effect that the
61261287Sdes * license from Licensee to its licensee is limited to the intellectual
62261287Sdes * property embodied in the software Licensee provides to its licensee, and
63261287Sdes * not to intellectual property embodied in modifications its licensee may
64261287Sdes * make.
65261287Sdes *
66261287Sdes * 3.3. Redistribution of Executable. Redistribution in executable form of any
67261287Sdes * substantial portion of the Covered Code or modification must reproduce the
68261287Sdes * above Copyright Notice, and the following Disclaimer and Export Compliance
69261287Sdes * provision in the documentation and/or other materials provided with the
70261287Sdes * distribution.
71261287Sdes *
72261287Sdes * 3.4. Intel retains all right, title, and interest in and to the Original
73261287Sdes * Intel Code.
74261287Sdes *
75261287Sdes * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76261287Sdes * Intel shall be used in advertising or otherwise to promote the sale, use or
77261287Sdes * other dealings in products derived from or relating to the Covered Code
78261287Sdes * without prior written authorization from Intel.
79261287Sdes *
80261287Sdes * 4. Disclaimer and Export Compliance
81261287Sdes *
82261287Sdes * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83261287Sdes * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84261287Sdes * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85261287Sdes * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86261287Sdes * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87261287Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88261287Sdes * PARTICULAR PURPOSE.
89261287Sdes *
90261287Sdes * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91261287Sdes * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92261287Sdes * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93261287Sdes * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94261287Sdes * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95261287Sdes * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96261287Sdes * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97261287Sdes * LIMITED REMEDY.
98261287Sdes *
99261287Sdes * 4.3. Licensee shall not export, either directly or indirectly, any of this
100261287Sdes * software or system incorporating such software without first obtaining any
101261287Sdes * required license or other approval from the U. S. Department of Commerce or
102261287Sdes * any other agency or department of the United States Government.  In the
103261287Sdes * event Licensee exports any such software from the United States or
104261287Sdes * re-exports any such software from a foreign destination, Licensee shall
105261287Sdes * ensure that the distribution and export/re-export of the software is in
106261287Sdes * compliance with all laws, regulations, orders, or other restrictions of the
107261287Sdes * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108261287Sdes * any of its subsidiaries will export/re-export any technical data, process,
109261287Sdes * software, or service, directly or indirectly, to any country for which the
110261287Sdes * United States government or any agency thereof requires an export license,
111261287Sdes * other governmental approval, or letter of assurance, without first obtaining
112261287Sdes * such license, approval or letter.
113261287Sdes *
114261287Sdes *****************************************************************************/
115261287Sdes
116261287Sdes#include <contrib/dev/acpica/include/acpi.h>
117261287Sdes#include <contrib/dev/acpica/include/accommon.h>
118261287Sdes#include <contrib/dev/acpica/include/acdisasm.h>
119261287Sdes#include <contrib/dev/acpica/include/actables.h>
120261287Sdes#include <contrib/dev/acpica/compiler/aslcompiler.h>
121261287Sdes#include <contrib/dev/acpica/compiler/dtcompiler.h>
122261287Sdes
123261287Sdes/* This module used for application-level code only */
124261287Sdes
125261287Sdes#define _COMPONENT          ACPI_CA_DISASSEMBLER
126261287Sdes        ACPI_MODULE_NAME    ("dmtable")
127261287Sdes
128261287Sdes/* Local Prototypes */
129261287Sdes
130261287Sdesstatic void
131261287SdesAcpiDmCheckAscii (
132261287Sdes    UINT8                   *Target,
133261287Sdes    char                    *RepairedName,
134261287Sdes    UINT32                  Count);
135261287Sdes
136261287Sdes
137261287Sdes/* These tables map a subtable type to a description string */
138261287Sdes
139261287Sdesstatic const char           *AcpiDmAsfSubnames[] =
140261287Sdes{
141261287Sdes    "ASF Information",
142261287Sdes    "ASF Alerts",
143261287Sdes    "ASF Remote Control",
144261287Sdes    "ASF RMCP Boot Options",
145261287Sdes    "ASF Address",
146261287Sdes    "Unknown SubTable Type"         /* Reserved */
147261287Sdes};
148261287Sdes
149261287Sdesstatic const char           *AcpiDmDmarSubnames[] =
150261287Sdes{
151261287Sdes    "Hardware Unit Definition",
152261287Sdes    "Reserved Memory Region",
153261287Sdes    "Root Port ATS Capability",
154261287Sdes    "Remapping Hardware Static Affinity",
155261287Sdes    "Unknown SubTable Type"         /* Reserved */
156261287Sdes};
157261287Sdes
158261287Sdesstatic const char           *AcpiDmEinjActions[] =
159261287Sdes{
160261287Sdes    "Begin Operation",
161261287Sdes    "Get Trigger Table",
162261287Sdes    "Set Error Type",
163261287Sdes    "Get Error Type",
164261287Sdes    "End Operation",
165261287Sdes    "Execute Operation",
166261287Sdes    "Check Busy Status",
167261287Sdes    "Get Command Status",
168261287Sdes    "Unknown Action"
169261287Sdes};
170261287Sdes
171261287Sdesstatic const char           *AcpiDmEinjInstructions[] =
172261287Sdes{
173261287Sdes    "Read Register",
174261287Sdes    "Read Register Value",
175261287Sdes    "Write Register",
176261287Sdes    "Write Register Value",
177261287Sdes    "Noop",
178261287Sdes    "Unknown Instruction"
179261287Sdes};
180261287Sdes
181261287Sdesstatic const char           *AcpiDmErstActions[] =
182261287Sdes{
183261287Sdes    "Begin Write Operation",
184261287Sdes    "Begin Read Operation",
185261287Sdes    "Begin Clear Operation",
186261287Sdes    "End Operation",
187261287Sdes    "Set Record Offset",
188261287Sdes    "Execute Operation",
189261287Sdes    "Check Busy Status",
190261287Sdes    "Get Command Status",
191261287Sdes    "Get Record Identifier",
192261287Sdes    "Set Record Identifier",
193261287Sdes    "Get Record Count",
194261287Sdes    "Begin Dummy Write",
195261287Sdes    "Unused/Unknown Action",
196261287Sdes    "Get Error Address Range",
197261287Sdes    "Get Error Address Length",
198261287Sdes    "Get Error Attributes",
199261287Sdes    "Unknown Action"
200261287Sdes};
201261287Sdes
202261287Sdesstatic const char           *AcpiDmErstInstructions[] =
203261287Sdes{
204261287Sdes    "Read Register",
205261287Sdes    "Read Register Value",
206261287Sdes    "Write Register",
207261287Sdes    "Write Register Value",
208261287Sdes    "Noop",
209261287Sdes    "Load Var1",
210261287Sdes    "Load Var2",
211261287Sdes    "Store Var1",
212261287Sdes    "Add",
213261287Sdes    "Subtract",
214261287Sdes    "Add Value",
215261287Sdes    "Subtract Value",
216261287Sdes    "Stall",
217261287Sdes    "Stall While True",
218261287Sdes    "Skip Next If True",
219261287Sdes    "GoTo",
220261287Sdes    "Set Source Address",
221261287Sdes    "Set Destination Address",
222261287Sdes    "Move Data",
223    "Unknown Instruction"
224};
225
226static 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
241static const char           *AcpiDmHestNotifySubnames[] =
242{
243    "Polled",
244    "External Interrupt",
245    "Local Interrupt",
246    "SCI",
247    "NMI",
248    "Unknown Notify Type"           /* Reserved */
249};
250
251static 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
267static 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
275static 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
285static 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
300static 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
324ACPI_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
375UINT8
376AcpiDmGenerateChecksum (
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
411ACPI_DMTABLE_DATA *
412AcpiDmGetTableData (
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
443void
444AcpiDmDumpDataTable (
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
542void
543AcpiDmLineHeader (
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
577void
578AcpiDmLineHeader2 (
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
633ACPI_STATUS
634AcpiDmDumpTable (
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
1138static void
1139AcpiDmCheckAscii (
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}
1161