1291333Sjkim/****************************************************************************** 2291333Sjkim * 3291333Sjkim * Module Name: dmtables - disassembler ACPI table support 4291333Sjkim * 5291333Sjkim *****************************************************************************/ 6291333Sjkim 7291333Sjkim/* 8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9291333Sjkim * All rights reserved. 10291333Sjkim * 11291333Sjkim * Redistribution and use in source and binary forms, with or without 12291333Sjkim * modification, are permitted provided that the following conditions 13291333Sjkim * are met: 14291333Sjkim * 1. Redistributions of source code must retain the above copyright 15291333Sjkim * notice, this list of conditions, and the following disclaimer, 16291333Sjkim * without modification. 17291333Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18291333Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19291333Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20291333Sjkim * including a substantially similar Disclaimer requirement for further 21291333Sjkim * binary redistribution. 22291333Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23291333Sjkim * of any contributors may be used to endorse or promote products derived 24291333Sjkim * from this software without specific prior written permission. 25291333Sjkim * 26291333Sjkim * Alternatively, this software may be distributed under the terms of the 27291333Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28291333Sjkim * Software Foundation. 29291333Sjkim * 30291333Sjkim * NO WARRANTY 31291333Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32291333Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33291333Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34291333Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35291333Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36291333Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37291333Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38291333Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39291333Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40291333Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41291333Sjkim * POSSIBILITY OF SUCH DAMAGES. 42291333Sjkim */ 43291333Sjkim 44298714Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 45298714Sjkim#include <contrib/dev/acpica/include/acapps.h> 46298714Sjkim#include <contrib/dev/acpica/include/acdispat.h> 47298714Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 48298714Sjkim#include <contrib/dev/acpica/include/actables.h> 49298714Sjkim#include <contrib/dev/acpica/include/acparser.h> 50291333Sjkim 51291333Sjkim#include <stdio.h> 52291333Sjkim#include <time.h> 53291333Sjkim 54291333Sjkim#define _COMPONENT ACPI_TOOLS 55291333Sjkim ACPI_MODULE_NAME ("dmtables") 56291333Sjkim 57291333Sjkim 58291333Sjkim/* Local prototypes */ 59291333Sjkim 60291333Sjkimstatic void 61291333SjkimAdCreateTableHeader ( 62291333Sjkim char *Filename, 63291333Sjkim ACPI_TABLE_HEADER *Table); 64291333Sjkim 65291333Sjkimstatic ACPI_STATUS 66291333SjkimAdStoreTable ( 67291333Sjkim ACPI_TABLE_HEADER *Table, 68291333Sjkim UINT32 *TableIndex); 69291333Sjkim 70291333Sjkim 71291333Sjkimextern ACPI_TABLE_DESC LocalTables[1]; 72291333Sjkimextern ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; 73291333Sjkim 74291333Sjkim 75291333Sjkim/****************************************************************************** 76291333Sjkim * 77291333Sjkim * FUNCTION: AdDisassemblerHeader 78291333Sjkim * 79291333Sjkim * PARAMETERS: Filename - Input file for the table 80291333Sjkim * TableType - Either AML or DataTable 81291333Sjkim * 82291333Sjkim * RETURN: None 83291333Sjkim * 84291333Sjkim * DESCRIPTION: Create the disassembler header, including ACPICA signon with 85291333Sjkim * current time and date. 86291333Sjkim * 87291333Sjkim *****************************************************************************/ 88291333Sjkim 89291333Sjkimvoid 90291333SjkimAdDisassemblerHeader ( 91291333Sjkim char *Filename, 92291333Sjkim UINT8 TableType) 93291333Sjkim{ 94291333Sjkim time_t Timer; 95291333Sjkim 96291333Sjkim 97291333Sjkim time (&Timer); 98291333Sjkim 99291333Sjkim /* Header and input table info */ 100291333Sjkim 101291333Sjkim AcpiOsPrintf ("/*\n"); 102291333Sjkim AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * ")); 103291333Sjkim 104291333Sjkim if (TableType == ACPI_IS_AML_TABLE) 105291333Sjkim { 106291333Sjkim if (AcpiGbl_CstyleDisassembly) 107291333Sjkim { 108291333Sjkim AcpiOsPrintf ( 109291333Sjkim " * Disassembling to symbolic ASL+ operators\n" 110291333Sjkim " *\n"); 111291333Sjkim } 112291333Sjkim else 113291333Sjkim { 114291333Sjkim AcpiOsPrintf ( 115291333Sjkim " * Disassembling to non-symbolic legacy ASL operators\n" 116291333Sjkim " *\n"); 117291333Sjkim } 118291333Sjkim } 119291333Sjkim 120291333Sjkim AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer)); 121291333Sjkim AcpiOsPrintf (" *\n"); 122291333Sjkim} 123291333Sjkim 124291333Sjkim 125291333Sjkim/****************************************************************************** 126291333Sjkim * 127291333Sjkim * FUNCTION: AdCreateTableHeader 128291333Sjkim * 129291333Sjkim * PARAMETERS: Filename - Input file for the table 130291333Sjkim * Table - Pointer to the raw table 131291333Sjkim * 132291333Sjkim * RETURN: None 133291333Sjkim * 134291333Sjkim * DESCRIPTION: Create the ASL table header, including ACPICA signon with 135291333Sjkim * current time and date. 136291333Sjkim * 137291333Sjkim *****************************************************************************/ 138291333Sjkim 139291333Sjkimstatic void 140291333SjkimAdCreateTableHeader ( 141291333Sjkim char *Filename, 142291333Sjkim ACPI_TABLE_HEADER *Table) 143291333Sjkim{ 144291333Sjkim UINT8 Checksum; 145291333Sjkim 146291333Sjkim 147298714Sjkim /* Reset globals for External statements */ 148298714Sjkim 149298714Sjkim AcpiGbl_NumExternalMethods = 0; 150298714Sjkim AcpiGbl_ResolvedExternalMethods = 0; 151298714Sjkim 152291333Sjkim /* 153291333Sjkim * Print file header and dump original table header 154291333Sjkim */ 155291333Sjkim AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE); 156291333Sjkim 157291333Sjkim AcpiOsPrintf (" * Original Table Header:\n"); 158291333Sjkim AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature); 159291333Sjkim AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length); 160291333Sjkim 161291333Sjkim /* Print and validate the revision */ 162291333Sjkim 163291333Sjkim AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision); 164291333Sjkim 165291333Sjkim switch (Table->Revision) 166291333Sjkim { 167291333Sjkim case 0: 168291333Sjkim 169291333Sjkim AcpiOsPrintf (" **** Invalid Revision"); 170291333Sjkim break; 171291333Sjkim 172291333Sjkim case 1: 173291333Sjkim 174291333Sjkim /* Revision of DSDT controls the ACPI integer width */ 175291333Sjkim 176291333Sjkim if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) 177291333Sjkim { 178291333Sjkim AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support"); 179291333Sjkim } 180291333Sjkim break; 181291333Sjkim 182291333Sjkim default: 183291333Sjkim 184291333Sjkim break; 185291333Sjkim } 186291333Sjkim 187291333Sjkim /* Print and validate the table checksum */ 188291333Sjkim 189298714Sjkim AcpiOsPrintf ("\n * Checksum 0x%2.2X", Table->Checksum); 190291333Sjkim 191291333Sjkim Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length); 192291333Sjkim if (Checksum) 193291333Sjkim { 194291333Sjkim AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X", 195291333Sjkim (UINT8) (Table->Checksum - Checksum)); 196291333Sjkim } 197291333Sjkim 198291333Sjkim AcpiOsPrintf ("\n"); 199291333Sjkim AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId); 200291333Sjkim AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId); 201291333Sjkim AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision); 202291333Sjkim AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId); 203291333Sjkim AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision); 204291333Sjkim AcpiOsPrintf (" */\n"); 205291333Sjkim 206298714Sjkim /* 207298714Sjkim * Open the ASL definition block. 208298714Sjkim * 209298714Sjkim * Note: the AMLFilename string is left zero-length in order to just let 210298714Sjkim * the compiler create it when the disassembled file is compiled. This 211298714Sjkim * makes it easier to rename the disassembled ASL file if needed. 212298714Sjkim */ 213291333Sjkim AcpiOsPrintf ( 214298714Sjkim "DefinitionBlock (\"\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n", 215298714Sjkim Table->Signature, Table->Revision, 216291333Sjkim Table->OemId, Table->OemTableId, Table->OemRevision); 217291333Sjkim} 218291333Sjkim 219291333Sjkim 220291333Sjkim/****************************************************************************** 221291333Sjkim * 222291333Sjkim * FUNCTION: AdDisplayTables 223291333Sjkim * 224291333Sjkim * PARAMETERS: Filename - Input file for the table 225291333Sjkim * Table - Pointer to the raw table 226291333Sjkim * 227291333Sjkim * RETURN: Status 228291333Sjkim * 229291333Sjkim * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables 230291333Sjkim * 231291333Sjkim *****************************************************************************/ 232291333Sjkim 233291333SjkimACPI_STATUS 234291333SjkimAdDisplayTables ( 235291333Sjkim char *Filename, 236291333Sjkim ACPI_TABLE_HEADER *Table) 237291333Sjkim{ 238291333Sjkim 239291333Sjkim 240291333Sjkim if (!AcpiGbl_ParseOpRoot) 241291333Sjkim { 242291333Sjkim return (AE_NOT_EXIST); 243291333Sjkim } 244291333Sjkim 245291333Sjkim if (!AcpiGbl_DmOpt_Listing) 246291333Sjkim { 247291333Sjkim AdCreateTableHeader (Filename, Table); 248291333Sjkim } 249291333Sjkim 250291333Sjkim AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX); 251291333Sjkim MpEmitMappingInfo (); 252291333Sjkim 253291333Sjkim if (AcpiGbl_DmOpt_Listing) 254291333Sjkim { 255291333Sjkim AcpiOsPrintf ("\n\nTable Header:\n"); 256291333Sjkim AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER), 257291333Sjkim DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 258291333Sjkim 259291333Sjkim AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length); 260291333Sjkim AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), 261291333Sjkim Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 262291333Sjkim } 263291333Sjkim 264291333Sjkim return (AE_OK); 265291333Sjkim} 266291333Sjkim 267291333Sjkim 268291333Sjkim/******************************************************************************* 269291333Sjkim * 270291333Sjkim * FUNCTION: AdStoreTable 271291333Sjkim * 272291333Sjkim * PARAMETERS: Table - Table header 273291333Sjkim * TableIndex - Where the table index is returned 274291333Sjkim * 275291333Sjkim * RETURN: Status and table index. 276291333Sjkim * 277291333Sjkim * DESCRIPTION: Add an ACPI table to the global table list 278291333Sjkim * 279291333Sjkim ******************************************************************************/ 280291333Sjkim 281291333Sjkimstatic ACPI_STATUS 282291333SjkimAdStoreTable ( 283291333Sjkim ACPI_TABLE_HEADER *Table, 284291333Sjkim UINT32 *TableIndex) 285291333Sjkim{ 286291333Sjkim ACPI_STATUS Status; 287291333Sjkim ACPI_TABLE_DESC *TableDesc; 288291333Sjkim 289291333Sjkim 290291333Sjkim Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc); 291291333Sjkim if (ACPI_FAILURE (Status)) 292291333Sjkim { 293291333Sjkim return (Status); 294291333Sjkim } 295291333Sjkim 296291333Sjkim /* Initialize added table */ 297291333Sjkim 298291333Sjkim AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table), 299291333Sjkim ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table); 300291333Sjkim Status = AcpiTbValidateTable (TableDesc); 301291333Sjkim return (Status); 302291333Sjkim} 303291333Sjkim 304291333Sjkim 305291333Sjkim/****************************************************************************** 306291333Sjkim * 307291333Sjkim * FUNCTION: AdGetLocalTables 308291333Sjkim * 309291333Sjkim * PARAMETERS: None 310291333Sjkim * 311291333Sjkim * RETURN: Status 312291333Sjkim * 313291333Sjkim * DESCRIPTION: Get the ACPI tables from either memory or a file 314291333Sjkim * 315291333Sjkim *****************************************************************************/ 316291333Sjkim 317291333SjkimACPI_STATUS 318291333SjkimAdGetLocalTables ( 319291333Sjkim void) 320291333Sjkim{ 321291333Sjkim ACPI_STATUS Status; 322291333Sjkim ACPI_TABLE_HEADER TableHeader; 323291333Sjkim ACPI_TABLE_HEADER *NewTable; 324291333Sjkim UINT32 TableIndex; 325291333Sjkim 326291333Sjkim 327291333Sjkim /* Get the DSDT via table override */ 328291333Sjkim 329291333Sjkim ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); 330291333Sjkim AcpiOsTableOverride (&TableHeader, &NewTable); 331291333Sjkim if (!NewTable) 332291333Sjkim { 333291333Sjkim fprintf (stderr, "Could not obtain DSDT\n"); 334291333Sjkim return (AE_NO_ACPI_TABLES); 335291333Sjkim } 336291333Sjkim 337291333Sjkim AdWriteTable (NewTable, NewTable->Length, 338291333Sjkim ACPI_SIG_DSDT, NewTable->OemTableId); 339291333Sjkim 340291333Sjkim /* Store DSDT in the Table Manager */ 341291333Sjkim 342291333Sjkim Status = AdStoreTable (NewTable, &TableIndex); 343291333Sjkim if (ACPI_FAILURE (Status)) 344291333Sjkim { 345291333Sjkim fprintf (stderr, "Could not store DSDT\n"); 346291333Sjkim return (AE_NO_ACPI_TABLES); 347291333Sjkim } 348291333Sjkim 349291333Sjkim return (AE_OK); 350291333Sjkim} 351291333Sjkim 352291333Sjkim 353291333Sjkim/****************************************************************************** 354291333Sjkim * 355291333Sjkim * FUNCTION: AdParseTable 356291333Sjkim * 357291333Sjkim * PARAMETERS: Table - Pointer to the raw table 358291333Sjkim * OwnerId - Returned OwnerId of the table 359291333Sjkim * LoadTable - If add table to the global table list 360291333Sjkim * External - If this is an external table 361291333Sjkim * 362291333Sjkim * RETURN: Status 363291333Sjkim * 364291333Sjkim * DESCRIPTION: Parse an ACPI AML table 365291333Sjkim * 366291333Sjkim *****************************************************************************/ 367291333Sjkim 368291333SjkimACPI_STATUS 369291333SjkimAdParseTable ( 370291333Sjkim ACPI_TABLE_HEADER *Table, 371291333Sjkim ACPI_OWNER_ID *OwnerId, 372291333Sjkim BOOLEAN LoadTable, 373291333Sjkim BOOLEAN External) 374291333Sjkim{ 375291333Sjkim ACPI_STATUS Status = AE_OK; 376291333Sjkim ACPI_WALK_STATE *WalkState; 377291333Sjkim UINT8 *AmlStart; 378291333Sjkim UINT32 AmlLength; 379291333Sjkim UINT32 TableIndex; 380291333Sjkim 381291333Sjkim 382291333Sjkim if (!Table) 383291333Sjkim { 384291333Sjkim return (AE_NOT_EXIST); 385291333Sjkim } 386291333Sjkim 387291333Sjkim /* Pass 1: Parse everything except control method bodies */ 388291333Sjkim 389291333Sjkim fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); 390291333Sjkim 391291333Sjkim AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); 392291333Sjkim AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); 393291333Sjkim 394291333Sjkim /* Create the root object */ 395291333Sjkim 396291333Sjkim AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (AmlStart); 397291333Sjkim if (!AcpiGbl_ParseOpRoot) 398291333Sjkim { 399291333Sjkim return (AE_NO_MEMORY); 400291333Sjkim } 401291333Sjkim 402291333Sjkim /* Create and initialize a new walk state */ 403291333Sjkim 404291333Sjkim WalkState = AcpiDsCreateWalkState (0, AcpiGbl_ParseOpRoot, NULL, NULL); 405291333Sjkim if (!WalkState) 406291333Sjkim { 407291333Sjkim return (AE_NO_MEMORY); 408291333Sjkim } 409291333Sjkim 410291333Sjkim Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, 411291333Sjkim NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 412291333Sjkim if (ACPI_FAILURE (Status)) 413291333Sjkim { 414291333Sjkim return (Status); 415291333Sjkim } 416291333Sjkim 417291333Sjkim WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 418291333Sjkim WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 419291333Sjkim 420291333Sjkim Status = AcpiPsParseAml (WalkState); 421291333Sjkim if (ACPI_FAILURE (Status)) 422291333Sjkim { 423291333Sjkim return (Status); 424291333Sjkim } 425291333Sjkim 426291333Sjkim /* If LoadTable is FALSE, we are parsing the last loaded table */ 427291333Sjkim 428291333Sjkim TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; 429291333Sjkim 430291333Sjkim /* Pass 2 */ 431291333Sjkim 432291333Sjkim if (LoadTable) 433291333Sjkim { 434291333Sjkim Status = AdStoreTable (Table, &TableIndex); 435291333Sjkim if (ACPI_FAILURE (Status)) 436291333Sjkim { 437291333Sjkim return (Status); 438291333Sjkim } 439291333Sjkim Status = AcpiTbAllocateOwnerId (TableIndex); 440291333Sjkim if (ACPI_FAILURE (Status)) 441291333Sjkim { 442291333Sjkim return (Status); 443291333Sjkim } 444291333Sjkim if (OwnerId) 445291333Sjkim { 446291333Sjkim Status = AcpiTbGetOwnerId (TableIndex, OwnerId); 447291333Sjkim if (ACPI_FAILURE (Status)) 448291333Sjkim { 449291333Sjkim return (Status); 450291333Sjkim } 451291333Sjkim } 452291333Sjkim } 453291333Sjkim 454291333Sjkim fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); 455291333Sjkim 456291333Sjkim Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); 457291333Sjkim if (ACPI_FAILURE (Status)) 458291333Sjkim { 459291333Sjkim return (Status); 460291333Sjkim } 461291333Sjkim 462291333Sjkim /* No need to parse control methods of external table */ 463291333Sjkim 464291333Sjkim if (External) 465291333Sjkim { 466291333Sjkim return (AE_OK); 467291333Sjkim } 468291333Sjkim 469291333Sjkim /* 470291333Sjkim * Pass 3: Parse control methods and link their parse trees 471291333Sjkim * into the main parse tree 472291333Sjkim */ 473291333Sjkim fprintf (stderr, 474291333Sjkim "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); 475291333Sjkim 476291333Sjkim Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot); 477291333Sjkim fprintf (stderr, "\n"); 478291333Sjkim 479291333Sjkim /* Process Resource Templates */ 480291333Sjkim 481291333Sjkim AcpiDmFindResources (AcpiGbl_ParseOpRoot); 482291333Sjkim 483291333Sjkim fprintf (stderr, "Parsing completed\n"); 484291333Sjkim return (AE_OK); 485291333Sjkim} 486