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