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