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