Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 "acpi.h"
  117. #include "accommon.h"
  118. #include "acdisasm.h"
  119. #include "actables.h"
  120. #include "dtcompiler.h"
  121.  
  122. /* This module used for application-level code only */
  123.  
  124. #define _COMPONENT          ACPI_CA_DISASSEMBLER
  125.         ACPI_MODULE_NAME    ("dmtable")
  126.  
  127. /* Local Prototypes */
  128.  
  129. static void
  130. AcpiDmCheckAscii (
  131.     UINT8                   *Target,
  132.     char                    *RepairedName,
  133.     UINT32                  Count);
  134.  
  135. UINT8
  136. AcpiTbGenerateChecksum (
  137.     ACPI_TABLE_HEADER       *Table);
  138.  
  139.  
  140. /* These tables map a subtable type to a description string */
  141.  
  142. static const char           *AcpiDmAsfSubnames[] =
  143. {
  144.     "ASF Information",
  145.     "ASF Alerts",
  146.     "ASF Remote Control",
  147.     "ASF RMCP Boot Options",
  148.     "ASF Address",
  149.     "Unknown SubTable Type"         /* Reserved */
  150. };
  151.  
  152. static const char           *AcpiDmDmarSubnames[] =
  153. {
  154.     "Hardware Unit Definition",
  155.     "Reserved Memory Region",
  156.     "Root Port ATS Capability",
  157.     "Remapping Hardware Static Affinity",
  158.     "Unknown SubTable Type"         /* Reserved */
  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           *AcpiDmSratSubnames[] =
  203. {
  204.     "Processor Local APIC/SAPIC Affinity",
  205.     "Memory Affinity",
  206.     "Processor Local x2APIC Affinity",
  207.     "Unknown SubTable Type"         /* Reserved */
  208. };
  209.  
  210. static const char           *AcpiDmIvrsSubnames[] =
  211. {
  212.     "Hardware Definition Block",
  213.     "Memory Definition Block",
  214.     "Unknown SubTable Type"         /* Reserved */
  215. };
  216.  
  217.  
  218. #define ACPI_FADT_PM_RESERVED       8
  219.  
  220. static const char           *AcpiDmFadtProfiles[] =
  221. {
  222.     "Unspecified",
  223.     "Desktop",
  224.     "Mobile",
  225.     "Workstation",
  226.     "Enterprise Server",
  227.     "SOHO Server",
  228.     "Appliance PC",
  229.     "Performance Server",
  230.     "Unknown Profile Type"
  231. };
  232.  
  233. /*******************************************************************************
  234.  *
  235.  * ACPI Table Data, indexed by signature.
  236.  *
  237.  * Each entry contains: Signature, Table Info, Handler, Description
  238.  *
  239.  * Simple tables have only a TableInfo structure, complex tables have a handler.
  240.  * This table must be NULL terminated. RSDP and FACS are special-cased
  241.  * elsewhere.
  242.  *
  243.  ******************************************************************************/
  244.  
  245. static ACPI_DMTABLE_DATA    AcpiDmTableData[] =
  246. {
  247.     {ACPI_SIG_ASF,  NULL,                   AcpiDmDumpAsf,  DtCompileAsf,   "Alert Standard Format table"},
  248.     {ACPI_SIG_BOOT, AcpiDmTableInfoBoot,    NULL,           NULL,           "Simple Boot Flag Table"},
  249.     {ACPI_SIG_BERT, AcpiDmTableInfoBert,    NULL,           NULL,           "Boot Error Record Table"},
  250.     {ACPI_SIG_CPEP, NULL,                   AcpiDmDumpCpep, DtCompileCpep,  "Corrected Platform Error Polling table"},
  251.     {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp,    NULL,           NULL,           "Debug Port table"},
  252.     {ACPI_SIG_DMAR, NULL,                   AcpiDmDumpDmar, DtCompileDmar,  "DMA Remapping table"},
  253.     {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt,    NULL,           NULL,           "Embedded Controller Boot Resources Table"},
  254.     {ACPI_SIG_EINJ, NULL,                   AcpiDmDumpEinj, DtCompileEinj,  "Error Injection table"},
  255.     {ACPI_SIG_ERST, NULL,                   AcpiDmDumpErst, DtCompileErst,  "Error Record Serialization Table"},
  256.     {ACPI_SIG_FADT, NULL,                   AcpiDmDumpFadt, DtCompileFadt,  "Fixed ACPI Description Table"},
  257.     {ACPI_SIG_HEST, NULL,                   AcpiDmDumpHest, DtCompileHest,  "Hardware Error Source Table"},
  258.     {ACPI_SIG_HPET, AcpiDmTableInfoHpet,    NULL,           NULL,           "High Precision Event Timer table"},
  259.     {ACPI_SIG_IVRS, NULL,                   AcpiDmDumpIvrs, DtCompileIvrs,  "I/O Virtualization Reporting Structure"},
  260.     {ACPI_SIG_MADT, NULL,                   AcpiDmDumpMadt, DtCompileMadt,  "Multiple APIC Description Table"},
  261.     {ACPI_SIG_MCFG, NULL,                   AcpiDmDumpMcfg, DtCompileMcfg,  "Memory Mapped Configuration table"},
  262.     {ACPI_SIG_MCHI, AcpiDmTableInfoMchi,    NULL,           NULL,           "Management Controller Host Interface table"},
  263.     {ACPI_SIG_MSCT, NULL,                   AcpiDmDumpMsct, DtCompileMsct,  "Maximum System Characteristics Table"},
  264.     {ACPI_SIG_RSDT, NULL,                   AcpiDmDumpRsdt, DtCompileRsdt,  "Root System Description Table"},
  265.     {ACPI_SIG_SBST, AcpiDmTableInfoSbst,    NULL,           NULL,           "Smart Battery Specification Table"},
  266.     {ACPI_SIG_SLIC, AcpiDmTableInfoSlic,    NULL,           NULL,           "Software Licensing Description Table"},
  267.     {ACPI_SIG_SLIT, NULL,                   AcpiDmDumpSlit, DtCompileSlit,  "System Locality Information Table"},
  268.     {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr,    NULL,           NULL,           "Serial Port Console Redirection table"},
  269.     {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi,    NULL,           NULL,           "Server Platform Management Interface table"},
  270.     {ACPI_SIG_SRAT, NULL,                   AcpiDmDumpSrat, DtCompileSrat,  "System Resource Affinity Table"},
  271.     {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa,    NULL,           NULL,           "Trusted Computing Platform Alliance table"},
  272.     {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           NULL,           "UEFI Boot Optimization Table"},
  273.     {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           NULL,           "Windows ACPI Emulated Devices Table"},
  274.     {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, DtCompileWdat,  "Watchdog Action Table"},
  275.     {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           NULL,           "Watchdog Resource Table"},
  276.     {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, DtCompileXsdt,  "Extended System Description Table"},
  277.     {NULL,          NULL,                   NULL,           NULL,           NULL}
  278. };
  279.  
  280.  
  281. /*******************************************************************************
  282.  *
  283.  * FUNCTION:    AcpiTbGenerateChecksum
  284.  *
  285.  * PARAMETERS:  Table               - Pointer to a valid ACPI table (with a
  286.  *                                    standard ACPI header)
  287.  *
  288.  * RETURN:      8 bit checksum of buffer
  289.  *
  290.  * DESCRIPTION: Computes an 8 bit checksum of the table.
  291.  *
  292.  ******************************************************************************/
  293.  
  294. UINT8
  295. AcpiTbGenerateChecksum (
  296.     ACPI_TABLE_HEADER       *Table)
  297. {
  298.     UINT8                   Checksum;
  299.  
  300.  
  301.     /* Sum the entire table as-is */
  302.  
  303.     Checksum = AcpiTbChecksum ((UINT8 *) Table, Table->Length);
  304.  
  305.     /* Subtract off the existing checksum value in the table */
  306.  
  307.     Checksum = (UINT8) (Checksum - Table->Checksum);
  308.  
  309.     /* Compute the final checksum */
  310.  
  311.     Checksum = (UINT8) (0 - Checksum);
  312.     return (Checksum);
  313. }
  314.  
  315.  
  316. /*******************************************************************************
  317.  *
  318.  * FUNCTION:    AcpiDmGetTableData
  319.  *
  320.  * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
  321.  *
  322.  * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
  323.  *
  324.  * DESCRIPTION: Find a match in the global table of supported ACPI tables
  325.  *
  326.  ******************************************************************************/
  327.  
  328. ACPI_DMTABLE_DATA *
  329. AcpiDmGetTableData (
  330.     char                    *Signature)
  331. {
  332.     ACPI_DMTABLE_DATA       *TableData;
  333.  
  334.  
  335.     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
  336.     {
  337.         if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
  338.         {
  339.             return (TableData);
  340.         }
  341.     }
  342.  
  343.     return (NULL);
  344. }
  345.  
  346.  
  347. /*******************************************************************************
  348.  *
  349.  * FUNCTION:    AcpiDmDumpDataTable
  350.  *
  351.  * PARAMETERS:  Table               - An ACPI table
  352.  *
  353.  * RETURN:      None.
  354.  *
  355.  * DESCRIPTION: Format the contents of an ACPI data table (any table other
  356.  *              than an SSDT or DSDT that does not contain executable AML code)
  357.  *
  358.  ******************************************************************************/
  359.  
  360. void
  361. AcpiDmDumpDataTable (
  362.     ACPI_TABLE_HEADER       *Table)
  363. {
  364.     ACPI_STATUS             Status;
  365.     ACPI_DMTABLE_DATA       *TableData;
  366.     UINT32                  Length;
  367.  
  368.  
  369.     /* Ignore tables that contain AML */
  370.  
  371.     if (AcpiUtIsAmlTable (Table))
  372.     {
  373.         return;
  374.     }
  375.  
  376.     /*
  377.      * Handle tables that don't use the common ACPI table header structure.
  378.      * Currently, these are the FACS and RSDP.
  379.      */
  380.     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
  381.     {
  382.         Length = Table->Length;
  383.         AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
  384.     }
  385.     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
  386.     {
  387.         Length = AcpiDmDumpRsdp (Table);
  388.     }
  389.     else
  390.     {
  391.         /*
  392.          * All other tables must use the common ACPI table header, dump it now
  393.          */
  394.         Length = Table->Length;
  395.         Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
  396.         if (ACPI_FAILURE (Status))
  397.         {
  398.             return;
  399.         }
  400.         AcpiOsPrintf ("\n");
  401.  
  402.         /* Match signature and dispatch appropriately */
  403.  
  404.         TableData = AcpiDmGetTableData (Table->Signature);
  405.         if (!TableData)
  406.         {
  407.             if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
  408.             {
  409.                 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
  410.                     Table->Signature);
  411.             }
  412.             else
  413.             {
  414.                 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
  415.                     Table->Signature);
  416.             }
  417.         }
  418.         else if (TableData->TableHandler)
  419.         {
  420.             /* Complex table, has a handler */
  421.  
  422.             TableData->TableHandler (Table);
  423.         }
  424.         else if (TableData->TableInfo)
  425.         {
  426.             /* Simple table, just walk the info table */
  427.  
  428.             AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
  429.         }
  430.     }
  431.  
  432.     /* Always dump the raw table data */
  433.  
  434.     AcpiOsPrintf ("\nRaw Table Data\n\n");
  435.     AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
  436. }
  437.  
  438.  
  439. /*******************************************************************************
  440.  *
  441.  * FUNCTION:    AcpiDmLineHeader
  442.  *
  443.  * PARAMETERS:  Offset              - Current byte offset, from table start
  444.  *              ByteLength          - Length of the field in bytes, 0 for flags
  445.  *              Name                - Name of this field
  446.  *              Value               - Optional value, displayed on left of ':'
  447.  *
  448.  * RETURN:      None
  449.  *
  450.  * DESCRIPTION: Utility routines for formatting output lines. Displays the
  451.  *              current table offset in hex and decimal, the field length,
  452.  *              and the field name.
  453.  *
  454.  ******************************************************************************/
  455.  
  456. void
  457. AcpiDmLineHeader (
  458.     UINT32                  Offset,
  459.     UINT32                  ByteLength,
  460.     char                    *Name)
  461. {
  462.  
  463.     if (ByteLength)
  464.     {
  465.         AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %28s : ",
  466.             Offset, Offset, ByteLength, Name);
  467.     }
  468.     else
  469.     {
  470.         AcpiOsPrintf ("%43s : ",
  471.             Name);
  472.     }
  473. }
  474.  
  475. void
  476. AcpiDmLineHeader2 (
  477.     UINT32                  Offset,
  478.     UINT32                  ByteLength,
  479.     char                    *Name,
  480.     UINT32                  Value)
  481. {
  482.  
  483.     if (ByteLength)
  484.     {
  485.         AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %24s % 3d : ",
  486.             Offset, Offset, ByteLength, Name, Value);
  487.     }
  488.     else
  489.     {
  490.         AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s % 3d : ",
  491.             Offset, Offset, Name, Value);
  492.     }
  493. }
  494.  
  495.  
  496. /*******************************************************************************
  497.  *
  498.  * FUNCTION:    AcpiDmDumpTable
  499.  *
  500.  * PARAMETERS:  TableLength         - Length of the entire ACPI table
  501.  *              TableOffset         - Starting offset within the table for this
  502.  *                                    sub-descriptor (0 if main table)
  503.  *              Table               - The ACPI table
  504.  *              SubtableLength      - Length of this sub-descriptor
  505.  *              Info                - Info table for this ACPI table
  506.  *
  507.  * RETURN:      None
  508.  *
  509.  * DESCRIPTION: Display ACPI table contents by walking the Info table.
  510.  *
  511.  ******************************************************************************/
  512.  
  513. ACPI_STATUS
  514. AcpiDmDumpTable (
  515.     UINT32                  TableLength,
  516.     UINT32                  TableOffset,
  517.     void                    *Table,
  518.     UINT32                  SubtableLength,
  519.     ACPI_DMTABLE_INFO       *Info)
  520. {
  521.     UINT8                   *Target;
  522.     UINT32                  CurrentOffset;
  523.     UINT32                  ByteLength;
  524.     UINT8                   Temp8;
  525.     UINT16                  Temp16;
  526.     ACPI_DMTABLE_DATA       *TableData;
  527.     const char              *Name;
  528.     BOOLEAN                 LastOutputBlankLine = FALSE;
  529.     char                    RepairedName[8];
  530.  
  531.  
  532.     if (!Info)
  533.     {
  534.         AcpiOsPrintf ("Display not implemented\n");
  535.         return (AE_NOT_IMPLEMENTED);
  536.     }
  537.  
  538.     /* Walk entire Info table; Null name terminates */
  539.  
  540.     for (; Info->Name; Info++)
  541.     {
  542.         /*
  543.          * Target points to the field within the ACPI Table. CurrentOffset is
  544.          * the offset of the field from the start of the main table.
  545.          */
  546.         Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
  547.         CurrentOffset = TableOffset + Info->Offset;
  548.  
  549.         /* Check for beyond EOT or beyond subtable end */
  550.  
  551.         if ((CurrentOffset >= TableLength) ||
  552.             (SubtableLength && (Info->Offset >= SubtableLength)))
  553.         {
  554.             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
  555.             return (AE_BAD_DATA);
  556.         }
  557.  
  558.         /* Generate the byte length for this field */
  559.  
  560.         switch (Info->Opcode)
  561.         {
  562.         case ACPI_DMT_UINT8:
  563.         case ACPI_DMT_CHKSUM:
  564.         case ACPI_DMT_SPACEID:
  565.         case ACPI_DMT_IVRS:
  566.         case ACPI_DMT_MADT:
  567.         case ACPI_DMT_SRAT:
  568.         case ACPI_DMT_ASF:
  569.         case ACPI_DMT_HESTNTYP:
  570.         case ACPI_DMT_FADTPM:
  571.             ByteLength = 1;
  572.             break;
  573.         case ACPI_DMT_UINT16:
  574.         case ACPI_DMT_DMAR:
  575.         case ACPI_DMT_HEST:
  576.             ByteLength = 2;
  577.             break;
  578.         case ACPI_DMT_UINT24:
  579.             ByteLength = 3;
  580.             break;
  581.         case ACPI_DMT_UINT32:
  582.         case ACPI_DMT_NAME4:
  583.         case ACPI_DMT_SIG:
  584.             ByteLength = 4;
  585.             break;
  586.         case ACPI_DMT_NAME6:
  587.             ByteLength = 6;
  588.             break;
  589.         case ACPI_DMT_UINT56:
  590.             ByteLength = 7;
  591.             break;
  592.         case ACPI_DMT_UINT64:
  593.         case ACPI_DMT_NAME8:
  594.             ByteLength = 8;
  595.             break;
  596.         case ACPI_DMT_BUF16:
  597.             ByteLength = 16;
  598.             break;
  599.         case ACPI_DMT_STRING:
  600.             ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
  601.             break;
  602.         case ACPI_DMT_GAS:
  603.             if (!LastOutputBlankLine)
  604.             {
  605.                 AcpiOsPrintf ("\n");
  606.                 LastOutputBlankLine = TRUE;
  607.             }
  608.             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
  609.             break;
  610.         case ACPI_DMT_HESTNTFY:
  611.             if (!LastOutputBlankLine)
  612.             {
  613.                 AcpiOsPrintf ("\n");
  614.                 LastOutputBlankLine = TRUE;
  615.             }
  616.             ByteLength = sizeof (ACPI_HEST_NOTIFY);
  617.             break;
  618.         default:
  619.             ByteLength = 0;
  620.             break;
  621.         }
  622.  
  623.         if (CurrentOffset + ByteLength > TableLength)
  624.         {
  625.             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
  626.             return (AE_BAD_DATA);
  627.         }
  628.  
  629.         /* Start a new line and decode the opcode */
  630.  
  631.         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
  632.  
  633.         switch (Info->Opcode)
  634.         {
  635.         /* Single-bit Flag fields. Note: Opcode is the bit position */
  636.  
  637.         case ACPI_DMT_FLAG0:
  638.         case ACPI_DMT_FLAG1:
  639.         case ACPI_DMT_FLAG2:
  640.         case ACPI_DMT_FLAG3:
  641.         case ACPI_DMT_FLAG4:
  642.         case ACPI_DMT_FLAG5:
  643.         case ACPI_DMT_FLAG6:
  644.         case ACPI_DMT_FLAG7:
  645.  
  646.             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
  647.             break;
  648.  
  649.         /* 2-bit Flag fields */
  650.  
  651.         case ACPI_DMT_FLAGS0:
  652.  
  653.             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
  654.             break;
  655.  
  656.         case ACPI_DMT_FLAGS2:
  657.  
  658.             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
  659.             break;
  660.  
  661.         /* Standard Data Types */
  662.  
  663.         case ACPI_DMT_UINT8:
  664.  
  665.             AcpiOsPrintf ("%2.2X\n", *Target);
  666.             break;
  667.  
  668.         case ACPI_DMT_UINT16:
  669.  
  670.             AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
  671.             break;
  672.  
  673.         case ACPI_DMT_UINT24:
  674.  
  675.             AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
  676.                 *Target, *(Target + 1), *(Target + 2));
  677.             break;
  678.  
  679.         case ACPI_DMT_UINT32:
  680.  
  681.             AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
  682.             break;
  683.  
  684.         case ACPI_DMT_UINT56:
  685.  
  686.             for (Temp8 = 0; Temp8 < 7; Temp8++)
  687.             {
  688.                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
  689.             }
  690.             AcpiOsPrintf ("\n");
  691.             break;
  692.  
  693.         case ACPI_DMT_UINT64:
  694.  
  695.             AcpiOsPrintf ("%8.8X%8.8X\n",
  696.                 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
  697.             break;
  698.  
  699.         case ACPI_DMT_BUF16:
  700.  
  701.             /* Buffer of length 16 */
  702.  
  703.             for (Temp8 = 0; Temp8 < 16; Temp8++)
  704.             {
  705.                 AcpiOsPrintf ("%2.2X,", Target[Temp8]);
  706.             }
  707.             AcpiOsPrintf ("\n");
  708.             break;
  709.  
  710.         case ACPI_DMT_STRING:
  711.  
  712.             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
  713.             break;
  714.  
  715.         /* Fixed length ASCII name fields */
  716.  
  717.         case ACPI_DMT_SIG:
  718.  
  719.             AcpiDmCheckAscii (Target, RepairedName, 4);
  720.             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
  721.             TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
  722.             if (TableData)
  723.             {
  724.                 AcpiOsPrintf ("/* %s */", TableData->Name);
  725.             }
  726.             AcpiOsPrintf ("\n");
  727.             break;
  728.  
  729.         case ACPI_DMT_NAME4:
  730.  
  731.             AcpiDmCheckAscii (Target, RepairedName, 4);
  732.             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
  733.             break;
  734.  
  735.         case ACPI_DMT_NAME6:
  736.  
  737.             AcpiDmCheckAscii (Target, RepairedName, 6);
  738.             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
  739.             break;
  740.  
  741.         case ACPI_DMT_NAME8:
  742.  
  743.             AcpiDmCheckAscii (Target, RepairedName, 8);
  744.             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
  745.             break;
  746.  
  747.         /* Special Data Types */
  748.  
  749.         case ACPI_DMT_CHKSUM:
  750.  
  751.             /* Checksum, display and validate */
  752.  
  753.             AcpiOsPrintf ("%2.2X", *Target);
  754.             Temp8 = AcpiTbGenerateChecksum (Table);
  755.             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
  756.             {
  757.                 AcpiOsPrintf (
  758.                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
  759.             }
  760.             AcpiOsPrintf ("\n");
  761.             break;
  762.  
  763.         case ACPI_DMT_SPACEID:
  764.  
  765.             /* Address Space ID */
  766.  
  767.             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target));
  768.             break;
  769.  
  770.         case ACPI_DMT_GAS:
  771.  
  772.             /* Generic Address Structure */
  773.  
  774.             AcpiOsPrintf ("<Generic Address Structure>\n");
  775.             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
  776.                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
  777.             AcpiOsPrintf ("\n");
  778.             LastOutputBlankLine = TRUE;
  779.             break;
  780.  
  781.         case ACPI_DMT_ASF:
  782.  
  783.             /* ASF subtable types */
  784.  
  785.             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
  786.             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
  787.             {
  788.                 Temp16 = ACPI_ASF_TYPE_RESERVED;
  789.             }
  790.  
  791.             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmAsfSubnames[Temp16]);
  792.             break;
  793.  
  794.         case ACPI_DMT_DMAR:
  795.  
  796.             /* DMAR subtable types */
  797.  
  798.             Temp16 = ACPI_GET16 (Target);
  799.             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
  800.             {
  801.                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
  802.             }
  803.  
  804.             AcpiOsPrintf ("%4.4X <%s>\n", ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
  805.             break;
  806.  
  807.         case ACPI_DMT_HEST:
  808.  
  809.             /* HEST subtable types */
  810.  
  811.             Temp16 = ACPI_GET16 (Target);
  812.             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
  813.             {
  814.                 Temp16 = ACPI_HEST_TYPE_RESERVED;
  815.             }
  816.  
  817.             AcpiOsPrintf ("%4.4X (%s)\n", ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
  818.             break;
  819.  
  820.         case ACPI_DMT_HESTNTFY:
  821.  
  822.             AcpiOsPrintf ("<Hardware Error Notification Structure>\n");
  823.             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
  824.                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
  825.             AcpiOsPrintf ("\n");
  826.             LastOutputBlankLine = TRUE;
  827.             break;
  828.  
  829.         case ACPI_DMT_HESTNTYP:
  830.  
  831.             /* HEST Notify types */
  832.  
  833.             Temp8 = *Target;
  834.             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
  835.             {
  836.                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
  837.             }
  838.  
  839.             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmHestNotifySubnames[Temp8]);
  840.             break;
  841.  
  842.  
  843.         case ACPI_DMT_MADT:
  844.  
  845.             /* MADT subtable types */
  846.  
  847.             Temp8 = *Target;
  848.             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
  849.             {
  850.                 Temp8 = ACPI_MADT_TYPE_RESERVED;
  851.             }
  852.  
  853.             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]);
  854.             break;
  855.  
  856.         case ACPI_DMT_SRAT:
  857.  
  858.             /* SRAT subtable types */
  859.  
  860.             Temp8 = *Target;
  861.             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
  862.             {
  863.                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
  864.             }
  865.  
  866.             AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]);
  867.             break;
  868.  
  869.         case ACPI_DMT_FADTPM:
  870.  
  871.             /* FADT Preferred PM Profile names */
  872.  
  873.             Temp8 = *Target;
  874.             if (Temp8 > ACPI_FADT_PM_RESERVED)
  875.             {
  876.                 Temp8 = ACPI_FADT_PM_RESERVED;
  877.             }
  878.  
  879.             AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]);
  880.             break;
  881.  
  882.         case ACPI_DMT_IVRS:
  883.  
  884.             /* IVRS subtable types */
  885.  
  886.             Temp8 = *Target;
  887.             switch (Temp8)
  888.             {
  889.             case ACPI_IVRS_TYPE_HARDWARE:
  890.                 Name = AcpiDmIvrsSubnames[0];
  891.                 break;
  892.  
  893.             case ACPI_IVRS_TYPE_MEMORY1:
  894.             case ACPI_IVRS_TYPE_MEMORY2:
  895.             case ACPI_IVRS_TYPE_MEMORY3:
  896.                 Name = AcpiDmIvrsSubnames[1];
  897.                 break;
  898.  
  899.             default:
  900.                 Name = AcpiDmIvrsSubnames[2];
  901.                 break;
  902.             }
  903.  
  904.             AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name);
  905.             break;
  906.  
  907.         case ACPI_DMT_EXIT:
  908.             return (AE_OK);
  909.  
  910.         default:
  911.             ACPI_ERROR ((AE_INFO,
  912.                 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
  913.             return (AE_SUPPORT);
  914.         }
  915.     }
  916.  
  917.     if (TableOffset && !SubtableLength)
  918.     {
  919.         /* If this table is not the main table, subtable must have valid length */
  920.  
  921.         AcpiOsPrintf ("Invalid zero length subtable\n");
  922.         return (AE_BAD_DATA);
  923.     }
  924.  
  925.     return (AE_OK);
  926. }
  927.  
  928.  
  929. /*******************************************************************************
  930.  *
  931.  * FUNCTION:    AcpiDmCheckAscii
  932.  *
  933.  * PARAMETERS:  Name                - Ascii string
  934.  *              Count               - Number of characters to check
  935.  *
  936.  * RETURN:      None
  937.  *
  938.  * DESCRIPTION: Ensure that the requested number of characters are printable
  939.  *              Ascii characters. Sets non-printable and null chars to <space>.
  940.  *
  941.  ******************************************************************************/
  942.  
  943. static void
  944. AcpiDmCheckAscii (
  945.     UINT8                   *Name,
  946.     char                    *RepairedName,
  947.     UINT32                  Count)
  948. {
  949.     UINT32                  i;
  950.  
  951.  
  952.     for (i = 0; i < Count; i++)
  953.     {
  954.         RepairedName[i] = (char) Name[i];
  955.  
  956.         if (!Name[i])
  957.         {
  958.             return;
  959.         }
  960.         if (!isprint (Name[i]))
  961.         {
  962.             RepairedName[i] = ' ';
  963.         }
  964.     }
  965. }
  966.