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