1 /****************************************************************************** 2 * 3 * Module Name: adisasm - Application-level disassembler routines 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 117 #include <contrib/dev/acpica/include/acpi.h> 118 #include <contrib/dev/acpica/include/accommon.h> 119 #include <contrib/dev/acpica/include/acparser.h> 120 #include <contrib/dev/acpica/include/amlcode.h> 121 #include <contrib/dev/acpica/include/acdebug.h> 122 #include <contrib/dev/acpica/include/acdisasm.h> 123 #include <contrib/dev/acpica/include/acdispat.h> 124 #include <contrib/dev/acpica/include/acnamesp.h> 125 #include <contrib/dev/acpica/include/actables.h> 126 #include <contrib/dev/acpica/include/acapps.h> 127 128 #include <stdio.h> 129 #include <time.h> 130 131 132 #define _COMPONENT ACPI_TOOLS 133 ACPI_MODULE_NAME ("adisasm") 134 135 136 extern int AslCompilerdebug; 137 extern char *Gbl_ExternalFilename; 138 139 140 ACPI_STATUS 141 LsDisplayNamespace ( 142 void); 143 144 void 145 LsSetupNsList ( 146 void *Handle); 147 148 149 /* Local prototypes */ 150 151 void 152 AdCreateTableHeader ( 153 char *Filename, 154 ACPI_TABLE_HEADER *Table); 155 156 ACPI_STATUS 157 AdDeferredParse ( 158 ACPI_PARSE_OBJECT *Op, 159 UINT8 *Aml, 160 UINT32 AmlLength); 161 162 ACPI_STATUS 163 AdParseDeferredOps ( 164 ACPI_PARSE_OBJECT *Root); 165 166 167 /* Stubs for ASL compiler */ 168 169 #ifndef ACPI_ASL_COMPILER 170 BOOLEAN 171 AcpiDsIsResultUsed ( 172 ACPI_PARSE_OBJECT *Op, 173 ACPI_WALK_STATE *WalkState) 174 { 175 return TRUE; 176 } 177 178 ACPI_STATUS 179 AcpiDsMethodError ( 180 ACPI_STATUS Status, 181 ACPI_WALK_STATE *WalkState) 182 { 183 return (Status); 184 } 185 #endif 186 187 ACPI_STATUS 188 AcpiNsLoadTable ( 189 UINT32 TableIndex, 190 ACPI_NAMESPACE_NODE *Node) 191 { 192 return (AE_NOT_IMPLEMENTED); 193 } 194 195 ACPI_STATUS 196 AcpiDsRestartControlMethod ( 197 ACPI_WALK_STATE *WalkState, 198 ACPI_OPERAND_OBJECT *ReturnDesc) 199 { 200 return (AE_OK); 201 } 202 203 void 204 AcpiDsTerminateControlMethod ( 205 ACPI_OPERAND_OBJECT *MethodDesc, 206 ACPI_WALK_STATE *WalkState) 207 { 208 return; 209 } 210 211 ACPI_STATUS 212 AcpiDsCallControlMethod ( 213 ACPI_THREAD_STATE *Thread, 214 ACPI_WALK_STATE *WalkState, 215 ACPI_PARSE_OBJECT *Op) 216 { 217 return (AE_OK); 218 } 219 220 ACPI_STATUS 221 AcpiDsMethodDataInitArgs ( 222 ACPI_OPERAND_OBJECT **Params, 223 UINT32 MaxParamCount, 224 ACPI_WALK_STATE *WalkState) 225 { 226 return (AE_OK); 227 } 228 229 230 static ACPI_TABLE_DESC LocalTables[1]; 231 static ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; 232 233 234 /******************************************************************************* 235 * 236 * FUNCTION: AdInitialize 237 * 238 * PARAMETERS: None 239 * 240 * RETURN: Status 241 * 242 * DESCRIPTION: ACPICA and local initialization 243 * 244 ******************************************************************************/ 245 246 ACPI_STATUS 247 AdInitialize ( 248 void) 249 { 250 ACPI_STATUS Status; 251 252 253 /* ACPI CA subsystem initialization */ 254 255 Status = AcpiOsInitialize (); 256 if (ACPI_FAILURE (Status)) 257 { 258 return (Status); 259 } 260 261 Status = AcpiUtInitGlobals (); 262 if (ACPI_FAILURE (Status)) 263 { 264 return (Status); 265 } 266 267 Status = AcpiUtMutexInitialize (); 268 if (ACPI_FAILURE (Status)) 269 { 270 return (Status); 271 } 272 273 Status = AcpiNsRootInitialize (); 274 if (ACPI_FAILURE (Status)) 275 { 276 return (Status); 277 } 278 279 /* Setup the Table Manager (cheat - there is no RSDT) */ 280 281 AcpiGbl_RootTableList.MaxTableCount = 1; 282 AcpiGbl_RootTableList.CurrentTableCount = 0; 283 AcpiGbl_RootTableList.Tables = LocalTables; 284 285 return (Status); 286 } 287 288 289 /****************************************************************************** 290 * 291 * FUNCTION: AdAmlDisassemble 292 * 293 * PARAMETERS: Filename - AML input filename 294 * OutToFile - TRUE if output should go to a file 295 * Prefix - Path prefix for output 296 * OutFilename - where the filename is returned 297 * GetAllTables - TRUE if all tables are desired 298 * 299 * RETURN: Status 300 * 301 * DESCRIPTION: Disassemble an entire ACPI table 302 * 303 *****************************************************************************/ 304 305 ACPI_STATUS 306 AdAmlDisassemble ( 307 BOOLEAN OutToFile, 308 char *Filename, 309 char *Prefix, 310 char **OutFilename, 311 BOOLEAN GetAllTables) 312 { 313 ACPI_STATUS Status; 314 char *DisasmFilename = NULL; 315 char *ExternalFilename; 316 FILE *File = NULL; 317 ACPI_TABLE_HEADER *Table = NULL; 318 ACPI_TABLE_HEADER *ExternalTable; 319 ACPI_OWNER_ID OwnerId; 320 321 322 /* 323 * Input: AML code from either a file or via GetTables (memory or 324 * registry) 325 */ 326 if (Filename) 327 { 328 Status = AcpiDbGetTableFromFile (Filename, &Table); 329 if (ACPI_FAILURE (Status)) 330 { 331 return Status; 332 } 333 334 /* 335 * External filenames separated by commas 336 * Example: iasl -e file1,file2,file3 -d xxx.aml 337 */ 338 if (Gbl_ExternalFilename) 339 { 340 ExternalFilename = strtok (Gbl_ExternalFilename, ","); 341 342 while (ExternalFilename) 343 { 344 Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable); 345 if (ACPI_FAILURE (Status)) 346 { 347 return Status; 348 } 349 350 /* Load external table for symbol resolution */ 351 352 if (ExternalTable) 353 { 354 Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE); 355 if (ACPI_FAILURE (Status)) 356 { 357 AcpiOsPrintf ("Could not parse external ACPI tables, %s\n", 358 AcpiFormatException (Status)); 359 return Status; 360 } 361 362 /* 363 * Load namespace from names created within control methods 364 * Set owner id of nodes in external table 365 */ 366 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 367 AcpiGbl_RootNode, OwnerId); 368 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 369 } 370 371 /* Next external file name */ 372 373 ExternalFilename = strtok (NULL, ","); 374 } 375 376 /* Clear external list generated by Scope in external tables */ 377 378 AcpiDmClearExternalList (); 379 } 380 } 381 else 382 { 383 Status = AdGetLocalTables (Filename, GetAllTables); 384 if (ACPI_FAILURE (Status)) 385 { 386 AcpiOsPrintf ("Could not get ACPI tables, %s\n", 387 AcpiFormatException (Status)); 388 return Status; 389 } 390 391 if (!AcpiGbl_DbOpt_disasm) 392 { 393 return AE_OK; 394 } 395 396 /* Obtained the local tables, just disassemble the DSDT */ 397 398 Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table); 399 if (ACPI_FAILURE (Status)) 400 { 401 AcpiOsPrintf ("Could not get DSDT, %s\n", 402 AcpiFormatException (Status)); 403 return Status; 404 } 405 406 AcpiOsPrintf ("\nDisassembly of DSDT\n"); 407 Prefix = AdGenerateFilename ("dsdt", Table->OemTableId); 408 } 409 410 /* 411 * Output: ASL code. Redirect to a file if requested 412 */ 413 if (OutToFile) 414 { 415 /* Create/Open a disassembly output file */ 416 417 DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY); 418 if (!OutFilename) 419 { 420 fprintf (stderr, "Could not generate output filename\n"); 421 Status = AE_ERROR; 422 goto Cleanup; 423 } 424 425 File = fopen (DisasmFilename, "w+"); 426 if (!File) 427 { 428 fprintf (stderr, "Could not open output file %s\n", DisasmFilename); 429 Status = AE_ERROR; 430 goto Cleanup; 431 } 432 433 AcpiOsRedirectOutput (File); 434 } 435 436 *OutFilename = DisasmFilename; 437 438 if (!AcpiUtIsAmlTable (Table)) 439 { 440 AdDisassemblerHeader (Filename); 441 AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n", 442 Table->Signature); 443 AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue\n */\n\n"); 444 445 AcpiDmDumpDataTable (Table); 446 fprintf (stderr, "Acpi Data Table [%4.4s] decoded, written to \"%s\"\n", 447 Table->Signature, DisasmFilename); 448 } 449 else 450 { 451 /* Always parse the tables, only option is what to display */ 452 453 Status = AdParseTable (Table, &OwnerId, TRUE, FALSE); 454 if (ACPI_FAILURE (Status)) 455 { 456 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 457 AcpiFormatException (Status)); 458 goto Cleanup; 459 } 460 461 if (AslCompilerdebug) 462 { 463 AcpiOsPrintf ("/**** Before second load\n"); 464 465 LsSetupNsList (File); 466 LsDisplayNamespace (); 467 AcpiOsPrintf ("*****/\n"); 468 } 469 470 /* 471 * Load namespace from names created within control methods 472 */ 473 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode, OwnerId); 474 475 /* 476 * Cross reference the namespace here, in order to generate External() statements 477 */ 478 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode, OwnerId); 479 480 if (AslCompilerdebug) 481 { 482 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 483 } 484 485 /* Find possible calls to external control methods */ 486 487 AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot); 488 489 /* Convert fixed-offset references to resource descriptors to symbolic references */ 490 491 AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode); 492 493 /* 494 * If we found any external control methods, we must reparse the entire 495 * tree with the new information (namely, the number of arguments per 496 * method) 497 */ 498 if (AcpiDmGetExternalMethodCount ()) 499 { 500 fprintf (stderr, 501 "\nFound %u external control methods, reparsing with new information\n", 502 AcpiDmGetExternalMethodCount ()); 503 504 /* 505 * Reparse, rebuild namespace. no need to xref namespace 506 */ 507 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 508 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 509 510 AcpiGbl_RootNode = NULL; 511 AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME; 512 AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED; 513 AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE; 514 AcpiGbl_RootNodeStruct.Parent = NULL; 515 AcpiGbl_RootNodeStruct.Child = NULL; 516 AcpiGbl_RootNodeStruct.Peer = NULL; 517 AcpiGbl_RootNodeStruct.Object = NULL; 518 AcpiGbl_RootNodeStruct.Flags = 0; 519 520 Status = AcpiNsRootInitialize (); 521 AcpiDmAddExternalsToNamespace (); 522 523 /* Parse table. No need to reload it, however (FALSE) */ 524 525 Status = AdParseTable (Table, NULL, FALSE, FALSE); 526 if (ACPI_FAILURE (Status)) 527 { 528 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 529 AcpiFormatException (Status)); 530 goto Cleanup; 531 } 532 533 if (AslCompilerdebug) 534 { 535 AcpiOsPrintf ("/**** After second load and resource conversion\n"); 536 LsSetupNsList (File); 537 LsDisplayNamespace (); 538 AcpiOsPrintf ("*****/\n"); 539 540 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 541 } 542 } 543 544 /* Optional displays */ 545 546 if (AcpiGbl_DbOpt_disasm) 547 { 548 AdDisplayTables (Filename, Table); 549 fprintf (stderr, 550 "Disassembly completed, written to \"%s\"\n", 551 DisasmFilename); 552 } 553 } 554 555 Cleanup: 556 557 if (Table && !AcpiUtIsAmlTable (Table)) 558 { 559 ACPI_FREE (Table); 560 } 561 562 if (DisasmFilename) 563 { 564 ACPI_FREE (DisasmFilename); 565 } 566 567 if (OutToFile && File) 568 { 569 570 #ifdef ASL_DISASM_DEBUG 571 LsSetupNsList (File); 572 LsDisplayNamespace (); 573 #endif 574 fclose (File); 575 AcpiOsRedirectOutput (stdout); 576 } 577 578 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 579 AcpiGbl_ParseOpRoot = NULL; 580 return (Status); 581 } 582 583 584 /****************************************************************************** 585 * 586 * FUNCTION: AdDisassemblerHeader 587 * 588 * PARAMETERS: Filename - Input file for the table 589 * 590 * RETURN: None 591 * 592 * DESCRIPTION: Create the disassembler header, including ACPI CA signon with 593 * current time and date. 594 * 595 *****************************************************************************/ 596 597 void 598 AdDisassemblerHeader ( 599 char *Filename) 600 { 601 time_t Timer; 602 603 time (&Timer); 604 605 /* Header and input table info */ 606 607 AcpiOsPrintf ("/*\n * Intel ACPI Component Architecture\n"); 608 AcpiOsPrintf (" * AML Disassembler version %8.8X\n", ACPI_CA_VERSION); 609 610 AcpiOsPrintf (" *\n * Disassembly of %s, %s", Filename, ctime (&Timer)); 611 AcpiOsPrintf (" *\n"); 612 } 613 614 615 /****************************************************************************** 616 * 617 * FUNCTION: AdCreateTableHeader 618 * 619 * PARAMETERS: Filename - Input file for the table 620 * Table - Pointer to the raw table 621 * 622 * RETURN: None 623 * 624 * DESCRIPTION: Create the ASL table header, including ACPI CA signon with 625 * current time and date. 626 * 627 *****************************************************************************/ 628 629 void 630 AdCreateTableHeader ( 631 char *Filename, 632 ACPI_TABLE_HEADER *Table) 633 { 634 char *NewFilename; 635 UINT8 Checksum; 636 637 638 /* 639 * Print file header and dump original table header 640 */ 641 AdDisassemblerHeader (Filename); 642 643 AcpiOsPrintf (" * Original Table Header:\n"); 644 AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature); 645 AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length); 646 647 /* Print and validate the revision */ 648 649 AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision); 650 651 switch (Table->Revision) 652 { 653 case 0: 654 AcpiOsPrintf (" **** Invalid Revision"); 655 break; 656 657 case 1: 658 /* Revision of DSDT controls the ACPI integer width */ 659 660 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) 661 { 662 AcpiOsPrintf (" **** ACPI 1.0, no 64-bit math support"); 663 } 664 break; 665 666 default: 667 break; 668 } 669 AcpiOsPrintf ("\n"); 670 671 /* Print and validate the table checksum */ 672 673 AcpiOsPrintf (" * Checksum 0x%2.2X", Table->Checksum); 674 675 Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length); 676 if (Checksum) 677 { 678 AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X", 679 (UINT8) (Table->Checksum - Checksum)); 680 } 681 AcpiOsPrintf ("\n"); 682 683 AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId); 684 AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId); 685 AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision); 686 AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId); 687 AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision); 688 AcpiOsPrintf (" */\n\n"); 689 690 /* Create AML output filename based on input filename */ 691 692 if (Filename) 693 { 694 NewFilename = FlGenerateFilename (Filename, "aml"); 695 } 696 else 697 { 698 NewFilename = ACPI_ALLOCATE_ZEROED (9); 699 strncat (NewFilename, Table->Signature, 4); 700 strcat (NewFilename, ".aml"); 701 } 702 703 /* Open the ASL definition block */ 704 705 AcpiOsPrintf ( 706 "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n", 707 NewFilename, Table->Signature, Table->Revision, 708 Table->OemId, Table->OemTableId, Table->OemRevision); 709 710 ACPI_FREE (NewFilename); 711 } 712 713 714 /****************************************************************************** 715 * 716 * FUNCTION: AdDisplayTables 717 * 718 * PARAMETERS: Filename - Input file for the table 719 * Table - Pointer to the raw table 720 * 721 * RETURN: Status 722 * 723 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables 724 * 725 *****************************************************************************/ 726 727 ACPI_STATUS 728 AdDisplayTables ( 729 char *Filename, 730 ACPI_TABLE_HEADER *Table) 731 { 732 733 734 if (!AcpiGbl_ParseOpRoot) 735 { 736 return AE_NOT_EXIST; 737 } 738 739 if (!AcpiGbl_DbOpt_verbose) 740 { 741 AdCreateTableHeader (Filename, Table); 742 } 743 744 AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX); 745 746 if (AcpiGbl_DbOpt_verbose) 747 { 748 AcpiOsPrintf ("\n\nTable Header:\n"); 749 AcpiUtDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER), 750 DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 751 752 AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length); 753 AcpiUtDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), Table->Length, 754 DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 755 } 756 757 return AE_OK; 758 } 759 760 761 /****************************************************************************** 762 * 763 * FUNCTION: AdDeferredParse 764 * 765 * PARAMETERS: Op - Root Op of the deferred opcode 766 * Aml - Pointer to the raw AML 767 * AmlLength - Length of the AML 768 * 769 * RETURN: Status 770 * 771 * DESCRIPTION: Parse one deferred opcode 772 * (Methods, operation regions, etc.) 773 * 774 *****************************************************************************/ 775 776 ACPI_STATUS 777 AdDeferredParse ( 778 ACPI_PARSE_OBJECT *Op, 779 UINT8 *Aml, 780 UINT32 AmlLength) 781 { 782 ACPI_WALK_STATE *WalkState; 783 ACPI_STATUS Status; 784 ACPI_PARSE_OBJECT *SearchOp; 785 ACPI_PARSE_OBJECT *StartOp; 786 UINT32 BaseAmlOffset; 787 ACPI_PARSE_OBJECT *ExtraOp; 788 789 790 ACPI_FUNCTION_TRACE (AdDeferredParse); 791 792 793 fprintf (stderr, "."); 794 795 if (!Aml || !AmlLength) 796 { 797 return_ACPI_STATUS (AE_OK); 798 } 799 800 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing %s [%4.4s]\n", 801 Op->Common.AmlOpName, (char *) &Op->Named.Name)); 802 803 WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); 804 if (!WalkState) 805 { 806 return_ACPI_STATUS (AE_NO_MEMORY); 807 } 808 809 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml, 810 AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 811 if (ACPI_FAILURE (Status)) 812 { 813 return_ACPI_STATUS (Status); 814 } 815 816 /* Parse the method */ 817 818 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 819 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 820 Status = AcpiPsParseAml (WalkState); 821 822 /* 823 * We need to update all of the Aml offsets, since the parser thought 824 * that the method began at offset zero. In reality, it began somewhere 825 * within the ACPI table, at the BaseAmlOffset. Walk the entire tree that 826 * was just created and update the AmlOffset in each Op 827 */ 828 BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1; 829 StartOp = (Op->Common.Value.Arg)->Common.Next; 830 SearchOp = StartOp; 831 832 /* Walk the parse tree */ 833 834 while (SearchOp) 835 { 836 SearchOp->Common.AmlOffset += BaseAmlOffset; 837 SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 838 } 839 840 /* 841 * Link the newly parsed subtree into the main parse tree 842 */ 843 switch (Op->Common.AmlOpcode) 844 { 845 case AML_BUFFER_OP: 846 case AML_PACKAGE_OP: 847 case AML_VAR_PACKAGE_OP: 848 849 switch (Op->Common.AmlOpcode) 850 { 851 case AML_PACKAGE_OP: 852 ExtraOp = Op->Common.Value.Arg; 853 ExtraOp = ExtraOp->Common.Next; 854 Op->Common.Value.Arg = ExtraOp->Common.Value.Arg; 855 break; 856 857 case AML_VAR_PACKAGE_OP: 858 case AML_BUFFER_OP: 859 default: 860 ExtraOp = Op->Common.Value.Arg; 861 Op->Common.Value.Arg = ExtraOp->Common.Value.Arg; 862 break; 863 } 864 865 /* Must point all parents to the main tree */ 866 867 StartOp = Op; 868 SearchOp = StartOp; 869 while (SearchOp) 870 { 871 if (SearchOp->Common.Parent == ExtraOp) 872 { 873 SearchOp->Common.Parent = Op; 874 } 875 SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 876 } 877 break; 878 879 default: 880 break; 881 } 882 883 return_ACPI_STATUS (AE_OK); 884 } 885 886 887 /****************************************************************************** 888 * 889 * FUNCTION: AdParseDeferredOps 890 * 891 * PARAMETERS: Root - Root of the parse tree 892 * 893 * RETURN: Status 894 * 895 * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.) 896 * 897 *****************************************************************************/ 898 899 ACPI_STATUS 900 AdParseDeferredOps ( 901 ACPI_PARSE_OBJECT *Root) 902 { 903 ACPI_PARSE_OBJECT *Op = Root; 904 ACPI_STATUS Status = AE_OK; 905 const ACPI_OPCODE_INFO *OpInfo; 906 907 908 ACPI_FUNCTION_NAME (AdParseDeferredOps); 909 fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); 910 911 while (Op) 912 { 913 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 914 if (!(OpInfo->Flags & AML_DEFER)) 915 { 916 Op = AcpiPsGetDepthNext (Root, Op); 917 continue; 918 } 919 920 switch (Op->Common.AmlOpcode) 921 { 922 case AML_METHOD_OP: 923 case AML_BUFFER_OP: 924 case AML_PACKAGE_OP: 925 case AML_VAR_PACKAGE_OP: 926 927 Status = AdDeferredParse (Op, Op->Named.Data, Op->Named.Length); 928 if (ACPI_FAILURE (Status)) 929 { 930 return_ACPI_STATUS (Status); 931 } 932 break; 933 934 case AML_REGION_OP: 935 case AML_CREATE_QWORD_FIELD_OP: 936 case AML_CREATE_DWORD_FIELD_OP: 937 case AML_CREATE_WORD_FIELD_OP: 938 case AML_CREATE_BYTE_FIELD_OP: 939 case AML_CREATE_BIT_FIELD_OP: 940 case AML_CREATE_FIELD_OP: 941 case AML_BANK_FIELD_OP: 942 943 /* Nothing to do in these cases */ 944 945 break; 946 947 default: 948 ACPI_ERROR ((AE_INFO, "Unhandled deferred opcode [%s]", 949 Op->Common.AmlOpName)); 950 break; 951 } 952 953 Op = AcpiPsGetDepthNext (Root, Op); 954 } 955 956 fprintf (stderr, "\n"); 957 return Status; 958 } 959 960 961 /****************************************************************************** 962 * 963 * FUNCTION: AdGetLocalTables 964 * 965 * PARAMETERS: Filename - Not used 966 * GetAllTables - TRUE if all tables are desired 967 * 968 * RETURN: Status 969 * 970 * DESCRIPTION: Get the ACPI tables from either memory or a file 971 * 972 *****************************************************************************/ 973 974 ACPI_STATUS 975 AdGetLocalTables ( 976 char *Filename, 977 BOOLEAN GetAllTables) 978 { 979 ACPI_STATUS Status; 980 ACPI_TABLE_HEADER TableHeader; 981 ACPI_TABLE_HEADER *NewTable; 982 UINT32 NumTables; 983 UINT32 PointerSize; 984 UINT32 TableIndex; 985 986 987 if (GetAllTables) 988 { 989 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_RSDT); 990 AcpiOsTableOverride (&TableHeader, &NewTable); 991 if (!NewTable) 992 { 993 fprintf (stderr, "Could not obtain RSDT\n"); 994 return AE_NO_ACPI_TABLES; 995 } 996 else 997 { 998 AdWriteTable (NewTable, NewTable->Length, 999 ACPI_SIG_RSDT, NewTable->OemTableId); 1000 } 1001 1002 if (ACPI_COMPARE_NAME (NewTable->Signature, ACPI_SIG_RSDT)) 1003 { 1004 PointerSize = sizeof (UINT32); 1005 } 1006 else 1007 { 1008 PointerSize = sizeof (UINT64); 1009 } 1010 1011 /* 1012 * Determine the number of tables pointed to by the RSDT/XSDT. 1013 * This is defined by the ACPI Specification to be the number of 1014 * pointers contained within the RSDT/XSDT. The size of the pointers 1015 * is architecture-dependent. 1016 */ 1017 NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize; 1018 AcpiOsPrintf ("There are %u tables defined in the %4.4s\n\n", 1019 NumTables, NewTable->Signature); 1020 1021 /* Get the FADT */ 1022 1023 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_FADT); 1024 AcpiOsTableOverride (&TableHeader, &NewTable); 1025 if (NewTable) 1026 { 1027 AdWriteTable (NewTable, NewTable->Length, 1028 ACPI_SIG_FADT, NewTable->OemTableId); 1029 } 1030 AcpiOsPrintf ("\n"); 1031 1032 /* Don't bother with FACS, it is usually all zeros */ 1033 } 1034 1035 /* Always get the DSDT */ 1036 1037 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); 1038 AcpiOsTableOverride (&TableHeader, &NewTable); 1039 if (NewTable) 1040 { 1041 AdWriteTable (NewTable, NewTable->Length, 1042 ACPI_SIG_DSDT, NewTable->OemTableId); 1043 1044 /* Store DSDT in the Table Manager */ 1045 1046 Status = AcpiTbStoreTable (0, NewTable, NewTable->Length, 1047 0, &TableIndex); 1048 if (ACPI_FAILURE (Status)) 1049 { 1050 fprintf (stderr, "Could not store DSDT\n"); 1051 return AE_NO_ACPI_TABLES; 1052 } 1053 } 1054 else 1055 { 1056 fprintf (stderr, "Could not obtain DSDT\n"); 1057 return AE_NO_ACPI_TABLES; 1058 } 1059 1060 #if 0 1061 /* TBD: Future implementation */ 1062 1063 AcpiOsPrintf ("\n"); 1064 1065 /* Get all SSDTs */ 1066 1067 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_SSDT); 1068 do 1069 { 1070 NewTable = NULL; 1071 Status = AcpiOsTableOverride (&TableHeader, &NewTable); 1072 1073 } while (NewTable); 1074 #endif 1075 1076 return AE_OK; 1077 } 1078 1079 1080 /****************************************************************************** 1081 * 1082 * FUNCTION: AdParseTable 1083 * 1084 * PARAMETERS: Table - Pointer to the raw table 1085 * OwnerId - Returned OwnerId of the table 1086 * LoadTable - If add table to the global table list 1087 * External - If this is an external table 1088 * 1089 * RETURN: Status 1090 * 1091 * DESCRIPTION: Parse the DSDT. 1092 * 1093 *****************************************************************************/ 1094 1095 ACPI_STATUS 1096 AdParseTable ( 1097 ACPI_TABLE_HEADER *Table, 1098 ACPI_OWNER_ID *OwnerId, 1099 BOOLEAN LoadTable, 1100 BOOLEAN External) 1101 { 1102 ACPI_STATUS Status = AE_OK; 1103 ACPI_WALK_STATE *WalkState; 1104 UINT8 *AmlStart; 1105 UINT32 AmlLength; 1106 UINT32 TableIndex; 1107 1108 1109 if (!Table) 1110 { 1111 return AE_NOT_EXIST; 1112 } 1113 1114 /* Pass 1: Parse everything except control method bodies */ 1115 1116 fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); 1117 1118 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); 1119 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); 1120 1121 /* Create the root object */ 1122 1123 AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (); 1124 if (!AcpiGbl_ParseOpRoot) 1125 { 1126 return AE_NO_MEMORY; 1127 } 1128 1129 /* Create and initialize a new walk state */ 1130 1131 WalkState = AcpiDsCreateWalkState (0, 1132 AcpiGbl_ParseOpRoot, NULL, NULL); 1133 if (!WalkState) 1134 { 1135 return (AE_NO_MEMORY); 1136 } 1137 1138 Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, 1139 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 1140 if (ACPI_FAILURE (Status)) 1141 { 1142 return (Status); 1143 } 1144 1145 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 1146 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 1147 1148 Status = AcpiPsParseAml (WalkState); 1149 if (ACPI_FAILURE (Status)) 1150 { 1151 return Status; 1152 } 1153 1154 /* If LoadTable is FALSE, we are parsing the last loaded table */ 1155 1156 TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; 1157 1158 /* Pass 2 */ 1159 1160 if (LoadTable) 1161 { 1162 Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table, 1163 Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex); 1164 if (ACPI_FAILURE (Status)) 1165 { 1166 return Status; 1167 } 1168 Status = AcpiTbAllocateOwnerId (TableIndex); 1169 if (ACPI_FAILURE (Status)) 1170 { 1171 return Status; 1172 } 1173 if (OwnerId) 1174 { 1175 Status = AcpiTbGetOwnerId (TableIndex, OwnerId); 1176 if (ACPI_FAILURE (Status)) 1177 { 1178 return Status; 1179 } 1180 } 1181 } 1182 1183 fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); 1184 1185 Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); 1186 if (ACPI_FAILURE (Status)) 1187 { 1188 return (Status); 1189 } 1190 1191 /* No need to parse control methods of external table */ 1192 1193 if (External) 1194 { 1195 return AE_OK; 1196 } 1197 1198 /* Pass 3: Parse control methods and link their parse trees into the main parse tree */ 1199 1200 Status = AdParseDeferredOps (AcpiGbl_ParseOpRoot); 1201 1202 /* Process Resource Templates */ 1203 1204 AcpiDmFindResources (AcpiGbl_ParseOpRoot); 1205 1206 fprintf (stderr, "Parsing completed\n"); 1207 return AE_OK; 1208 } 1209 1210 1211