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