dmtable.c revision 209746
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
130static void
131AcpiDmCheckAscii (
132    UINT8                   *Target,
133    char                    *RepairedName,
134    UINT32                  Count);
135
136
137/* These tables map a subtable type to a description string */
138
139static 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
149static 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
158static 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
171static 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
181static 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
202static 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
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/*******************************************************************************
299 *
300 * ACPI Table Data, indexed by signature.
301 *
302 * Each entry contains: Signature, Table Info, Handler, DtHandler,
303 *  Template, Description
304 *
305 * Simple tables have only a TableInfo structure, complex tables have a
306 * handler. This table must be NULL terminated. RSDP and FACS are
307 * special-cased elsewhere.
308 *
309 ******************************************************************************/
310
311ACPI_DMTABLE_DATA    AcpiDmTableData[] =
312{
313    {ACPI_SIG_ASF,  NULL,                   AcpiDmDumpAsf,  DtCompileAsf,   TemplateAsf,    "Alert Standard Format table"},
314    {ACPI_SIG_BOOT, AcpiDmTableInfoBoot,    NULL,           NULL,           TemplateBoot,   "Simple Boot Flag Table"},
315    {ACPI_SIG_BERT, AcpiDmTableInfoBert,    NULL,           NULL,           TemplateBert,   "Boot Error Record Table"},
316    {ACPI_SIG_CPEP, NULL,                   AcpiDmDumpCpep, DtCompileCpep,  TemplateCpep,   "Corrected Platform Error Polling table"},
317    {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp,    NULL,           NULL,           TemplateDbgp,   "Debug Port table"},
318    {ACPI_SIG_DMAR, NULL,                   AcpiDmDumpDmar, DtCompileDmar,  TemplateDmar,   "DMA Remapping table"},
319    {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt,    NULL,           NULL,           TemplateEcdt,   "Embedded Controller Boot Resources Table"},
320    {ACPI_SIG_EINJ, NULL,                   AcpiDmDumpEinj, DtCompileEinj,  TemplateEinj,   "Error Injection table"},
321    {ACPI_SIG_ERST, NULL,                   AcpiDmDumpErst, DtCompileErst,  TemplateErst,   "Error Record Serialization Table"},
322    {ACPI_SIG_FADT, NULL,                   AcpiDmDumpFadt, DtCompileFadt,  TemplateFadt,   "Fixed ACPI Description Table"},
323    {ACPI_SIG_HEST, NULL,                   AcpiDmDumpHest, DtCompileHest,  TemplateHest,   "Hardware Error Source Table"},
324    {ACPI_SIG_HPET, AcpiDmTableInfoHpet,    NULL,           NULL,           TemplateHpet,   "High Precision Event Timer table"},
325    {ACPI_SIG_IVRS, NULL,                   AcpiDmDumpIvrs, DtCompileIvrs,  TemplateIvrs,   "I/O Virtualization Reporting Structure"},
326    {ACPI_SIG_MADT, NULL,                   AcpiDmDumpMadt, DtCompileMadt,  TemplateMadt,   "Multiple APIC Description Table"},
327    {ACPI_SIG_MCFG, NULL,                   AcpiDmDumpMcfg, DtCompileMcfg,  TemplateMcfg,   "Memory Mapped Configuration table"},
328    {ACPI_SIG_MCHI, AcpiDmTableInfoMchi,    NULL,           NULL,           TemplateMchi,   "Management Controller Host Interface table"},
329    {ACPI_SIG_MSCT, NULL,                   AcpiDmDumpMsct, DtCompileMsct,  TemplateMsct,   "Maximum System Characteristics Table"},
330    {ACPI_SIG_RSDT, NULL,                   AcpiDmDumpRsdt, DtCompileRsdt,  TemplateRsdt,   "Root System Description Table"},
331    {ACPI_SIG_SBST, AcpiDmTableInfoSbst,    NULL,           NULL,           TemplateSbst,   "Smart Battery Specification Table"},
332    {ACPI_SIG_SLIC, AcpiDmTableInfoSlic,    NULL,           NULL,           NULL,           "Software Licensing Description Table"},
333    {ACPI_SIG_SLIT, NULL,                   AcpiDmDumpSlit, DtCompileSlit,  TemplateSlit,   "System Locality Information Table"},
334    {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr,    NULL,           NULL,           TemplateSpcr,   "Serial Port Console Redirection table"},
335    {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi,    NULL,           NULL,           TemplateSpmi,   "Server Platform Management Interface table"},
336    {ACPI_SIG_SRAT, NULL,                   AcpiDmDumpSrat, DtCompileSrat,  TemplateSrat,   "System Resource Affinity Table"},
337    {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa,    NULL,           NULL,           TemplateTcpa,   "Trusted Computing Platform Alliance table"},
338    {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           NULL,           TemplateUefi,   "UEFI Boot Optimization Table"},
339    {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           NULL,           TemplateWaet,   "Windows ACPI Emulated Devices Table"},
340    {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, DtCompileWdat,  TemplateWdat,   "Watchdog Action Table"},
341    {ACPI_SIG_WDDT, AcpiDmTableInfoWddt,    NULL,           NULL,           TemplateWddt,   "Watchdog Description Table"},
342    {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           NULL,           TemplateWdrt,   "Watchdog Resource Table"},
343    {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, DtCompileXsdt,  TemplateXsdt,   "Extended System Description Table"},
344    {NULL,          NULL,                   NULL,           NULL,           NULL,           NULL}
345};
346
347
348/*******************************************************************************
349 *
350 * FUNCTION:    AcpiDmGenerateChecksum
351 *
352 * PARAMETERS:  Table               - Pointer to table to be checksummed
353 *              Length              - Length of the table
354 *              OriginalChecksum    - Value of the checksum field
355 *
356 * RETURN:      8 bit checksum of buffer
357 *
358 * DESCRIPTION: Computes an 8 bit checksum of the table.
359 *
360 ******************************************************************************/
361
362UINT8
363AcpiDmGenerateChecksum (
364    void                    *Table,
365    UINT32                  Length,
366    UINT8                   OriginalChecksum)
367{
368    UINT8                   Checksum;
369
370
371    /* Sum the entire table as-is */
372
373    Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
374
375    /* Subtract off the existing checksum value in the table */
376
377    Checksum = (UINT8) (Checksum - OriginalChecksum);
378
379    /* Compute the final checksum */
380
381    Checksum = (UINT8) (0 - Checksum);
382    return (Checksum);
383}
384
385
386/*******************************************************************************
387 *
388 * FUNCTION:    AcpiDmGetTableData
389 *
390 * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
391 *
392 * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
393 *
394 * DESCRIPTION: Find a match in the global table of supported ACPI tables
395 *
396 ******************************************************************************/
397
398ACPI_DMTABLE_DATA *
399AcpiDmGetTableData (
400    char                    *Signature)
401{
402    ACPI_DMTABLE_DATA       *TableData;
403
404
405    for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
406    {
407        if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
408        {
409            return (TableData);
410        }
411    }
412
413    return (NULL);
414}
415
416
417/*******************************************************************************
418 *
419 * FUNCTION:    AcpiDmDumpDataTable
420 *
421 * PARAMETERS:  Table               - An ACPI table
422 *
423 * RETURN:      None.
424 *
425 * DESCRIPTION: Format the contents of an ACPI data table (any table other
426 *              than an SSDT or DSDT that does not contain executable AML code)
427 *
428 ******************************************************************************/
429
430void
431AcpiDmDumpDataTable (
432    ACPI_TABLE_HEADER       *Table)
433{
434    ACPI_STATUS             Status;
435    ACPI_DMTABLE_DATA       *TableData;
436    UINT32                  Length;
437
438
439    /* Ignore tables that contain AML */
440
441    if (AcpiUtIsAmlTable (Table))
442    {
443        return;
444    }
445
446    /*
447     * Handle tables that don't use the common ACPI table header structure.
448     * Currently, these are the FACS and RSDP.
449     */
450    if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
451    {
452        Length = Table->Length;
453        AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
454    }
455    else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
456    {
457        Length = AcpiDmDumpRsdp (Table);
458    }
459    else
460    {
461        /*
462         * All other tables must use the common ACPI table header, dump it now
463         */
464        Length = Table->Length;
465        Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
466        if (ACPI_FAILURE (Status))
467        {
468            return;
469        }
470        AcpiOsPrintf ("\n");
471
472        /* Match signature and dispatch appropriately */
473
474        TableData = AcpiDmGetTableData (Table->Signature);
475        if (!TableData)
476        {
477            if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
478            {
479                AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
480                    Table->Signature);
481            }
482            else
483            {
484                AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
485                    Table->Signature);
486            }
487        }
488        else if (TableData->TableHandler)
489        {
490            /* Complex table, has a handler */
491
492            TableData->TableHandler (Table);
493        }
494        else if (TableData->TableInfo)
495        {
496            /* Simple table, just walk the info table */
497
498            AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
499        }
500    }
501
502    if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
503    {
504        /* Dump the raw table data */
505
506        AcpiOsPrintf ("\nRaw Table Data\n\n");
507        AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
508    }
509}
510
511
512/*******************************************************************************
513 *
514 * FUNCTION:    AcpiDmLineHeader
515 *
516 * PARAMETERS:  Offset              - Current byte offset, from table start
517 *              ByteLength          - Length of the field in bytes, 0 for flags
518 *              Name                - Name of this field
519 *              Value               - Optional value, displayed on left of ':'
520 *
521 * RETURN:      None
522 *
523 * DESCRIPTION: Utility routines for formatting output lines. Displays the
524 *              current table offset in hex and decimal, the field length,
525 *              and the field name.
526 *
527 ******************************************************************************/
528
529void
530AcpiDmLineHeader (
531    UINT32                  Offset,
532    UINT32                  ByteLength,
533    char                    *Name)
534{
535
536    if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
537    {
538        if (ByteLength)
539        {
540            AcpiOsPrintf ("[%.3d] %34s : ",
541                ByteLength, Name);
542        }
543        else
544        {
545            AcpiOsPrintf ("%40s : ",
546                Name);
547        }
548    }
549    else /* Normal disassembler or verbose template */
550    {
551        if (ByteLength)
552        {
553            AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %28s : ",
554                Offset, Offset, ByteLength, Name);
555        }
556        else
557        {
558            AcpiOsPrintf ("%43s : ",
559                Name);
560        }
561    }
562}
563
564void
565AcpiDmLineHeader2 (
566    UINT32                  Offset,
567    UINT32                  ByteLength,
568    char                    *Name,
569    UINT32                  Value)
570{
571
572    if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
573    {
574        if (ByteLength)
575        {
576            AcpiOsPrintf ("[%.3d] %30s % 3d : ",
577                ByteLength, Name, Value);
578        }
579        else
580        {
581            AcpiOsPrintf ("%36s % 3d : ",
582                Name, Value);
583        }
584    }
585    else /* Normal disassembler or verbose template */
586    {
587        if (ByteLength)
588        {
589            AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %24s % 3d : ",
590                Offset, Offset, ByteLength, Name, Value);
591        }
592        else
593        {
594            AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s % 3d : ",
595                Offset, Offset, Name, Value);
596        }
597    }
598}
599
600
601/*******************************************************************************
602 *
603 * FUNCTION:    AcpiDmDumpTable
604 *
605 * PARAMETERS:  TableLength         - Length of the entire ACPI table
606 *              TableOffset         - Starting offset within the table for this
607 *                                    sub-descriptor (0 if main table)
608 *              Table               - The ACPI table
609 *              SubtableLength      - Length of this sub-descriptor
610 *              Info                - Info table for this ACPI table
611 *
612 * RETURN:      None
613 *
614 * DESCRIPTION: Display ACPI table contents by walking the Info table.
615 *
616 * Note: This function must remain in sync with DtGetFieldLength.
617 *
618 ******************************************************************************/
619
620ACPI_STATUS
621AcpiDmDumpTable (
622    UINT32                  TableLength,
623    UINT32                  TableOffset,
624    void                    *Table,
625    UINT32                  SubtableLength,
626    ACPI_DMTABLE_INFO       *Info)
627{
628    UINT8                   *Target;
629    UINT32                  CurrentOffset;
630    UINT32                  ByteLength;
631    UINT8                   Temp8;
632    UINT16                  Temp16;
633    ACPI_DMTABLE_DATA       *TableData;
634    const char              *Name;
635    BOOLEAN                 LastOutputBlankLine = FALSE;
636    char                    RepairedName[8];
637
638
639    if (!Info)
640    {
641        AcpiOsPrintf ("Display not implemented\n");
642        return (AE_NOT_IMPLEMENTED);
643    }
644
645    /* Walk entire Info table; Null name terminates */
646
647    for (; Info->Name; Info++)
648    {
649        /*
650         * Target points to the field within the ACPI Table. CurrentOffset is
651         * the offset of the field from the start of the main table.
652         */
653        Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
654        CurrentOffset = TableOffset + Info->Offset;
655
656        /* Check for beyond EOT or beyond subtable end */
657
658        if ((CurrentOffset >= TableLength) ||
659            (SubtableLength && (Info->Offset >= SubtableLength)))
660        {
661            AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
662            return (AE_BAD_DATA);
663        }
664
665        /* Generate the byte length for this field */
666
667        switch (Info->Opcode)
668        {
669        case ACPI_DMT_UINT8:
670        case ACPI_DMT_CHKSUM:
671        case ACPI_DMT_SPACEID:
672        case ACPI_DMT_IVRS:
673        case ACPI_DMT_MADT:
674        case ACPI_DMT_SRAT:
675        case ACPI_DMT_ASF:
676        case ACPI_DMT_HESTNTYP:
677        case ACPI_DMT_FADTPM:
678        case ACPI_DMT_EINJACT:
679        case ACPI_DMT_EINJINST:
680        case ACPI_DMT_ERSTACT:
681        case ACPI_DMT_ERSTINST:
682            ByteLength = 1;
683            break;
684        case ACPI_DMT_UINT16:
685        case ACPI_DMT_DMAR:
686        case ACPI_DMT_HEST:
687            ByteLength = 2;
688            break;
689        case ACPI_DMT_UINT24:
690            ByteLength = 3;
691            break;
692        case ACPI_DMT_UINT32:
693        case ACPI_DMT_NAME4:
694        case ACPI_DMT_SIG:
695            ByteLength = 4;
696            break;
697        case ACPI_DMT_NAME6:
698            ByteLength = 6;
699            break;
700        case ACPI_DMT_UINT56:
701            ByteLength = 7;
702            break;
703        case ACPI_DMT_UINT64:
704        case ACPI_DMT_NAME8:
705            ByteLength = 8;
706            break;
707        case ACPI_DMT_BUF16:
708            ByteLength = 16;
709            break;
710        case ACPI_DMT_STRING:
711            ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
712            break;
713        case ACPI_DMT_GAS:
714            if (!LastOutputBlankLine)
715            {
716                AcpiOsPrintf ("\n");
717                LastOutputBlankLine = TRUE;
718            }
719            ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
720            break;
721        case ACPI_DMT_HESTNTFY:
722            if (!LastOutputBlankLine)
723            {
724                AcpiOsPrintf ("\n");
725                LastOutputBlankLine = TRUE;
726            }
727            ByteLength = sizeof (ACPI_HEST_NOTIFY);
728            break;
729        default:
730            ByteLength = 0;
731            break;
732        }
733
734        if (CurrentOffset + ByteLength > TableLength)
735        {
736            AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
737            return (AE_BAD_DATA);
738        }
739
740        /* Start a new line and decode the opcode */
741
742        AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
743
744        switch (Info->Opcode)
745        {
746        /* Single-bit Flag fields. Note: Opcode is the bit position */
747
748        case ACPI_DMT_FLAG0:
749        case ACPI_DMT_FLAG1:
750        case ACPI_DMT_FLAG2:
751        case ACPI_DMT_FLAG3:
752        case ACPI_DMT_FLAG4:
753        case ACPI_DMT_FLAG5:
754        case ACPI_DMT_FLAG6:
755        case ACPI_DMT_FLAG7:
756
757            AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
758            break;
759
760        /* 2-bit Flag fields */
761
762        case ACPI_DMT_FLAGS0:
763
764            AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
765            break;
766
767        case ACPI_DMT_FLAGS2:
768
769            AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
770            break;
771
772        /* Standard Data Types */
773
774        case ACPI_DMT_UINT8:
775
776            AcpiOsPrintf ("%2.2X\n", *Target);
777            break;
778
779        case ACPI_DMT_UINT16:
780
781            AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
782            break;
783
784        case ACPI_DMT_UINT24:
785
786            AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
787                *Target, *(Target + 1), *(Target + 2));
788            break;
789
790        case ACPI_DMT_UINT32:
791
792            AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
793            break;
794
795        case ACPI_DMT_UINT56:
796
797            for (Temp8 = 0; Temp8 < 7; Temp8++)
798            {
799                AcpiOsPrintf ("%2.2X", Target[Temp8]);
800            }
801            AcpiOsPrintf ("\n");
802            break;
803
804        case ACPI_DMT_UINT64:
805
806            AcpiOsPrintf ("%8.8X%8.8X\n",
807                ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
808            break;
809
810        case ACPI_DMT_BUF16:
811
812            /* Buffer of length 16 */
813
814            for (Temp8 = 0; Temp8 < 16; Temp8++)
815            {
816                AcpiOsPrintf ("%2.2X", Target[Temp8]);
817                if ((Temp8 + 1) < 16)
818                {
819                    AcpiOsPrintf (",");
820                }
821            }
822            AcpiOsPrintf ("\n");
823            break;
824
825        case ACPI_DMT_STRING:
826
827            AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
828            break;
829
830        /* Fixed length ASCII name fields */
831
832        case ACPI_DMT_SIG:
833
834            AcpiDmCheckAscii (Target, RepairedName, 4);
835            AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
836            TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
837            if (TableData)
838            {
839                AcpiOsPrintf ("/* %s */", TableData->Name);
840            }
841            AcpiOsPrintf ("\n");
842            break;
843
844        case ACPI_DMT_NAME4:
845
846            AcpiDmCheckAscii (Target, RepairedName, 4);
847            AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
848            break;
849
850        case ACPI_DMT_NAME6:
851
852            AcpiDmCheckAscii (Target, RepairedName, 6);
853            AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
854            break;
855
856        case ACPI_DMT_NAME8:
857
858            AcpiDmCheckAscii (Target, RepairedName, 8);
859            AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
860            break;
861
862        /* Special Data Types */
863
864        case ACPI_DMT_CHKSUM:
865
866            /* Checksum, display and validate */
867
868            AcpiOsPrintf ("%2.2X", *Target);
869            Temp8 = AcpiDmGenerateChecksum (Table,
870                        ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
871                        ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
872            if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
873            {
874                AcpiOsPrintf (
875                    "     /* Incorrect checksum, should be %2.2X */", Temp8);
876            }
877            AcpiOsPrintf ("\n");
878            break;
879
880        case ACPI_DMT_SPACEID:
881
882            /* Address Space ID */
883
884            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target));
885            break;
886
887        case ACPI_DMT_GAS:
888
889            /* Generic Address Structure */
890
891            AcpiOsPrintf ("<Generic Address Structure>\n");
892            AcpiDmDumpTable (TableLength, CurrentOffset, Target,
893                sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
894            AcpiOsPrintf ("\n");
895            LastOutputBlankLine = TRUE;
896            break;
897
898        case ACPI_DMT_ASF:
899
900            /* ASF subtable types */
901
902            Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
903            if (Temp16 > ACPI_ASF_TYPE_RESERVED)
904            {
905                Temp16 = ACPI_ASF_TYPE_RESERVED;
906            }
907
908            AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmAsfSubnames[Temp16]);
909            break;
910
911        case ACPI_DMT_DMAR:
912
913            /* DMAR subtable types */
914
915            Temp16 = ACPI_GET16 (Target);
916            if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
917            {
918                Temp16 = ACPI_DMAR_TYPE_RESERVED;
919            }
920
921            AcpiOsPrintf ("%4.4X <%s>\n", ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
922            break;
923
924        case ACPI_DMT_EINJACT:
925
926            /* EINJ Action types */
927
928            Temp8 = *Target;
929            if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
930            {
931                Temp8 = ACPI_EINJ_ACTION_RESERVED;
932            }
933
934            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjActions[Temp8]);
935            break;
936
937        case ACPI_DMT_EINJINST:
938
939            /* EINJ Instruction types */
940
941            Temp8 = *Target;
942            if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
943            {
944                Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
945            }
946
947            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjInstructions[Temp8]);
948            break;
949
950        case ACPI_DMT_ERSTACT:
951
952            /* ERST Action types */
953
954            Temp8 = *Target;
955            if (Temp8 > ACPI_ERST_ACTION_RESERVED)
956            {
957                Temp8 = ACPI_ERST_ACTION_RESERVED;
958            }
959
960            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstActions[Temp8]);
961            break;
962
963        case ACPI_DMT_ERSTINST:
964
965            /* ERST Instruction types */
966
967            Temp8 = *Target;
968            if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
969            {
970                Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
971            }
972
973            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstInstructions[Temp8]);
974            break;
975
976        case ACPI_DMT_HEST:
977
978            /* HEST subtable types */
979
980            Temp16 = ACPI_GET16 (Target);
981            if (Temp16 > ACPI_HEST_TYPE_RESERVED)
982            {
983                Temp16 = ACPI_HEST_TYPE_RESERVED;
984            }
985
986            AcpiOsPrintf ("%4.4X (%s)\n", ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
987            break;
988
989        case ACPI_DMT_HESTNTFY:
990
991            AcpiOsPrintf ("<Hardware Error Notification Structure>\n");
992            AcpiDmDumpTable (TableLength, CurrentOffset, Target,
993                sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
994            AcpiOsPrintf ("\n");
995            LastOutputBlankLine = TRUE;
996            break;
997
998        case ACPI_DMT_HESTNTYP:
999
1000            /* HEST Notify types */
1001
1002            Temp8 = *Target;
1003            if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1004            {
1005                Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1006            }
1007
1008            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmHestNotifySubnames[Temp8]);
1009            break;
1010
1011        case ACPI_DMT_MADT:
1012
1013            /* MADT subtable types */
1014
1015            Temp8 = *Target;
1016            if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1017            {
1018                Temp8 = ACPI_MADT_TYPE_RESERVED;
1019            }
1020
1021            AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]);
1022            break;
1023
1024        case ACPI_DMT_SRAT:
1025
1026            /* SRAT subtable types */
1027
1028            Temp8 = *Target;
1029            if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1030            {
1031                Temp8 = ACPI_SRAT_TYPE_RESERVED;
1032            }
1033
1034            AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]);
1035            break;
1036
1037        case ACPI_DMT_FADTPM:
1038
1039            /* FADT Preferred PM Profile names */
1040
1041            Temp8 = *Target;
1042            if (Temp8 > ACPI_FADT_PM_RESERVED)
1043            {
1044                Temp8 = ACPI_FADT_PM_RESERVED;
1045            }
1046
1047            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]);
1048            break;
1049
1050        case ACPI_DMT_IVRS:
1051
1052            /* IVRS subtable types */
1053
1054            Temp8 = *Target;
1055            switch (Temp8)
1056            {
1057            case ACPI_IVRS_TYPE_HARDWARE:
1058                Name = AcpiDmIvrsSubnames[0];
1059                break;
1060
1061            case ACPI_IVRS_TYPE_MEMORY1:
1062            case ACPI_IVRS_TYPE_MEMORY2:
1063            case ACPI_IVRS_TYPE_MEMORY3:
1064                Name = AcpiDmIvrsSubnames[1];
1065                break;
1066
1067            default:
1068                Name = AcpiDmIvrsSubnames[2];
1069                break;
1070            }
1071
1072            AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name);
1073            break;
1074
1075        case ACPI_DMT_EXIT:
1076            return (AE_OK);
1077
1078        default:
1079            ACPI_ERROR ((AE_INFO,
1080                "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1081            return (AE_SUPPORT);
1082        }
1083    }
1084
1085    if (TableOffset && !SubtableLength)
1086    {
1087        /* If this table is not the main table, subtable must have valid length */
1088
1089        AcpiOsPrintf ("Invalid zero length subtable\n");
1090        return (AE_BAD_DATA);
1091    }
1092
1093    return (AE_OK);
1094}
1095
1096
1097/*******************************************************************************
1098 *
1099 * FUNCTION:    AcpiDmCheckAscii
1100 *
1101 * PARAMETERS:  Name                - Ascii string
1102 *              Count               - Number of characters to check
1103 *
1104 * RETURN:      None
1105 *
1106 * DESCRIPTION: Ensure that the requested number of characters are printable
1107 *              Ascii characters. Sets non-printable and null chars to <space>.
1108 *
1109 ******************************************************************************/
1110
1111static void
1112AcpiDmCheckAscii (
1113    UINT8                   *Name,
1114    char                    *RepairedName,
1115    UINT32                  Count)
1116{
1117    UINT32                  i;
1118
1119
1120    for (i = 0; i < Count; i++)
1121    {
1122        RepairedName[i] = (char) Name[i];
1123
1124        if (!Name[i])
1125        {
1126            return;
1127        }
1128        if (!isprint (Name[i]))
1129        {
1130            RepairedName[i] = ' ';
1131        }
1132    }
1133}
1134