1 /****************************************************************************** 2 * 3 * Module Name: adisasm - Application-level disassembler routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 <contrib/dev/acpica/include/acpi.h> 46 #include <contrib/dev/acpica/include/accommon.h> 47 #include <contrib/dev/acpica/include/acparser.h> 48 #include <contrib/dev/acpica/include/amlcode.h> 49 #include <contrib/dev/acpica/include/acdebug.h> 50 #include <contrib/dev/acpica/include/acdisasm.h> 51 #include <contrib/dev/acpica/include/acdispat.h> 52 #include <contrib/dev/acpica/include/acnamesp.h> 53 #include <contrib/dev/acpica/include/actables.h> 54 #include <contrib/dev/acpica/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 * GetAllTables - TRUE if all tables are desired 254 * 255 * RETURN: Status 256 * 257 * DESCRIPTION: Disassemble an entire ACPI table 258 * 259 *****************************************************************************/ 260 261 ACPI_STATUS 262 AdAmlDisassemble ( 263 BOOLEAN OutToFile, 264 char *Filename, 265 char *Prefix, 266 char **OutFilename, 267 BOOLEAN GetAllTables) 268 { 269 ACPI_STATUS Status; 270 char *DisasmFilename = NULL; 271 char *ExternalFilename; 272 ACPI_EXTERNAL_FILE *ExternalFileList = AcpiGbl_ExternalFileList; 273 FILE *File = NULL; 274 ACPI_TABLE_HEADER *Table = NULL; 275 ACPI_TABLE_HEADER *ExternalTable; 276 ACPI_OWNER_ID OwnerId; 277 278 279 /* 280 * Input: AML code from either a file or via GetTables (memory or 281 * registry) 282 */ 283 if (Filename) 284 { 285 Status = AcpiDbGetTableFromFile (Filename, &Table); 286 if (ACPI_FAILURE (Status)) 287 { 288 return (Status); 289 } 290 291 /* 292 * External filenames separated by commas 293 * Example: iasl -e file1,file2,file3 -d xxx.aml 294 */ 295 while (ExternalFileList) 296 { 297 ExternalFilename = ExternalFileList->Path; 298 if (!ACPI_STRCMP (ExternalFilename, Filename)) 299 { 300 /* Next external file */ 301 302 ExternalFileList = ExternalFileList->Next; 303 continue; 304 } 305 306 Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable); 307 if (ACPI_FAILURE (Status)) 308 { 309 return (Status); 310 } 311 312 /* Load external table for symbol resolution */ 313 314 if (ExternalTable) 315 { 316 Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE); 317 if (ACPI_FAILURE (Status)) 318 { 319 AcpiOsPrintf ("Could not parse external ACPI tables, %s\n", 320 AcpiFormatException (Status)); 321 return (Status); 322 } 323 324 /* 325 * Load namespace from names created within control methods 326 * Set owner id of nodes in external table 327 */ 328 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 329 AcpiGbl_RootNode, OwnerId); 330 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 331 } 332 333 /* Next external file */ 334 335 ExternalFileList = ExternalFileList->Next; 336 } 337 338 /* Clear external list generated by Scope in external tables */ 339 340 if (AcpiGbl_ExternalFileList) 341 { 342 AcpiDmClearExternalList (); 343 } 344 } 345 else 346 { 347 Status = AdGetLocalTables (Filename, GetAllTables); 348 if (ACPI_FAILURE (Status)) 349 { 350 AcpiOsPrintf ("Could not get ACPI tables, %s\n", 351 AcpiFormatException (Status)); 352 return (Status); 353 } 354 355 if (!AcpiGbl_DbOpt_disasm) 356 { 357 return (AE_OK); 358 } 359 360 /* Obtained the local tables, just disassemble the DSDT */ 361 362 Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table); 363 if (ACPI_FAILURE (Status)) 364 { 365 AcpiOsPrintf ("Could not get DSDT, %s\n", 366 AcpiFormatException (Status)); 367 return (Status); 368 } 369 370 AcpiOsPrintf ("\nDisassembly of DSDT\n"); 371 Prefix = AdGenerateFilename ("dsdt", Table->OemTableId); 372 } 373 374 /* 375 * Output: ASL code. Redirect to a file if requested 376 */ 377 if (OutToFile) 378 { 379 /* Create/Open a disassembly output file */ 380 381 DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY); 382 if (!OutFilename) 383 { 384 fprintf (stderr, "Could not generate output filename\n"); 385 Status = AE_ERROR; 386 goto Cleanup; 387 } 388 389 File = fopen (DisasmFilename, "w+"); 390 if (!File) 391 { 392 fprintf (stderr, "Could not open output file %s\n", DisasmFilename); 393 Status = AE_ERROR; 394 goto Cleanup; 395 } 396 397 AcpiOsRedirectOutput (File); 398 } 399 400 *OutFilename = DisasmFilename; 401 402 if (!AcpiUtIsAmlTable (Table)) 403 { 404 AdDisassemblerHeader (Filename); 405 AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n", 406 Table->Signature); 407 AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength] " 408 "FieldName : FieldValue\n */\n\n"); 409 410 AcpiDmDumpDataTable (Table); 411 fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n", 412 Table->Signature); 413 fprintf (stderr, "Formatted output: %s - %u bytes\n", 414 DisasmFilename, AdGetFileSize (File)); 415 } 416 else 417 { 418 /* Always parse the tables, only option is what to display */ 419 420 Status = AdParseTable (Table, &OwnerId, TRUE, FALSE); 421 if (ACPI_FAILURE (Status)) 422 { 423 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 424 AcpiFormatException (Status)); 425 goto Cleanup; 426 } 427 428 if (AslCompilerdebug) 429 { 430 AcpiOsPrintf ("/**** Before second load\n"); 431 432 NsSetupNamespaceListing (File); 433 NsDisplayNamespace (); 434 AcpiOsPrintf ("*****/\n"); 435 } 436 437 /* Load namespace from names created within control methods */ 438 439 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 440 AcpiGbl_RootNode, OwnerId); 441 442 /* 443 * Cross reference the namespace here, in order to 444 * generate External() statements 445 */ 446 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, 447 AcpiGbl_RootNode, OwnerId); 448 449 if (AslCompilerdebug) 450 { 451 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 452 } 453 454 /* Find possible calls to external control methods */ 455 456 AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot); 457 458 /* 459 * If we found any external control methods, we must reparse 460 * the entire tree with the new information (namely, the 461 * number of arguments per method) 462 */ 463 if (AcpiDmGetExternalMethodCount ()) 464 { 465 fprintf (stderr, 466 "\nFound %u external control methods, " 467 "reparsing with new information\n", 468 AcpiDmGetExternalMethodCount ()); 469 470 /* Reparse, rebuild namespace. no need to xref namespace */ 471 472 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 473 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 474 475 AcpiGbl_RootNode = NULL; 476 AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME; 477 AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED; 478 AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE; 479 AcpiGbl_RootNodeStruct.Parent = NULL; 480 AcpiGbl_RootNodeStruct.Child = NULL; 481 AcpiGbl_RootNodeStruct.Peer = NULL; 482 AcpiGbl_RootNodeStruct.Object = NULL; 483 AcpiGbl_RootNodeStruct.Flags = 0; 484 485 Status = AcpiNsRootInitialize (); 486 AcpiDmAddExternalsToNamespace (); 487 488 /* Parse the table again. No need to reload it, however */ 489 490 Status = AdParseTable (Table, NULL, FALSE, FALSE); 491 if (ACPI_FAILURE (Status)) 492 { 493 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 494 AcpiFormatException (Status)); 495 goto Cleanup; 496 } 497 498 if (AslCompilerdebug) 499 { 500 AcpiOsPrintf ("/**** After second load and resource conversion\n"); 501 NsSetupNamespaceListing (File); 502 NsDisplayNamespace (); 503 AcpiOsPrintf ("*****/\n"); 504 505 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 506 } 507 } 508 509 /* 510 * Now that the namespace is finalized, we can perform namespace 511 * transforms. 512 * 513 * 1) Convert fixed-offset references to resource descriptors 514 * to symbolic references (Note: modifies namespace) 515 */ 516 AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode); 517 518 /* Optional displays */ 519 520 if (AcpiGbl_DbOpt_disasm) 521 { 522 /* This is the real disassembly */ 523 524 AdDisplayTables (Filename, Table); 525 526 /* Dump hex table if requested (-vt) */ 527 528 AcpiDmDumpDataTable (Table); 529 530 fprintf (stderr, "Disassembly completed\n"); 531 fprintf (stderr, "ASL Output: %s - %u bytes\n", 532 DisasmFilename, AdGetFileSize (File)); 533 } 534 } 535 536 Cleanup: 537 538 if (Table && !AcpiUtIsAmlTable (Table)) 539 { 540 ACPI_FREE (Table); 541 } 542 543 if (OutToFile && 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 * 567 * RETURN: None 568 * 569 * DESCRIPTION: Create the disassembler header, including ACPI CA signon with 570 * current time and date. 571 * 572 *****************************************************************************/ 573 574 void 575 AdDisassemblerHeader ( 576 char *Filename) 577 { 578 time_t Timer; 579 580 time (&Timer); 581 582 /* Header and input table info */ 583 584 AcpiOsPrintf ("/*\n"); 585 AcpiOsPrintf (ACPI_COMMON_HEADER ("AML Disassembler", " * ")); 586 587 AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer)); 588 AcpiOsPrintf (" *\n"); 589 } 590 591 592 /****************************************************************************** 593 * 594 * FUNCTION: AdCreateTableHeader 595 * 596 * PARAMETERS: Filename - Input file for the table 597 * Table - Pointer to the raw table 598 * 599 * RETURN: None 600 * 601 * DESCRIPTION: Create the ASL table header, including ACPI CA signon with 602 * current time and date. 603 * 604 *****************************************************************************/ 605 606 static void 607 AdCreateTableHeader ( 608 char *Filename, 609 ACPI_TABLE_HEADER *Table) 610 { 611 char *NewFilename; 612 UINT8 Checksum; 613 614 615 /* 616 * Print file header and dump original table header 617 */ 618 AdDisassemblerHeader (Filename); 619 620 AcpiOsPrintf (" * Original Table Header:\n"); 621 AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature); 622 AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length); 623 624 /* Print and validate the revision */ 625 626 AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision); 627 628 switch (Table->Revision) 629 { 630 case 0: 631 632 AcpiOsPrintf (" **** Invalid Revision"); 633 break; 634 635 case 1: 636 637 /* Revision of DSDT controls the ACPI integer width */ 638 639 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) 640 { 641 AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support"); 642 } 643 break; 644 645 default: 646 647 break; 648 } 649 AcpiOsPrintf ("\n"); 650 651 /* Print and validate the table checksum */ 652 653 AcpiOsPrintf (" * Checksum 0x%2.2X", Table->Checksum); 654 655 Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length); 656 if (Checksum) 657 { 658 AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X", 659 (UINT8) (Table->Checksum - Checksum)); 660 } 661 AcpiOsPrintf ("\n"); 662 663 AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId); 664 AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId); 665 AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision); 666 AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId); 667 AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision); 668 AcpiOsPrintf (" */\n"); 669 670 /* Create AML output filename based on input filename */ 671 672 if (Filename) 673 { 674 NewFilename = FlGenerateFilename (Filename, "aml"); 675 } 676 else 677 { 678 NewFilename = ACPI_ALLOCATE_ZEROED (9); 679 strncat (NewFilename, Table->Signature, 4); 680 strcat (NewFilename, ".aml"); 681 } 682 683 /* Open the ASL definition block */ 684 685 AcpiOsPrintf ( 686 "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n", 687 NewFilename, Table->Signature, Table->Revision, 688 Table->OemId, Table->OemTableId, Table->OemRevision); 689 690 ACPI_FREE (NewFilename); 691 } 692 693 694 /****************************************************************************** 695 * 696 * FUNCTION: AdDisplayTables 697 * 698 * PARAMETERS: Filename - Input file for the table 699 * Table - Pointer to the raw table 700 * 701 * RETURN: Status 702 * 703 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables 704 * 705 *****************************************************************************/ 706 707 ACPI_STATUS 708 AdDisplayTables ( 709 char *Filename, 710 ACPI_TABLE_HEADER *Table) 711 { 712 713 714 if (!AcpiGbl_ParseOpRoot) 715 { 716 return (AE_NOT_EXIST); 717 } 718 719 if (!AcpiGbl_DbOpt_verbose) 720 { 721 AdCreateTableHeader (Filename, Table); 722 } 723 724 AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX); 725 726 if (AcpiGbl_DbOpt_verbose) 727 { 728 AcpiOsPrintf ("\n\nTable Header:\n"); 729 AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER), 730 DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 731 732 AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length); 733 AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), 734 Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 735 } 736 737 return (AE_OK); 738 } 739 740 741 /****************************************************************************** 742 * 743 * FUNCTION: AdGetLocalTables 744 * 745 * PARAMETERS: Filename - Not used 746 * GetAllTables - TRUE if all tables are desired 747 * 748 * RETURN: Status 749 * 750 * DESCRIPTION: Get the ACPI tables from either memory or a file 751 * 752 *****************************************************************************/ 753 754 ACPI_STATUS 755 AdGetLocalTables ( 756 char *Filename, 757 BOOLEAN GetAllTables) 758 { 759 ACPI_STATUS Status; 760 ACPI_TABLE_HEADER TableHeader; 761 ACPI_TABLE_HEADER *NewTable; 762 UINT32 NumTables; 763 UINT32 PointerSize; 764 UINT32 TableIndex; 765 766 767 if (GetAllTables) 768 { 769 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_RSDT); 770 AcpiOsTableOverride (&TableHeader, &NewTable); 771 if (!NewTable) 772 { 773 fprintf (stderr, "Could not obtain RSDT\n"); 774 return (AE_NO_ACPI_TABLES); 775 } 776 else 777 { 778 AdWriteTable (NewTable, NewTable->Length, 779 ACPI_SIG_RSDT, NewTable->OemTableId); 780 } 781 782 if (ACPI_COMPARE_NAME (NewTable->Signature, ACPI_SIG_RSDT)) 783 { 784 PointerSize = sizeof (UINT32); 785 } 786 else 787 { 788 PointerSize = sizeof (UINT64); 789 } 790 791 /* 792 * Determine the number of tables pointed to by the RSDT/XSDT. 793 * This is defined by the ACPI Specification to be the number of 794 * pointers contained within the RSDT/XSDT. The size of the pointers 795 * is architecture-dependent. 796 */ 797 NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize; 798 AcpiOsPrintf ("There are %u tables defined in the %4.4s\n\n", 799 NumTables, NewTable->Signature); 800 801 /* Get the FADT */ 802 803 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_FADT); 804 AcpiOsTableOverride (&TableHeader, &NewTable); 805 if (NewTable) 806 { 807 AdWriteTable (NewTable, NewTable->Length, 808 ACPI_SIG_FADT, NewTable->OemTableId); 809 } 810 AcpiOsPrintf ("\n"); 811 812 /* Don't bother with FACS, it is usually all zeros */ 813 } 814 815 /* Always get the DSDT */ 816 817 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); 818 AcpiOsTableOverride (&TableHeader, &NewTable); 819 if (NewTable) 820 { 821 AdWriteTable (NewTable, NewTable->Length, 822 ACPI_SIG_DSDT, NewTable->OemTableId); 823 824 /* Store DSDT in the Table Manager */ 825 826 Status = AcpiTbStoreTable (0, NewTable, NewTable->Length, 827 0, &TableIndex); 828 if (ACPI_FAILURE (Status)) 829 { 830 fprintf (stderr, "Could not store DSDT\n"); 831 return (AE_NO_ACPI_TABLES); 832 } 833 } 834 else 835 { 836 fprintf (stderr, "Could not obtain DSDT\n"); 837 return (AE_NO_ACPI_TABLES); 838 } 839 840 #if 0 841 /* TBD: Future implementation */ 842 843 AcpiOsPrintf ("\n"); 844 845 /* Get all SSDTs */ 846 847 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_SSDT); 848 do 849 { 850 NewTable = NULL; 851 Status = AcpiOsTableOverride (&TableHeader, &NewTable); 852 853 } while (NewTable); 854 #endif 855 856 return (AE_OK); 857 } 858 859 860 /****************************************************************************** 861 * 862 * FUNCTION: AdParseTable 863 * 864 * PARAMETERS: Table - Pointer to the raw table 865 * OwnerId - Returned OwnerId of the table 866 * LoadTable - If add table to the global table list 867 * External - If this is an external table 868 * 869 * RETURN: Status 870 * 871 * DESCRIPTION: Parse the DSDT. 872 * 873 *****************************************************************************/ 874 875 ACPI_STATUS 876 AdParseTable ( 877 ACPI_TABLE_HEADER *Table, 878 ACPI_OWNER_ID *OwnerId, 879 BOOLEAN LoadTable, 880 BOOLEAN External) 881 { 882 ACPI_STATUS Status = AE_OK; 883 ACPI_WALK_STATE *WalkState; 884 UINT8 *AmlStart; 885 UINT32 AmlLength; 886 UINT32 TableIndex; 887 888 889 if (!Table) 890 { 891 return (AE_NOT_EXIST); 892 } 893 894 /* Pass 1: Parse everything except control method bodies */ 895 896 fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); 897 898 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); 899 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); 900 901 /* Create the root object */ 902 903 AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (); 904 if (!AcpiGbl_ParseOpRoot) 905 { 906 return (AE_NO_MEMORY); 907 } 908 909 /* Create and initialize a new walk state */ 910 911 WalkState = AcpiDsCreateWalkState (0, 912 AcpiGbl_ParseOpRoot, NULL, NULL); 913 if (!WalkState) 914 { 915 return (AE_NO_MEMORY); 916 } 917 918 Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, 919 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 920 if (ACPI_FAILURE (Status)) 921 { 922 return (Status); 923 } 924 925 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 926 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 927 928 Status = AcpiPsParseAml (WalkState); 929 if (ACPI_FAILURE (Status)) 930 { 931 return (Status); 932 } 933 934 /* If LoadTable is FALSE, we are parsing the last loaded table */ 935 936 TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; 937 938 /* Pass 2 */ 939 940 if (LoadTable) 941 { 942 Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table, 943 Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex); 944 if (ACPI_FAILURE (Status)) 945 { 946 return (Status); 947 } 948 Status = AcpiTbAllocateOwnerId (TableIndex); 949 if (ACPI_FAILURE (Status)) 950 { 951 return (Status); 952 } 953 if (OwnerId) 954 { 955 Status = AcpiTbGetOwnerId (TableIndex, OwnerId); 956 if (ACPI_FAILURE (Status)) 957 { 958 return (Status); 959 } 960 } 961 } 962 963 fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); 964 965 Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); 966 if (ACPI_FAILURE (Status)) 967 { 968 return (Status); 969 } 970 971 /* No need to parse control methods of external table */ 972 973 if (External) 974 { 975 return (AE_OK); 976 } 977 978 /* Pass 3: Parse control methods and link their parse trees into the main parse tree */ 979 980 fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); 981 Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot); 982 fprintf (stderr, "\n"); 983 984 /* Process Resource Templates */ 985 986 AcpiDmFindResources (AcpiGbl_ParseOpRoot); 987 988 fprintf (stderr, "Parsing completed\n"); 989 return (AE_OK); 990 } 991