1 /****************************************************************************** 2 * 3 * Module Name: dmtables - disassembler ACPI table support 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 <contrib/dev/acpica/compiler/aslcompiler.h> 45 #include <contrib/dev/acpica/include/acdispat.h> 46 #include <contrib/dev/acpica/include/acnamesp.h> 47 #include <contrib/dev/acpica/include/actables.h> 48 #include <contrib/dev/acpica/include/acparser.h> 49 #include <contrib/dev/acpica/include/acapps.h> 50 51 52 #define _COMPONENT ACPI_TOOLS 53 ACPI_MODULE_NAME ("dmtables") 54 55 56 /* Local prototypes */ 57 58 static void 59 AdCreateTableHeader ( 60 char *Filename, 61 ACPI_TABLE_HEADER *Table); 62 63 static ACPI_STATUS 64 AdStoreTable ( 65 ACPI_TABLE_HEADER *Table, 66 UINT32 *TableIndex); 67 68 69 extern ACPI_TABLE_DESC LocalTables[1]; 70 extern ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; 71 72 73 /****************************************************************************** 74 * 75 * FUNCTION: AdDisassemblerHeader 76 * 77 * PARAMETERS: Filename - Input file for the table 78 * TableType - Either AML or DataTable 79 * 80 * RETURN: None 81 * 82 * DESCRIPTION: Create the disassembler header, including ACPICA signon with 83 * current time and date. 84 * 85 *****************************************************************************/ 86 87 void 88 AdDisassemblerHeader ( 89 char *Filename, 90 UINT8 TableType) 91 { 92 time_t Timer; 93 94 95 time (&Timer); 96 97 /* Header and input table info */ 98 99 AcpiOsPrintf ("/*\n"); 100 AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * ")); 101 102 if (TableType == ACPI_IS_AML_TABLE) 103 { 104 if (AcpiGbl_CstyleDisassembly) 105 { 106 AcpiOsPrintf ( 107 " * Disassembling to symbolic ASL+ operators\n" 108 " *\n"); 109 } 110 else 111 { 112 AcpiOsPrintf ( 113 " * Disassembling to non-symbolic legacy ASL operators\n" 114 " *\n"); 115 } 116 } 117 118 AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer)); 119 AcpiOsPrintf (" *\n"); 120 } 121 122 123 /****************************************************************************** 124 * 125 * FUNCTION: AdCreateTableHeader 126 * 127 * PARAMETERS: Filename - Input file for the table 128 * Table - Pointer to the raw table 129 * 130 * RETURN: None 131 * 132 * DESCRIPTION: Create the ASL table header, including ACPICA signon with 133 * current time and date. 134 * 135 *****************************************************************************/ 136 137 static void 138 AdCreateTableHeader ( 139 char *Filename, 140 ACPI_TABLE_HEADER *Table) 141 { 142 UINT8 Checksum; 143 144 145 /* Reset globals for External statements */ 146 147 AcpiGbl_NumExternalMethods = 0; 148 AcpiGbl_ResolvedExternalMethods = 0; 149 150 /* 151 * Print file header and dump original table header 152 */ 153 AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE); 154 155 AcpiOsPrintf (" * Original Table Header:\n"); 156 AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature); 157 AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length); 158 159 /* Print and validate the revision */ 160 161 AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision); 162 163 switch (Table->Revision) 164 { 165 case 0: 166 167 AcpiOsPrintf (" **** Invalid Revision"); 168 break; 169 170 case 1: 171 172 /* Revision of DSDT controls the ACPI integer width */ 173 174 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) 175 { 176 AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support"); 177 } 178 break; 179 180 default: 181 182 break; 183 } 184 185 /* Print and validate the table checksum */ 186 187 AcpiOsPrintf ("\n * Checksum 0x%2.2X", Table->Checksum); 188 189 Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length); 190 if (Checksum) 191 { 192 AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X", 193 (UINT8) (Table->Checksum - Checksum)); 194 } 195 196 AcpiOsPrintf ("\n"); 197 AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId); 198 AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId); 199 AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision); 200 AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId); 201 AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision); 202 AcpiOsPrintf (" */\n"); 203 204 /* 205 * Open the ASL definition block. 206 * 207 * Note: the AMLFilename string is left zero-length in order to just let 208 * the compiler create it when the disassembled file is compiled. This 209 * makes it easier to rename the disassembled ASL file if needed. 210 */ 211 AcpiOsPrintf ( 212 "DefinitionBlock (\"\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n", 213 Table->Signature, Table->Revision, 214 Table->OemId, Table->OemTableId, Table->OemRevision); 215 } 216 217 218 /****************************************************************************** 219 * 220 * FUNCTION: AdDisplayTables 221 * 222 * PARAMETERS: Filename - Input file for the table 223 * Table - Pointer to the raw table 224 * 225 * RETURN: Status 226 * 227 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables 228 * 229 *****************************************************************************/ 230 231 ACPI_STATUS 232 AdDisplayTables ( 233 char *Filename, 234 ACPI_TABLE_HEADER *Table) 235 { 236 237 238 if (!AcpiGbl_ParseOpRoot) 239 { 240 return (AE_NOT_EXIST); 241 } 242 243 if (!AcpiGbl_DmOpt_Listing) 244 { 245 AdCreateTableHeader (Filename, Table); 246 } 247 248 AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX); 249 MpEmitMappingInfo (); 250 251 if (AcpiGbl_DmOpt_Listing) 252 { 253 AcpiOsPrintf ("\n\nTable Header:\n"); 254 AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER), 255 DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 256 257 AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length); 258 AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), 259 Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 260 } 261 262 return (AE_OK); 263 } 264 265 266 /******************************************************************************* 267 * 268 * FUNCTION: AdStoreTable 269 * 270 * PARAMETERS: Table - Table header 271 * TableIndex - Where the table index is returned 272 * 273 * RETURN: Status and table index. 274 * 275 * DESCRIPTION: Add an ACPI table to the global table list 276 * 277 ******************************************************************************/ 278 279 static ACPI_STATUS 280 AdStoreTable ( 281 ACPI_TABLE_HEADER *Table, 282 UINT32 *TableIndex) 283 { 284 ACPI_STATUS Status; 285 ACPI_TABLE_DESC *TableDesc; 286 287 288 Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc); 289 if (ACPI_FAILURE (Status)) 290 { 291 return (Status); 292 } 293 294 /* Initialize added table */ 295 296 AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table), 297 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table); 298 Status = AcpiTbValidateTable (TableDesc); 299 return (Status); 300 } 301 302 303 /****************************************************************************** 304 * 305 * FUNCTION: AdGetLocalTables 306 * 307 * PARAMETERS: None 308 * 309 * RETURN: Status 310 * 311 * DESCRIPTION: Get the ACPI tables from either memory or a file 312 * 313 *****************************************************************************/ 314 315 ACPI_STATUS 316 AdGetLocalTables ( 317 void) 318 { 319 ACPI_STATUS Status; 320 ACPI_TABLE_HEADER TableHeader; 321 ACPI_TABLE_HEADER *NewTable; 322 UINT32 TableIndex; 323 324 325 /* Get the DSDT via table override */ 326 327 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); 328 AcpiOsTableOverride (&TableHeader, &NewTable); 329 if (!NewTable) 330 { 331 fprintf (stderr, "Could not obtain DSDT\n"); 332 return (AE_NO_ACPI_TABLES); 333 } 334 335 AdWriteTable (NewTable, NewTable->Length, 336 ACPI_SIG_DSDT, NewTable->OemTableId); 337 338 /* Store DSDT in the Table Manager */ 339 340 Status = AdStoreTable (NewTable, &TableIndex); 341 if (ACPI_FAILURE (Status)) 342 { 343 fprintf (stderr, "Could not store DSDT\n"); 344 return (AE_NO_ACPI_TABLES); 345 } 346 347 return (AE_OK); 348 } 349 350 351 /****************************************************************************** 352 * 353 * FUNCTION: AdParseTable 354 * 355 * PARAMETERS: Table - Pointer to the raw table 356 * OwnerId - Returned OwnerId of the table 357 * LoadTable - If add table to the global table list 358 * External - If this is an external table 359 * 360 * RETURN: Status 361 * 362 * DESCRIPTION: Parse an ACPI AML table 363 * 364 *****************************************************************************/ 365 366 ACPI_STATUS 367 AdParseTable ( 368 ACPI_TABLE_HEADER *Table, 369 ACPI_OWNER_ID *OwnerId, 370 BOOLEAN LoadTable, 371 BOOLEAN External) 372 { 373 ACPI_STATUS Status = AE_OK; 374 ACPI_WALK_STATE *WalkState; 375 UINT8 *AmlStart; 376 UINT32 AmlLength; 377 UINT32 TableIndex; 378 379 380 if (!Table) 381 { 382 return (AE_NOT_EXIST); 383 } 384 385 /* Pass 1: Parse everything except control method bodies */ 386 387 fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); 388 389 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); 390 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); 391 392 /* Create the root object */ 393 394 AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (AmlStart); 395 if (!AcpiGbl_ParseOpRoot) 396 { 397 return (AE_NO_MEMORY); 398 } 399 400 /* Create and initialize a new walk state */ 401 402 WalkState = AcpiDsCreateWalkState (0, AcpiGbl_ParseOpRoot, NULL, NULL); 403 if (!WalkState) 404 { 405 return (AE_NO_MEMORY); 406 } 407 408 Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, 409 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 410 if (ACPI_FAILURE (Status)) 411 { 412 return (Status); 413 } 414 415 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 416 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 417 418 Status = AcpiPsParseAml (WalkState); 419 if (ACPI_FAILURE (Status)) 420 { 421 return (Status); 422 } 423 424 /* If LoadTable is FALSE, we are parsing the last loaded table */ 425 426 TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; 427 428 /* Pass 2 */ 429 430 if (LoadTable) 431 { 432 Status = AdStoreTable (Table, &TableIndex); 433 if (ACPI_FAILURE (Status)) 434 { 435 return (Status); 436 } 437 Status = AcpiTbAllocateOwnerId (TableIndex); 438 if (ACPI_FAILURE (Status)) 439 { 440 return (Status); 441 } 442 if (OwnerId) 443 { 444 Status = AcpiTbGetOwnerId (TableIndex, OwnerId); 445 if (ACPI_FAILURE (Status)) 446 { 447 return (Status); 448 } 449 } 450 } 451 452 fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); 453 454 Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); 455 if (ACPI_FAILURE (Status)) 456 { 457 return (Status); 458 } 459 460 /* No need to parse control methods of external table */ 461 462 if (External) 463 { 464 return (AE_OK); 465 } 466 467 /* 468 * Pass 3: Parse control methods and link their parse trees 469 * into the main parse tree 470 */ 471 fprintf (stderr, 472 "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); 473 474 Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot); 475 fprintf (stderr, "\n"); 476 477 /* Process Resource Templates */ 478 479 AcpiDmFindResources (AcpiGbl_ParseOpRoot); 480 481 fprintf (stderr, "Parsing completed\n"); 482 return (AE_OK); 483 } 484