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 goto Cleanup; 361 } 362 363 AcpiOsRedirectOutput (File); 364 } 365 366 *OutFilename = DisasmFilename; 367 368 if (!AcpiUtIsAmlTable (Table)) 369 { 370 AdDisassemblerHeader (Filename); 371 AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n", 372 Table->Signature); 373 AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength] " 374 "FieldName : FieldValue\n */\n\n"); 375 376 AcpiDmDumpDataTable (Table); 377 fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n", 378 Table->Signature); 379 fprintf (stderr, "Formatted output: %s - %u bytes\n", 380 DisasmFilename, CmGetFileSize (File)); 381 } 382 else 383 { 384 /* Always parse the tables, only option is what to display */ 385 386 Status = AdParseTable (Table, &OwnerId, TRUE, FALSE); 387 if (ACPI_FAILURE (Status)) 388 { 389 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 390 AcpiFormatException (Status)); 391 goto Cleanup; 392 } 393 394 if (AslCompilerdebug) 395 { 396 AcpiOsPrintf ("/**** Before second load\n"); 397 398 NsSetupNamespaceListing (File); 399 NsDisplayNamespace (); 400 AcpiOsPrintf ("*****/\n"); 401 } 402 403 /* Load namespace from names created within control methods */ 404 405 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 406 AcpiGbl_RootNode, OwnerId); 407 408 /* 409 * Cross reference the namespace here, in order to 410 * generate External() statements 411 */ 412 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, 413 AcpiGbl_RootNode, OwnerId); 414 415 if (AslCompilerdebug) 416 { 417 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 418 } 419 420 /* Find possible calls to external control methods */ 421 422 AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot); 423 424 /* 425 * If we found any external control methods, we must reparse 426 * the entire tree with the new information (namely, the 427 * number of arguments per method) 428 */ 429 if (AcpiDmGetExternalMethodCount ()) 430 { 431 fprintf (stderr, 432 "\nFound %u external control methods, " 433 "reparsing with new information\n", 434 AcpiDmGetExternalMethodCount ()); 435 436 /* Reparse, rebuild namespace */ 437 438 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 439 AcpiGbl_ParseOpRoot = NULL; 440 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 441 442 AcpiGbl_RootNode = NULL; 443 AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME; 444 AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED; 445 AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE; 446 AcpiGbl_RootNodeStruct.Parent = NULL; 447 AcpiGbl_RootNodeStruct.Child = NULL; 448 AcpiGbl_RootNodeStruct.Peer = NULL; 449 AcpiGbl_RootNodeStruct.Object = NULL; 450 AcpiGbl_RootNodeStruct.Flags = 0; 451 452 Status = AcpiNsRootInitialize (); 453 454 /* New namespace, add the external definitions first */ 455 456 AcpiDmAddExternalsToNamespace (); 457 458 /* Parse the table again. No need to reload it, however */ 459 460 Status = AdParseTable (Table, NULL, FALSE, FALSE); 461 if (ACPI_FAILURE (Status)) 462 { 463 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 464 AcpiFormatException (Status)); 465 goto Cleanup; 466 } 467 468 /* Cross reference the namespace again */ 469 470 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 471 AcpiGbl_RootNode, OwnerId); 472 473 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, 474 AcpiGbl_RootNode, OwnerId); 475 476 if (AslCompilerdebug) 477 { 478 AcpiOsPrintf ("/**** After second load and resource conversion\n"); 479 NsSetupNamespaceListing (File); 480 NsDisplayNamespace (); 481 AcpiOsPrintf ("*****/\n"); 482 483 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 484 } 485 } 486 487 /* 488 * Now that the namespace is finalized, we can perform namespace 489 * transforms. 490 * 491 * 1) Convert fixed-offset references to resource descriptors 492 * to symbolic references (Note: modifies namespace) 493 */ 494 AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode); 495 496 /* Optional displays */ 497 498 if (AcpiGbl_DbOpt_disasm) 499 { 500 /* This is the real disassembly */ 501 502 AdDisplayTables (Filename, Table); 503 504 /* Dump hex table if requested (-vt) */ 505 506 AcpiDmDumpDataTable (Table); 507 508 fprintf (stderr, "Disassembly completed\n"); 509 fprintf (stderr, "ASL Output: %s - %u bytes\n", 510 DisasmFilename, CmGetFileSize (File)); 511 } 512 } 513 514 Cleanup: 515 516 if (Table && !AcpiUtIsAmlTable (Table)) 517 { 518 ACPI_FREE (Table); 519 } 520 521 if (OutToFile && File) 522 { 523 if (AslCompilerdebug) /* Display final namespace, with transforms */ 524 { 525 NsSetupNamespaceListing (File); 526 NsDisplayNamespace (); 527 } 528 529 fclose (File); 530 AcpiOsRedirectOutput (stdout); 531 } 532 533 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 534 AcpiGbl_ParseOpRoot = NULL; 535 return (Status); 536 } 537 538 539 /****************************************************************************** 540 * 541 * FUNCTION: AdDisassemblerHeader 542 * 543 * PARAMETERS: Filename - Input file for the table 544 * 545 * RETURN: None 546 * 547 * DESCRIPTION: Create the disassembler header, including ACPICA signon with 548 * current time and date. 549 * 550 *****************************************************************************/ 551 552 void 553 AdDisassemblerHeader ( 554 char *Filename) 555 { 556 time_t Timer; 557 558 time (&Timer); 559 560 /* Header and input table info */ 561 562 AcpiOsPrintf ("/*\n"); 563 AcpiOsPrintf (ACPI_COMMON_HEADER ("AML Disassembler", " * ")); 564 565 AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer)); 566 AcpiOsPrintf (" *\n"); 567 } 568 569 570 /****************************************************************************** 571 * 572 * FUNCTION: AdCreateTableHeader 573 * 574 * PARAMETERS: Filename - Input file for the table 575 * Table - Pointer to the raw table 576 * 577 * RETURN: None 578 * 579 * DESCRIPTION: Create the ASL table header, including ACPICA signon with 580 * current time and date. 581 * 582 *****************************************************************************/ 583 584 static void 585 AdCreateTableHeader ( 586 char *Filename, 587 ACPI_TABLE_HEADER *Table) 588 { 589 char *NewFilename; 590 UINT8 Checksum; 591 592 593 /* 594 * Print file header and dump original table header 595 */ 596 AdDisassemblerHeader (Filename); 597 598 AcpiOsPrintf (" * Original Table Header:\n"); 599 AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature); 600 AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length); 601 602 /* Print and validate the revision */ 603 604 AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision); 605 606 switch (Table->Revision) 607 { 608 case 0: 609 610 AcpiOsPrintf (" **** Invalid Revision"); 611 break; 612 613 case 1: 614 615 /* Revision of DSDT controls the ACPI integer width */ 616 617 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) 618 { 619 AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support"); 620 } 621 break; 622 623 default: 624 625 break; 626 } 627 AcpiOsPrintf ("\n"); 628 629 /* Print and validate the table checksum */ 630 631 AcpiOsPrintf (" * Checksum 0x%2.2X", Table->Checksum); 632 633 Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length); 634 if (Checksum) 635 { 636 AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X", 637 (UINT8) (Table->Checksum - Checksum)); 638 } 639 AcpiOsPrintf ("\n"); 640 641 AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId); 642 AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId); 643 AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision); 644 AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId); 645 AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision); 646 AcpiOsPrintf (" */\n"); 647 648 /* Create AML output filename based on input filename */ 649 650 if (Filename) 651 { 652 NewFilename = FlGenerateFilename (Filename, "aml"); 653 } 654 else 655 { 656 NewFilename = ACPI_ALLOCATE_ZEROED (9); 657 if (NewFilename) 658 { 659 strncat (NewFilename, Table->Signature, 4); 660 strcat (NewFilename, ".aml"); 661 } 662 } 663 664 if (!NewFilename) 665 { 666 AcpiOsPrintf (" **** Could not generate AML output filename\n"); 667 return; 668 } 669 670 /* Open the ASL definition block */ 671 672 AcpiOsPrintf ( 673 "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n", 674 NewFilename, Table->Signature, Table->Revision, 675 Table->OemId, Table->OemTableId, Table->OemRevision); 676 677 ACPI_FREE (NewFilename); 678 } 679 680 681 /****************************************************************************** 682 * 683 * FUNCTION: AdDisplayTables 684 * 685 * PARAMETERS: Filename - Input file for the table 686 * Table - Pointer to the raw table 687 * 688 * RETURN: Status 689 * 690 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables 691 * 692 *****************************************************************************/ 693 694 ACPI_STATUS 695 AdDisplayTables ( 696 char *Filename, 697 ACPI_TABLE_HEADER *Table) 698 { 699 700 701 if (!AcpiGbl_ParseOpRoot) 702 { 703 return (AE_NOT_EXIST); 704 } 705 706 if (!AcpiGbl_DbOpt_verbose) 707 { 708 AdCreateTableHeader (Filename, Table); 709 } 710 711 AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX); 712 713 if (AcpiGbl_DbOpt_verbose) 714 { 715 AcpiOsPrintf ("\n\nTable Header:\n"); 716 AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER), 717 DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 718 719 AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length); 720 AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), 721 Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 722 } 723 724 return (AE_OK); 725 } 726 727 728 /****************************************************************************** 729 * 730 * FUNCTION: AdGetLocalTables 731 * 732 * PARAMETERS: None 733 * 734 * RETURN: Status 735 * 736 * DESCRIPTION: Get the ACPI tables from either memory or a file 737 * 738 *****************************************************************************/ 739 740 ACPI_STATUS 741 AdGetLocalTables ( 742 void) 743 { 744 ACPI_STATUS Status; 745 ACPI_TABLE_HEADER TableHeader; 746 ACPI_TABLE_HEADER *NewTable; 747 UINT32 TableIndex; 748 749 750 /* Get the DSDT via table override */ 751 752 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); 753 AcpiOsTableOverride (&TableHeader, &NewTable); 754 if (!NewTable) 755 { 756 fprintf (stderr, "Could not obtain DSDT\n"); 757 return (AE_NO_ACPI_TABLES); 758 } 759 760 AdWriteTable (NewTable, NewTable->Length, 761 ACPI_SIG_DSDT, NewTable->OemTableId); 762 763 /* Store DSDT in the Table Manager */ 764 765 Status = AcpiTbStoreTable (0, NewTable, NewTable->Length, 766 0, &TableIndex); 767 if (ACPI_FAILURE (Status)) 768 { 769 fprintf (stderr, "Could not store DSDT\n"); 770 return (AE_NO_ACPI_TABLES); 771 } 772 773 return (AE_OK); 774 } 775 776 777 /****************************************************************************** 778 * 779 * FUNCTION: AdParseTable 780 * 781 * PARAMETERS: Table - Pointer to the raw table 782 * OwnerId - Returned OwnerId of the table 783 * LoadTable - If add table to the global table list 784 * External - If this is an external table 785 * 786 * RETURN: Status 787 * 788 * DESCRIPTION: Parse the DSDT. 789 * 790 *****************************************************************************/ 791 792 ACPI_STATUS 793 AdParseTable ( 794 ACPI_TABLE_HEADER *Table, 795 ACPI_OWNER_ID *OwnerId, 796 BOOLEAN LoadTable, 797 BOOLEAN External) 798 { 799 ACPI_STATUS Status = AE_OK; 800 ACPI_WALK_STATE *WalkState; 801 UINT8 *AmlStart; 802 UINT32 AmlLength; 803 UINT32 TableIndex; 804 805 806 if (!Table) 807 { 808 return (AE_NOT_EXIST); 809 } 810 811 /* Pass 1: Parse everything except control method bodies */ 812 813 fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); 814 815 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); 816 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); 817 818 /* Create the root object */ 819 820 AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (); 821 if (!AcpiGbl_ParseOpRoot) 822 { 823 return (AE_NO_MEMORY); 824 } 825 826 /* Create and initialize a new walk state */ 827 828 WalkState = AcpiDsCreateWalkState (0, 829 AcpiGbl_ParseOpRoot, NULL, NULL); 830 if (!WalkState) 831 { 832 return (AE_NO_MEMORY); 833 } 834 835 Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, 836 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 837 if (ACPI_FAILURE (Status)) 838 { 839 return (Status); 840 } 841 842 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 843 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 844 845 Status = AcpiPsParseAml (WalkState); 846 if (ACPI_FAILURE (Status)) 847 { 848 return (Status); 849 } 850 851 /* If LoadTable is FALSE, we are parsing the last loaded table */ 852 853 TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; 854 855 /* Pass 2 */ 856 857 if (LoadTable) 858 { 859 Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table, 860 Table->Length, ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, 861 &TableIndex); 862 if (ACPI_FAILURE (Status)) 863 { 864 return (Status); 865 } 866 Status = AcpiTbAllocateOwnerId (TableIndex); 867 if (ACPI_FAILURE (Status)) 868 { 869 return (Status); 870 } 871 if (OwnerId) 872 { 873 Status = AcpiTbGetOwnerId (TableIndex, OwnerId); 874 if (ACPI_FAILURE (Status)) 875 { 876 return (Status); 877 } 878 } 879 } 880 881 fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); 882 883 Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); 884 if (ACPI_FAILURE (Status)) 885 { 886 return (Status); 887 } 888 889 /* No need to parse control methods of external table */ 890 891 if (External) 892 { 893 return (AE_OK); 894 } 895 896 /* 897 * Pass 3: Parse control methods and link their parse trees 898 * into the main parse tree 899 */ 900 fprintf (stderr, 901 "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); 902 Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot); 903 fprintf (stderr, "\n"); 904 905 /* Process Resource Templates */ 906 907 AcpiDmFindResources (AcpiGbl_ParseOpRoot); 908 909 fprintf (stderr, "Parsing completed\n"); 910 return (AE_OK); 911 } 912