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