dmtables.c revision 298714
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: dmtables - disassembler ACPI table support 467754Smsmith * 5102550Siwasaki *****************************************************************************/ 667754Smsmith 767754Smsmith/* 867754Smsmith * Copyright (C) 2000 - 2016, Intel Corp. 967754Smsmith * All rights reserved. 1067754Smsmith * 1167754Smsmith * Redistribution and use in source and binary forms, with or without 1267754Smsmith * modification, are permitted provided that the following conditions 1391116Smsmith * are met: 1470243Smsmith * 1. Redistributions of source code must retain the above copyright 1567754Smsmith * notice, this list of conditions, and the following disclaimer, 1667754Smsmith * without modification. 1767754Smsmith * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1867754Smsmith * substantially similar to the "NO WARRANTY" disclaimer below 1967754Smsmith * ("Disclaimer") and any redistribution must be conditioned upon 2067754Smsmith * including a substantially similar Disclaimer requirement for further 2167754Smsmith * binary redistribution. 2267754Smsmith * 3. Neither the names of the above-listed copyright holders nor the names 2367754Smsmith * of any contributors may be used to endorse or promote products derived 2467754Smsmith * from this software without specific prior written permission. 2567754Smsmith * 2667754Smsmith * Alternatively, this software may be distributed under the terms of the 2767754Smsmith * GNU General Public License ("GPL") version 2 as published by the Free 2867754Smsmith * Software Foundation. 2967754Smsmith * 3067754Smsmith * NO WARRANTY 3167754Smsmith * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3267754Smsmith * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3367754Smsmith * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3467754Smsmith * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3567754Smsmith * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3667754Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3767754Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3867754Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3967754Smsmith * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4067754Smsmith * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4167754Smsmith * POSSIBILITY OF SUCH DAMAGES. 4267754Smsmith */ 4367754Smsmith 4467754Smsmith#include <contrib/dev/acpica/compiler/aslcompiler.h> 4567754Smsmith#include <contrib/dev/acpica/include/acapps.h> 4667754Smsmith#include <contrib/dev/acpica/include/acdispat.h> 4767754Smsmith#include <contrib/dev/acpica/include/acnamesp.h> 4867754Smsmith#include <contrib/dev/acpica/include/actables.h> 4967754Smsmith#include <contrib/dev/acpica/include/acparser.h> 5067754Smsmith 5167754Smsmith#include <stdio.h> 5267754Smsmith#include <time.h> 5367754Smsmith 5467754Smsmith#define _COMPONENT ACPI_TOOLS 5567754Smsmith ACPI_MODULE_NAME ("dmtables") 5667754Smsmith 5767754Smsmith 5867754Smsmith/* Local prototypes */ 5967754Smsmith 6067754Smsmithstatic void 6167754SmsmithAdCreateTableHeader ( 6267754Smsmith char *Filename, 6367754Smsmith ACPI_TABLE_HEADER *Table); 6467754Smsmith 6567754Smsmithstatic ACPI_STATUS 6667754SmsmithAdStoreTable ( 6767754Smsmith ACPI_TABLE_HEADER *Table, 6867754Smsmith UINT32 *TableIndex); 6967754Smsmith 7067754Smsmith 7167754Smsmithextern ACPI_TABLE_DESC LocalTables[1]; 7267754Smsmithextern ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; 7367754Smsmith 7467754Smsmith 7567754Smsmith/****************************************************************************** 7667754Smsmith * 7767754Smsmith * FUNCTION: AdDisassemblerHeader 7867754Smsmith * 7967754Smsmith * PARAMETERS: Filename - Input file for the table 8067754Smsmith * TableType - Either AML or DataTable 8167754Smsmith * 8267754Smsmith * RETURN: None 8367754Smsmith * 8467754Smsmith * DESCRIPTION: Create the disassembler header, including ACPICA signon with 8567754Smsmith * current time and date. 8667754Smsmith * 8767754Smsmith *****************************************************************************/ 8867754Smsmith 8967754Smsmithvoid 9067754SmsmithAdDisassemblerHeader ( 9167754Smsmith char *Filename, 9267754Smsmith UINT8 TableType) 9367754Smsmith{ 9467754Smsmith time_t Timer; 9567754Smsmith 9667754Smsmith 9767754Smsmith time (&Timer); 9867754Smsmith 9967754Smsmith /* Header and input table info */ 10067754Smsmith 10167754Smsmith AcpiOsPrintf ("/*\n"); 10267754Smsmith AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * ")); 10367754Smsmith 10467754Smsmith if (TableType == ACPI_IS_AML_TABLE) 10567754Smsmith { 10667754Smsmith if (AcpiGbl_CstyleDisassembly) 10767754Smsmith { 10867754Smsmith AcpiOsPrintf ( 10967754Smsmith " * Disassembling to symbolic ASL+ operators\n" 11067754Smsmith " *\n"); 11167754Smsmith } 11267754Smsmith else 11367754Smsmith { 11467754Smsmith AcpiOsPrintf ( 11567754Smsmith " * Disassembling to non-symbolic legacy ASL operators\n" 11667754Smsmith " *\n"); 11767754Smsmith } 11867754Smsmith } 11967754Smsmith 12067754Smsmith AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer)); 12167754Smsmith AcpiOsPrintf (" *\n"); 12267754Smsmith} 12367754Smsmith 124102550Siwasaki 12567754Smsmith/****************************************************************************** 126102550Siwasaki * 12791116Smsmith * FUNCTION: AdCreateTableHeader 12867754Smsmith * 12967754Smsmith * PARAMETERS: Filename - Input file for the table 13084491Smsmith * Table - Pointer to the raw table 13184491Smsmith * 13284491Smsmith * RETURN: None 13384491Smsmith * 13467754Smsmith * DESCRIPTION: Create the ASL table header, including ACPICA signon with 13567754Smsmith * current time and date. 13683174Smsmith * 13767754Smsmith *****************************************************************************/ 13867754Smsmith 13967754Smsmithstatic void 14084491SmsmithAdCreateTableHeader ( 14167754Smsmith char *Filename, 14284491Smsmith ACPI_TABLE_HEADER *Table) 14367754Smsmith{ 14467754Smsmith UINT8 Checksum; 14567754Smsmith 14667754Smsmith 14767754Smsmith /* Reset globals for External statements */ 14867754Smsmith 14967754Smsmith AcpiGbl_NumExternalMethods = 0; 15067754Smsmith AcpiGbl_ResolvedExternalMethods = 0; 15167754Smsmith 15267754Smsmith /* 15367754Smsmith * Print file header and dump original table header 15467754Smsmith */ 15567754Smsmith AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE); 15691116Smsmith 15767754Smsmith AcpiOsPrintf (" * Original Table Header:\n"); 15867754Smsmith AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature); 15967754Smsmith AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length); 16067754Smsmith 16167754Smsmith /* Print and validate the revision */ 16267754Smsmith 16367754Smsmith AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision); 16467754Smsmith 16567754Smsmith switch (Table->Revision) 16667754Smsmith { 16767754Smsmith case 0: 16867754Smsmith 16967754Smsmith AcpiOsPrintf (" **** Invalid Revision"); 17067754Smsmith break; 17191116Smsmith 17267754Smsmith case 1: 17391116Smsmith 17467754Smsmith /* Revision of DSDT controls the ACPI integer width */ 17567754Smsmith 17667754Smsmith if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) 17767754Smsmith { 17867754Smsmith AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support"); 17967754Smsmith } 18067754Smsmith break; 18167754Smsmith 18267754Smsmith default: 183102550Siwasaki 18467754Smsmith break; 18567754Smsmith } 18667754Smsmith 18767754Smsmith /* Print and validate the table checksum */ 18867754Smsmith 18967754Smsmith AcpiOsPrintf ("\n * Checksum 0x%2.2X", Table->Checksum); 19067754Smsmith 19167754Smsmith Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length); 19267754Smsmith if (Checksum) 19367754Smsmith { 19467754Smsmith AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X", 19567754Smsmith (UINT8) (Table->Checksum - Checksum)); 19667754Smsmith } 19767754Smsmith 19867754Smsmith AcpiOsPrintf ("\n"); 19967754Smsmith AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId); 20067754Smsmith AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId); 20167754Smsmith AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision); 20267754Smsmith AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId); 20383174Smsmith AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision); 20467754Smsmith AcpiOsPrintf (" */\n"); 20583174Smsmith 20683174Smsmith /* 20783174Smsmith * Open the ASL definition block. 20883174Smsmith * 20967754Smsmith * Note: the AMLFilename string is left zero-length in order to just let 21067754Smsmith * the compiler create it when the disassembled file is compiled. This 21167754Smsmith * makes it easier to rename the disassembled ASL file if needed. 21267754Smsmith */ 21367754Smsmith AcpiOsPrintf ( 21467754Smsmith "DefinitionBlock (\"\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n", 21567754Smsmith Table->Signature, Table->Revision, 21667754Smsmith Table->OemId, Table->OemTableId, Table->OemRevision); 21767754Smsmith} 21867754Smsmith 21967754Smsmith 22067754Smsmith/****************************************************************************** 22167754Smsmith * 22267754Smsmith * FUNCTION: AdDisplayTables 22367754Smsmith * 22467754Smsmith * PARAMETERS: Filename - Input file for the table 22567754Smsmith * Table - Pointer to the raw table 22667754Smsmith * 22767754Smsmith * RETURN: Status 22867754Smsmith * 22967754Smsmith * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables 23067754Smsmith * 23167754Smsmith *****************************************************************************/ 23267754Smsmith 23367754SmsmithACPI_STATUS 23467754SmsmithAdDisplayTables ( 23583174Smsmith char *Filename, 23683174Smsmith ACPI_TABLE_HEADER *Table) 23767754Smsmith{ 23867754Smsmith 23991116Smsmith 24083174Smsmith if (!AcpiGbl_ParseOpRoot) 24167754Smsmith { 24273561Smsmith return (AE_NOT_EXIST); 24373561Smsmith } 24473561Smsmith 24573561Smsmith if (!AcpiGbl_DmOpt_Listing) 24667754Smsmith { 24767754Smsmith AdCreateTableHeader (Filename, Table); 24867754Smsmith } 249100966Siwasaki 25067754Smsmith AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX); 25167754Smsmith MpEmitMappingInfo (); 25267754Smsmith 25367754Smsmith if (AcpiGbl_DmOpt_Listing) 25467754Smsmith { 25567754Smsmith AcpiOsPrintf ("\n\nTable Header:\n"); 25667754Smsmith AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER), 25767754Smsmith DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 25867754Smsmith 25967754Smsmith AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length); 26067754Smsmith AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), 26167754Smsmith Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 26267754Smsmith } 26367754Smsmith 26467754Smsmith return (AE_OK); 26567754Smsmith} 26667754Smsmith 26799679Siwasaki 26867754Smsmith/******************************************************************************* 26967754Smsmith * 27067754Smsmith * FUNCTION: AdStoreTable 27167754Smsmith * 27267754Smsmith * PARAMETERS: Table - Table header 27367754Smsmith * TableIndex - Where the table index is returned 27484491Smsmith * 27567754Smsmith * RETURN: Status and table index. 27667754Smsmith * 27769450Smsmith * DESCRIPTION: Add an ACPI table to the global table list 27867754Smsmith * 27967754Smsmith ******************************************************************************/ 28067754Smsmith 28167754Smsmithstatic ACPI_STATUS 28269450SmsmithAdStoreTable ( 28367754Smsmith ACPI_TABLE_HEADER *Table, 28467754Smsmith UINT32 *TableIndex) 28567754Smsmith{ 28667754Smsmith ACPI_STATUS Status; 28767754Smsmith ACPI_TABLE_DESC *TableDesc; 28867754Smsmith 28969450Smsmith 29069450Smsmith Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc); 29169450Smsmith if (ACPI_FAILURE (Status)) 29269450Smsmith { 293100966Siwasaki return (Status); 29467754Smsmith } 29569450Smsmith 29667754Smsmith /* Initialize added table */ 29767754Smsmith 29867754Smsmith AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table), 29969450Smsmith ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table); 30069450Smsmith Status = AcpiTbValidateTable (TableDesc); 30169450Smsmith return (Status); 30291116Smsmith} 30391116Smsmith 30491116Smsmith 30569450Smsmith/****************************************************************************** 30669450Smsmith * 30791116Smsmith * FUNCTION: AdGetLocalTables 30869450Smsmith * 30969450Smsmith * PARAMETERS: None 31069450Smsmith * 31167754Smsmith * RETURN: Status 31267754Smsmith * 31369450Smsmith * DESCRIPTION: Get the ACPI tables from either memory or a file 31484491Smsmith * 31567754Smsmith *****************************************************************************/ 31667754Smsmith 31783174SmsmithACPI_STATUS 31882367SmsmithAdGetLocalTables ( 31967754Smsmith void) 32067754Smsmith{ 32167754Smsmith ACPI_STATUS Status; 32267754Smsmith ACPI_TABLE_HEADER TableHeader; 32384491Smsmith ACPI_TABLE_HEADER *NewTable; 32484491Smsmith UINT32 TableIndex; 32567754Smsmith 32667754Smsmith 32767754Smsmith /* Get the DSDT via table override */ 32891116Smsmith 32967754Smsmith ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); 33067754Smsmith AcpiOsTableOverride (&TableHeader, &NewTable); 33167754Smsmith if (!NewTable) 33284491Smsmith { 33367754Smsmith fprintf (stderr, "Could not obtain DSDT\n"); 33467754Smsmith return (AE_NO_ACPI_TABLES); 33567754Smsmith } 33667754Smsmith 33767754Smsmith AdWriteTable (NewTable, NewTable->Length, 33867754Smsmith ACPI_SIG_DSDT, NewTable->OemTableId); 33967754Smsmith 34069746Smsmith /* Store DSDT in the Table Manager */ 34184491Smsmith 34267754Smsmith Status = AdStoreTable (NewTable, &TableIndex); 34367754Smsmith if (ACPI_FAILURE (Status)) 34467754Smsmith { 34567754Smsmith fprintf (stderr, "Could not store DSDT\n"); 34684491Smsmith return (AE_NO_ACPI_TABLES); 34767754Smsmith } 34867754Smsmith 34967754Smsmith return (AE_OK); 35067754Smsmith} 35167754Smsmith 35267754Smsmith 35367754Smsmith/****************************************************************************** 35467754Smsmith * 35567754Smsmith * FUNCTION: AdParseTable 35667754Smsmith * 35767754Smsmith * PARAMETERS: Table - Pointer to the raw table 35867754Smsmith * OwnerId - Returned OwnerId of the table 35967754Smsmith * LoadTable - If add table to the global table list 36067754Smsmith * External - If this is an external table 36167754Smsmith * 36267754Smsmith * RETURN: Status 36367754Smsmith * 36467754Smsmith * DESCRIPTION: Parse an ACPI AML table 36567754Smsmith * 36667754Smsmith *****************************************************************************/ 36767754Smsmith 36867754SmsmithACPI_STATUS 36967754SmsmithAdParseTable ( 37067754Smsmith ACPI_TABLE_HEADER *Table, 37167754Smsmith ACPI_OWNER_ID *OwnerId, 37267754Smsmith BOOLEAN LoadTable, 37367754Smsmith BOOLEAN External) 37467754Smsmith{ 37567754Smsmith ACPI_STATUS Status = AE_OK; 37667754Smsmith ACPI_WALK_STATE *WalkState; 37767754Smsmith UINT8 *AmlStart; 37867754Smsmith UINT32 AmlLength; 37967754Smsmith UINT32 TableIndex; 38067754Smsmith 38191116Smsmith 38267754Smsmith if (!Table) 38367754Smsmith { 38467754Smsmith return (AE_NOT_EXIST); 38567754Smsmith } 38667754Smsmith 38767754Smsmith /* Pass 1: Parse everything except control method bodies */ 388100966Siwasaki 389100966Siwasaki fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); 390100966Siwasaki 391100966Siwasaki AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); 392100966Siwasaki AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); 393100966Siwasaki 394100966Siwasaki /* Create the root object */ 39567754Smsmith 39667754Smsmith AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (AmlStart); 39799679Siwasaki if (!AcpiGbl_ParseOpRoot) 39867754Smsmith { 39967754Smsmith return (AE_NO_MEMORY); 40067754Smsmith } 40167754Smsmith 40267754Smsmith /* Create and initialize a new walk state */ 40367754Smsmith 40467754Smsmith WalkState = AcpiDsCreateWalkState (0, AcpiGbl_ParseOpRoot, NULL, NULL); 40567754Smsmith if (!WalkState) 40667754Smsmith { 407100966Siwasaki return (AE_NO_MEMORY); 40867754Smsmith } 40967754Smsmith 41067754Smsmith Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, 41167754Smsmith NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 41267754Smsmith if (ACPI_FAILURE (Status)) 41384491Smsmith { 41467754Smsmith return (Status); 41567754Smsmith } 41667754Smsmith 41767754Smsmith WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 41867754Smsmith WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 41967754Smsmith 42067754Smsmith Status = AcpiPsParseAml (WalkState); 42167754Smsmith if (ACPI_FAILURE (Status)) 42299146Siwasaki { 42367754Smsmith return (Status); 42499146Siwasaki } 42567754Smsmith 42667754Smsmith /* If LoadTable is FALSE, we are parsing the last loaded table */ 42767754Smsmith 42899146Siwasaki TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; 42967754Smsmith 43067754Smsmith /* Pass 2 */ 43167754Smsmith 43267754Smsmith if (LoadTable) 43367754Smsmith { 43467754Smsmith Status = AdStoreTable (Table, &TableIndex); 43567754Smsmith if (ACPI_FAILURE (Status)) 43667754Smsmith { 43767754Smsmith return (Status); 43867754Smsmith } 43967754Smsmith Status = AcpiTbAllocateOwnerId (TableIndex); 44067754Smsmith if (ACPI_FAILURE (Status)) 44167754Smsmith { 44267754Smsmith return (Status); 443100966Siwasaki } 44484491Smsmith if (OwnerId) 44567754Smsmith { 44667754Smsmith Status = AcpiTbGetOwnerId (TableIndex, OwnerId); 44767754Smsmith if (ACPI_FAILURE (Status)) 44867754Smsmith { 44967754Smsmith return (Status); 45067754Smsmith } 45167754Smsmith } 45267754Smsmith } 45399146Siwasaki 45499146Siwasaki fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); 45599146Siwasaki 45667754Smsmith Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); 45799146Siwasaki if (ACPI_FAILURE (Status)) 45899146Siwasaki { 45999146Siwasaki return (Status); 46099146Siwasaki } 46199146Siwasaki 46299146Siwasaki /* No need to parse control methods of external table */ 46399146Siwasaki 46499146Siwasaki if (External) 46599146Siwasaki { 46699146Siwasaki return (AE_OK); 46799146Siwasaki } 46899146Siwasaki 46999146Siwasaki /* 47099146Siwasaki * Pass 3: Parse control methods and link their parse trees 47199146Siwasaki * into the main parse tree 47299146Siwasaki */ 47399146Siwasaki fprintf (stderr, 47499146Siwasaki "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); 47599146Siwasaki 47699146Siwasaki Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot); 47799146Siwasaki fprintf (stderr, "\n"); 47899146Siwasaki 47999146Siwasaki /* Process Resource Templates */ 48099146Siwasaki 48199146Siwasaki AcpiDmFindResources (AcpiGbl_ParseOpRoot); 48299146Siwasaki 48399146Siwasaki fprintf (stderr, "Parsing completed\n"); 48499146Siwasaki return (AE_OK); 48584491Smsmith} 48667754Smsmith