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