1 /****************************************************************************** 2 * 3 * Module Name: adisasm - Application-level disassembler routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "aslcompiler.h" 45 #include "acparser.h" 46 #include "amlcode.h" 47 #include "acdisasm.h" 48 #include "acdispat.h" 49 #include "acnamesp.h" 50 #include "actables.h" 51 #include "acapps.h" 52 53 #include <stdio.h> 54 #include <time.h> 55 56 57 #define _COMPONENT ACPI_TOOLS 58 ACPI_MODULE_NAME ("adisasm") 59 60 /* Local prototypes */ 61 62 static void 63 AdCreateTableHeader ( 64 char *Filename, 65 ACPI_TABLE_HEADER *Table); 66 67 /* Stubs for ASL compiler */ 68 69 #ifndef ACPI_ASL_COMPILER 70 BOOLEAN 71 AcpiDsIsResultUsed ( 72 ACPI_PARSE_OBJECT *Op, 73 ACPI_WALK_STATE *WalkState) 74 { 75 return TRUE; 76 } 77 78 ACPI_STATUS 79 AcpiDsMethodError ( 80 ACPI_STATUS Status, 81 ACPI_WALK_STATE *WalkState) 82 { 83 return (Status); 84 } 85 #endif 86 87 ACPI_STATUS 88 AcpiNsLoadTable ( 89 UINT32 TableIndex, 90 ACPI_NAMESPACE_NODE *Node) 91 { 92 return (AE_NOT_IMPLEMENTED); 93 } 94 95 ACPI_STATUS 96 AcpiDsRestartControlMethod ( 97 ACPI_WALK_STATE *WalkState, 98 ACPI_OPERAND_OBJECT *ReturnDesc) 99 { 100 return (AE_OK); 101 } 102 103 void 104 AcpiDsTerminateControlMethod ( 105 ACPI_OPERAND_OBJECT *MethodDesc, 106 ACPI_WALK_STATE *WalkState) 107 { 108 return; 109 } 110 111 ACPI_STATUS 112 AcpiDsCallControlMethod ( 113 ACPI_THREAD_STATE *Thread, 114 ACPI_WALK_STATE *WalkState, 115 ACPI_PARSE_OBJECT *Op) 116 { 117 return (AE_OK); 118 } 119 120 ACPI_STATUS 121 AcpiDsMethodDataInitArgs ( 122 ACPI_OPERAND_OBJECT **Params, 123 UINT32 MaxParamCount, 124 ACPI_WALK_STATE *WalkState) 125 { 126 return (AE_OK); 127 } 128 129 130 static ACPI_TABLE_DESC LocalTables[1]; 131 static ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; 132 133 134 /******************************************************************************* 135 * 136 * FUNCTION: AdInitialize 137 * 138 * PARAMETERS: None 139 * 140 * RETURN: Status 141 * 142 * DESCRIPTION: ACPICA and local initialization 143 * 144 ******************************************************************************/ 145 146 ACPI_STATUS 147 AdInitialize ( 148 void) 149 { 150 ACPI_STATUS Status; 151 152 153 /* ACPICA subsystem initialization */ 154 155 Status = AcpiOsInitialize (); 156 if (ACPI_FAILURE (Status)) 157 { 158 return (Status); 159 } 160 161 Status = AcpiUtInitGlobals (); 162 if (ACPI_FAILURE (Status)) 163 { 164 return (Status); 165 } 166 167 Status = AcpiUtMutexInitialize (); 168 if (ACPI_FAILURE (Status)) 169 { 170 return (Status); 171 } 172 173 Status = AcpiNsRootInitialize (); 174 if (ACPI_FAILURE (Status)) 175 { 176 return (Status); 177 } 178 179 /* Setup the Table Manager (cheat - there is no RSDT) */ 180 181 AcpiGbl_RootTableList.MaxTableCount = 1; 182 AcpiGbl_RootTableList.CurrentTableCount = 0; 183 AcpiGbl_RootTableList.Tables = LocalTables; 184 185 return (Status); 186 } 187 188 189 /****************************************************************************** 190 * 191 * FUNCTION: AdAmlDisassemble 192 * 193 * PARAMETERS: Filename - AML input filename 194 * OutToFile - TRUE if output should go to a file 195 * Prefix - Path prefix for output 196 * OutFilename - where the filename is returned 197 * 198 * RETURN: Status 199 * 200 * DESCRIPTION: Disassemble an entire ACPI table 201 * 202 *****************************************************************************/ 203 204 ACPI_STATUS 205 AdAmlDisassemble ( 206 BOOLEAN OutToFile, 207 char *Filename, 208 char *Prefix, 209 char **OutFilename) 210 { 211 ACPI_STATUS Status; 212 char *DisasmFilename = NULL; 213 char *ExternalFilename; 214 ACPI_EXTERNAL_FILE *ExternalFileList = AcpiGbl_ExternalFileList; 215 FILE *File = NULL; 216 ACPI_TABLE_HEADER *Table = NULL; 217 ACPI_TABLE_HEADER *ExternalTable; 218 ACPI_OWNER_ID OwnerId; 219 220 221 /* 222 * Input: AML code from either a file or via GetTables (memory or 223 * registry) 224 */ 225 if (Filename) 226 { 227 Status = AcpiDbGetTableFromFile (Filename, &Table); 228 if (ACPI_FAILURE (Status)) 229 { 230 return (Status); 231 } 232 233 /* 234 * External filenames separated by commas 235 * Example: iasl -e file1,file2,file3 -d xxx.aml 236 */ 237 while (ExternalFileList) 238 { 239 ExternalFilename = ExternalFileList->Path; 240 if (!ACPI_STRCMP (ExternalFilename, Filename)) 241 { 242 /* Next external file */ 243 244 ExternalFileList = ExternalFileList->Next; 245 continue; 246 } 247 248 Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable); 249 if (ACPI_FAILURE (Status)) 250 { 251 return (Status); 252 } 253 254 /* Load external table for symbol resolution */ 255 256 if (ExternalTable) 257 { 258 Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE); 259 if (ACPI_FAILURE (Status)) 260 { 261 AcpiOsPrintf ("Could not parse external ACPI tables, %s\n", 262 AcpiFormatException (Status)); 263 return (Status); 264 } 265 266 /* 267 * Load namespace from names created within control methods 268 * Set owner id of nodes in external table 269 */ 270 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 271 AcpiGbl_RootNode, OwnerId); 272 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 273 } 274 275 /* Next external file */ 276 277 ExternalFileList = ExternalFileList->Next; 278 } 279 280 /* Clear external list generated by Scope in external tables */ 281 282 if (AcpiGbl_ExternalFileList) 283 { 284 AcpiDmClearExternalList (); 285 } 286 287 /* Load any externals defined in the optional external ref file */ 288 289 AcpiDmGetExternalsFromFile (); 290 } 291 else 292 { 293 Status = AdGetLocalTables (); 294 if (ACPI_FAILURE (Status)) 295 { 296 AcpiOsPrintf ("Could not get ACPI tables, %s\n", 297 AcpiFormatException (Status)); 298 return (Status); 299 } 300 301 if (!AcpiGbl_DbOpt_disasm) 302 { 303 return (AE_OK); 304 } 305 306 /* Obtained the local tables, just disassemble the DSDT */ 307 308 Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table); 309 if (ACPI_FAILURE (Status)) 310 { 311 AcpiOsPrintf ("Could not get DSDT, %s\n", 312 AcpiFormatException (Status)); 313 return (Status); 314 } 315 316 AcpiOsPrintf ("\nDisassembly of DSDT\n"); 317 Prefix = AdGenerateFilename ("dsdt", Table->OemTableId); 318 } 319 320 /* 321 * Output: ASL code. Redirect to a file if requested 322 */ 323 if (OutToFile) 324 { 325 /* Create/Open a disassembly output file */ 326 327 DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY); 328 if (!DisasmFilename) 329 { 330 fprintf (stderr, "Could not generate output filename\n"); 331 Status = AE_ERROR; 332 goto Cleanup; 333 } 334 335 File = fopen (DisasmFilename, "w+"); 336 if (!File) 337 { 338 fprintf (stderr, "Could not open output file %s\n", DisasmFilename); 339 Status = AE_ERROR; 340 ACPI_FREE (DisasmFilename); 341 goto Cleanup; 342 } 343 344 AcpiOsRedirectOutput (File); 345 } 346 347 *OutFilename = DisasmFilename; 348 349 if (!AcpiUtIsAmlTable (Table)) 350 { 351 AdDisassemblerHeader (Filename); 352 AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n", 353 Table->Signature); 354 AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength] " 355 "FieldName : FieldValue\n */\n\n"); 356 357 AcpiDmDumpDataTable (Table); 358 fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n", 359 Table->Signature); 360 fprintf (stderr, "Formatted output: %s - %u bytes\n", 361 DisasmFilename, CmGetFileSize (File)); 362 } 363 else 364 { 365 /* Always parse the tables, only option is what to display */ 366 367 Status = AdParseTable (Table, &OwnerId, TRUE, FALSE); 368 if (ACPI_FAILURE (Status)) 369 { 370 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 371 AcpiFormatException (Status)); 372 goto Cleanup; 373 } 374 375 if (AslCompilerdebug) 376 { 377 AcpiOsPrintf ("/**** Before second load\n"); 378 379 NsSetupNamespaceListing (File); 380 NsDisplayNamespace (); 381 AcpiOsPrintf ("*****/\n"); 382 } 383 384 /* Load namespace from names created within control methods */ 385 386 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 387 AcpiGbl_RootNode, OwnerId); 388 389 /* 390 * Cross reference the namespace here, in order to 391 * generate External() statements 392 */ 393 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, 394 AcpiGbl_RootNode, OwnerId); 395 396 if (AslCompilerdebug) 397 { 398 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 399 } 400 401 /* Find possible calls to external control methods */ 402 403 AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot); 404 405 /* 406 * If we found any external control methods, we must reparse 407 * the entire tree with the new information (namely, the 408 * number of arguments per method) 409 */ 410 if (AcpiDmGetExternalMethodCount ()) 411 { 412 fprintf (stderr, 413 "\nFound %u external control methods, " 414 "reparsing with new information\n", 415 AcpiDmGetExternalMethodCount ()); 416 417 /* Reparse, rebuild namespace */ 418 419 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 420 AcpiGbl_ParseOpRoot = NULL; 421 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 422 423 AcpiGbl_RootNode = NULL; 424 AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME; 425 AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED; 426 AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE; 427 AcpiGbl_RootNodeStruct.Parent = NULL; 428 AcpiGbl_RootNodeStruct.Child = NULL; 429 AcpiGbl_RootNodeStruct.Peer = NULL; 430 AcpiGbl_RootNodeStruct.Object = NULL; 431 AcpiGbl_RootNodeStruct.Flags = 0; 432 433 Status = AcpiNsRootInitialize (); 434 435 /* New namespace, add the external definitions first */ 436 437 AcpiDmAddExternalsToNamespace (); 438 439 /* Parse the table again. No need to reload it, however */ 440 441 Status = AdParseTable (Table, NULL, FALSE, FALSE); 442 if (ACPI_FAILURE (Status)) 443 { 444 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 445 AcpiFormatException (Status)); 446 goto Cleanup; 447 } 448 449 /* Cross reference the namespace again */ 450 451 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 452 AcpiGbl_RootNode, OwnerId); 453 454 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, 455 AcpiGbl_RootNode, OwnerId); 456 457 if (AslCompilerdebug) 458 { 459 AcpiOsPrintf ("/**** After second load and resource conversion\n"); 460 NsSetupNamespaceListing (File); 461 NsDisplayNamespace (); 462 AcpiOsPrintf ("*****/\n"); 463 464 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 465 } 466 } 467 468 /* 469 * Now that the namespace is finalized, we can perform namespace 470 * transforms. 471 * 472 * 1) Convert fixed-offset references to resource descriptors 473 * to symbolic references (Note: modifies namespace) 474 */ 475 AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode); 476 477 /* Optional displays */ 478 479 if (AcpiGbl_DbOpt_disasm) 480 { 481 /* This is the real disassembly */ 482 483 AdDisplayTables (Filename, Table); 484 485 /* Dump hex table if requested (-vt) */ 486 487 AcpiDmDumpDataTable (Table); 488 489 fprintf (stderr, "Disassembly completed\n"); 490 fprintf (stderr, "ASL Output: %s - %u bytes\n", 491 DisasmFilename, CmGetFileSize (File)); 492 } 493 } 494 495 Cleanup: 496 497 if (Table && !AcpiUtIsAmlTable (Table)) 498 { 499 ACPI_FREE (Table); 500 } 501 502 if (OutToFile && File) 503 { 504 if (AslCompilerdebug) /* Display final namespace, with transforms */ 505 { 506 NsSetupNamespaceListing (File); 507 NsDisplayNamespace (); 508 } 509 510 fclose (File); 511 AcpiOsRedirectOutput (stdout); 512 } 513 514 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 515 AcpiGbl_ParseOpRoot = NULL; 516 return (Status); 517 } 518 519 520 /****************************************************************************** 521 * 522 * FUNCTION: AdDisassemblerHeader 523 * 524 * PARAMETERS: Filename - Input file for the table 525 * 526 * RETURN: None 527 * 528 * DESCRIPTION: Create the disassembler header, including ACPICA signon with 529 * current time and date. 530 * 531 *****************************************************************************/ 532 533 void 534 AdDisassemblerHeader ( 535 char *Filename) 536 { 537 time_t Timer; 538 539 time (&Timer); 540 541 /* Header and input table info */ 542 543 AcpiOsPrintf ("/*\n"); 544 AcpiOsPrintf (ACPI_COMMON_HEADER ("AML Disassembler", " * ")); 545 546 AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer)); 547 AcpiOsPrintf (" *\n"); 548 } 549 550 551 /****************************************************************************** 552 * 553 * FUNCTION: AdCreateTableHeader 554 * 555 * PARAMETERS: Filename - Input file for the table 556 * Table - Pointer to the raw table 557 * 558 * RETURN: None 559 * 560 * DESCRIPTION: Create the ASL table header, including ACPICA signon with 561 * current time and date. 562 * 563 *****************************************************************************/ 564 565 static void 566 AdCreateTableHeader ( 567 char *Filename, 568 ACPI_TABLE_HEADER *Table) 569 { 570 char *NewFilename; 571 UINT8 Checksum; 572 573 574 /* 575 * Print file header and dump original table header 576 */ 577 AdDisassemblerHeader (Filename); 578 579 AcpiOsPrintf (" * Original Table Header:\n"); 580 AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature); 581 AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length); 582 583 /* Print and validate the revision */ 584 585 AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision); 586 587 switch (Table->Revision) 588 { 589 case 0: 590 591 AcpiOsPrintf (" **** Invalid Revision"); 592 break; 593 594 case 1: 595 596 /* Revision of DSDT controls the ACPI integer width */ 597 598 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) 599 { 600 AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support"); 601 } 602 break; 603 604 default: 605 606 break; 607 } 608 AcpiOsPrintf ("\n"); 609 610 /* Print and validate the table checksum */ 611 612 AcpiOsPrintf (" * Checksum 0x%2.2X", Table->Checksum); 613 614 Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length); 615 if (Checksum) 616 { 617 AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X", 618 (UINT8) (Table->Checksum - Checksum)); 619 } 620 AcpiOsPrintf ("\n"); 621 622 AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId); 623 AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId); 624 AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision); 625 AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId); 626 AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision); 627 AcpiOsPrintf (" */\n"); 628 629 /* Create AML output filename based on input filename */ 630 631 if (Filename) 632 { 633 NewFilename = FlGenerateFilename (Filename, "aml"); 634 } 635 else 636 { 637 NewFilename = UtStringCacheCalloc (9); 638 if (NewFilename) 639 { 640 strncat (NewFilename, Table->Signature, 4); 641 strcat (NewFilename, ".aml"); 642 } 643 } 644 645 if (!NewFilename) 646 { 647 AcpiOsPrintf (" **** Could not generate AML output filename\n"); 648 return; 649 } 650 651 /* Open the ASL definition block */ 652 653 AcpiOsPrintf ( 654 "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n", 655 NewFilename, Table->Signature, Table->Revision, 656 Table->OemId, Table->OemTableId, Table->OemRevision); 657 } 658 659 660 /****************************************************************************** 661 * 662 * FUNCTION: AdDisplayTables 663 * 664 * PARAMETERS: Filename - Input file for the table 665 * Table - Pointer to the raw table 666 * 667 * RETURN: Status 668 * 669 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables 670 * 671 *****************************************************************************/ 672 673 ACPI_STATUS 674 AdDisplayTables ( 675 char *Filename, 676 ACPI_TABLE_HEADER *Table) 677 { 678 679 680 if (!AcpiGbl_ParseOpRoot) 681 { 682 return (AE_NOT_EXIST); 683 } 684 685 if (!AcpiGbl_DbOpt_verbose) 686 { 687 AdCreateTableHeader (Filename, Table); 688 } 689 690 AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX); 691 692 if (AcpiGbl_DbOpt_verbose) 693 { 694 AcpiOsPrintf ("\n\nTable Header:\n"); 695 AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER), 696 DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 697 698 AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length); 699 AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), 700 Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 701 } 702 703 return (AE_OK); 704 } 705 706 707 /****************************************************************************** 708 * 709 * FUNCTION: AdGetLocalTables 710 * 711 * PARAMETERS: None 712 * 713 * RETURN: Status 714 * 715 * DESCRIPTION: Get the ACPI tables from either memory or a file 716 * 717 *****************************************************************************/ 718 719 ACPI_STATUS 720 AdGetLocalTables ( 721 void) 722 { 723 ACPI_STATUS Status; 724 ACPI_TABLE_HEADER TableHeader; 725 ACPI_TABLE_HEADER *NewTable; 726 UINT32 TableIndex; 727 728 729 /* Get the DSDT via table override */ 730 731 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); 732 AcpiOsTableOverride (&TableHeader, &NewTable); 733 if (!NewTable) 734 { 735 fprintf (stderr, "Could not obtain DSDT\n"); 736 return (AE_NO_ACPI_TABLES); 737 } 738 739 AdWriteTable (NewTable, NewTable->Length, 740 ACPI_SIG_DSDT, NewTable->OemTableId); 741 742 /* Store DSDT in the Table Manager */ 743 744 Status = AcpiTbStoreTable (0, NewTable, NewTable->Length, 745 0, &TableIndex); 746 if (ACPI_FAILURE (Status)) 747 { 748 fprintf (stderr, "Could not store DSDT\n"); 749 return (AE_NO_ACPI_TABLES); 750 } 751 752 return (AE_OK); 753 } 754 755 756 /****************************************************************************** 757 * 758 * FUNCTION: AdParseTable 759 * 760 * PARAMETERS: Table - Pointer to the raw table 761 * OwnerId - Returned OwnerId of the table 762 * LoadTable - If add table to the global table list 763 * External - If this is an external table 764 * 765 * RETURN: Status 766 * 767 * DESCRIPTION: Parse the DSDT. 768 * 769 *****************************************************************************/ 770 771 ACPI_STATUS 772 AdParseTable ( 773 ACPI_TABLE_HEADER *Table, 774 ACPI_OWNER_ID *OwnerId, 775 BOOLEAN LoadTable, 776 BOOLEAN External) 777 { 778 ACPI_STATUS Status = AE_OK; 779 ACPI_WALK_STATE *WalkState; 780 UINT8 *AmlStart; 781 UINT32 AmlLength; 782 UINT32 TableIndex; 783 784 785 if (!Table) 786 { 787 return (AE_NOT_EXIST); 788 } 789 790 /* Pass 1: Parse everything except control method bodies */ 791 792 fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); 793 794 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); 795 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); 796 797 /* Create the root object */ 798 799 AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (); 800 if (!AcpiGbl_ParseOpRoot) 801 { 802 return (AE_NO_MEMORY); 803 } 804 805 /* Create and initialize a new walk state */ 806 807 WalkState = AcpiDsCreateWalkState (0, 808 AcpiGbl_ParseOpRoot, NULL, NULL); 809 if (!WalkState) 810 { 811 return (AE_NO_MEMORY); 812 } 813 814 Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, 815 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 816 if (ACPI_FAILURE (Status)) 817 { 818 return (Status); 819 } 820 821 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 822 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 823 824 Status = AcpiPsParseAml (WalkState); 825 if (ACPI_FAILURE (Status)) 826 { 827 return (Status); 828 } 829 830 /* If LoadTable is FALSE, we are parsing the last loaded table */ 831 832 TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; 833 834 /* Pass 2 */ 835 836 if (LoadTable) 837 { 838 Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table, 839 Table->Length, ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, 840 &TableIndex); 841 if (ACPI_FAILURE (Status)) 842 { 843 return (Status); 844 } 845 Status = AcpiTbAllocateOwnerId (TableIndex); 846 if (ACPI_FAILURE (Status)) 847 { 848 return (Status); 849 } 850 if (OwnerId) 851 { 852 Status = AcpiTbGetOwnerId (TableIndex, OwnerId); 853 if (ACPI_FAILURE (Status)) 854 { 855 return (Status); 856 } 857 } 858 } 859 860 fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); 861 862 Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); 863 if (ACPI_FAILURE (Status)) 864 { 865 return (Status); 866 } 867 868 /* No need to parse control methods of external table */ 869 870 if (External) 871 { 872 return (AE_OK); 873 } 874 875 /* 876 * Pass 3: Parse control methods and link their parse trees 877 * into the main parse tree 878 */ 879 fprintf (stderr, 880 "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); 881 Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot); 882 fprintf (stderr, "\n"); 883 884 /* Process Resource Templates */ 885 886 AcpiDmFindResources (AcpiGbl_ParseOpRoot); 887 888 fprintf (stderr, "Parsing completed\n"); 889 return (AE_OK); 890 } 891