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