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