1 /****************************************************************************** 2 * 3 * Module Name: dmextern - Support for External() ASL statements 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 #include <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/amlcode.h> 47 #include <contrib/dev/acpica/include/acnamesp.h> 48 #include <contrib/dev/acpica/include/acdisasm.h> 49 #include <stdio.h> 50 51 52 /* 53 * This module is used for application-level code (iASL disassembler) only. 54 * 55 * It contains the code to create and emit any necessary External() ASL 56 * statements for the module being disassembled. 57 */ 58 #define _COMPONENT ACPI_CA_DISASSEMBLER 59 ACPI_MODULE_NAME ("dmextern") 60 61 62 /* 63 * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL 64 * ObjectTypeKeyword. Used to generate typed external declarations 65 */ 66 static const char *AcpiGbl_DmTypeNames[] = 67 { 68 /* 00 */ "", /* Type ANY */ 69 /* 01 */ ", IntObj", 70 /* 02 */ ", StrObj", 71 /* 03 */ ", BuffObj", 72 /* 04 */ ", PkgObj", 73 /* 05 */ ", FieldUnitObj", 74 /* 06 */ ", DeviceObj", 75 /* 07 */ ", EventObj", 76 /* 08 */ ", MethodObj", 77 /* 09 */ ", MutexObj", 78 /* 10 */ ", OpRegionObj", 79 /* 11 */ ", PowerResObj", 80 /* 12 */ ", ProcessorObj", 81 /* 13 */ ", ThermalZoneObj", 82 /* 14 */ ", BuffFieldObj", 83 /* 15 */ ", DDBHandleObj", 84 /* 16 */ "", /* Debug object */ 85 /* 17 */ ", FieldUnitObj", 86 /* 18 */ ", FieldUnitObj", 87 /* 19 */ ", FieldUnitObj" 88 }; 89 90 91 /* Local prototypes */ 92 93 static const char * 94 AcpiDmGetObjectTypeName ( 95 ACPI_OBJECT_TYPE Type); 96 97 static char * 98 AcpiDmNormalizeParentPrefix ( 99 ACPI_PARSE_OBJECT *Op, 100 char *Path); 101 102 103 /******************************************************************************* 104 * 105 * FUNCTION: AcpiDmGetObjectTypeName 106 * 107 * PARAMETERS: Type - An ACPI_OBJECT_TYPE 108 * 109 * RETURN: Pointer to a string 110 * 111 * DESCRIPTION: Map an object type to the ASL object type string. 112 * 113 ******************************************************************************/ 114 115 static const char * 116 AcpiDmGetObjectTypeName ( 117 ACPI_OBJECT_TYPE Type) 118 { 119 120 if (Type == ACPI_TYPE_LOCAL_SCOPE) 121 { 122 Type = ACPI_TYPE_DEVICE; 123 } 124 125 else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD) 126 { 127 return (""); 128 } 129 130 return (AcpiGbl_DmTypeNames[Type]); 131 } 132 133 134 /******************************************************************************* 135 * 136 * FUNCTION: AcpiDmNormalizeParentPrefix 137 * 138 * PARAMETERS: Op - Parse op 139 * Path - Path with parent prefix 140 * 141 * RETURN: The full pathname to the object (from the namespace root) 142 * 143 * DESCRIPTION: Returns the full pathname of a path with parent prefix 144 * The caller must free the fullpath returned. 145 * 146 ******************************************************************************/ 147 148 static char * 149 AcpiDmNormalizeParentPrefix ( 150 ACPI_PARSE_OBJECT *Op, 151 char *Path) 152 { 153 ACPI_NAMESPACE_NODE *Node; 154 char *Fullpath; 155 char *ParentPath; 156 ACPI_SIZE Length; 157 UINT32 Index = 0; 158 159 160 if (!Op) 161 { 162 return (NULL); 163 } 164 165 /* Search upwards in the parse tree until we reach the next namespace node */ 166 167 Op = Op->Common.Parent; 168 while (Op) 169 { 170 if (Op->Common.Node) 171 { 172 break; 173 } 174 175 Op = Op->Common.Parent; 176 } 177 178 if (!Op) 179 { 180 return (NULL); 181 } 182 183 /* 184 * Find the actual parent node for the reference: 185 * Remove all carat prefixes from the input path. 186 * There may be multiple parent prefixes (For example, ^^^M000) 187 */ 188 Node = Op->Common.Node; 189 while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) 190 { 191 Node = Node->Parent; 192 Path++; 193 } 194 195 if (!Node) 196 { 197 return (NULL); 198 } 199 200 /* Get the full pathname for the parent node */ 201 202 ParentPath = AcpiNsGetExternalPathname (Node); 203 if (!ParentPath) 204 { 205 return (NULL); 206 } 207 208 Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1); 209 if (ParentPath[1]) 210 { 211 /* 212 * If ParentPath is not just a simple '\', increment the length 213 * for the required dot separator (ParentPath.Path) 214 */ 215 Length++; 216 217 /* For External() statements, we do not want a leading '\' */ 218 219 if (*ParentPath == AML_ROOT_PREFIX) 220 { 221 Index = 1; 222 } 223 } 224 225 Fullpath = ACPI_ALLOCATE_ZEROED (Length); 226 if (!Fullpath) 227 { 228 goto Cleanup; 229 } 230 231 /* 232 * Concatenate parent fullpath and path. For example, 233 * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" 234 * 235 * Copy the parent path 236 */ 237 ACPI_STRCPY (Fullpath, &ParentPath[Index]); 238 239 /* 240 * Add dot separator 241 * (don't need dot if parent fullpath is a single backslash) 242 */ 243 if (ParentPath[1]) 244 { 245 ACPI_STRCAT (Fullpath, "."); 246 } 247 248 /* Copy child path (carat parent prefix(es) were skipped above) */ 249 250 ACPI_STRCAT (Fullpath, Path); 251 252 Cleanup: 253 ACPI_FREE (ParentPath); 254 return (Fullpath); 255 } 256 257 258 /******************************************************************************* 259 * 260 * FUNCTION: AcpiDmAddToExternalFileList 261 * 262 * PARAMETERS: PathList - Single path or list separated by comma 263 * 264 * RETURN: None 265 * 266 * DESCRIPTION: Add external files to global list 267 * 268 ******************************************************************************/ 269 270 ACPI_STATUS 271 AcpiDmAddToExternalFileList ( 272 char *PathList) 273 { 274 ACPI_EXTERNAL_FILE *ExternalFile; 275 char *Path; 276 char *TmpPath; 277 278 279 if (!PathList) 280 { 281 return (AE_OK); 282 } 283 284 Path = strtok (PathList, ","); 285 286 while (Path) 287 { 288 TmpPath = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (Path) + 1); 289 if (!TmpPath) 290 { 291 return (AE_NO_MEMORY); 292 } 293 294 ACPI_STRCPY (TmpPath, Path); 295 296 ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE)); 297 if (!ExternalFile) 298 { 299 ACPI_FREE (TmpPath); 300 return (AE_NO_MEMORY); 301 } 302 303 ExternalFile->Path = TmpPath; 304 305 if (AcpiGbl_ExternalFileList) 306 { 307 ExternalFile->Next = AcpiGbl_ExternalFileList; 308 } 309 310 AcpiGbl_ExternalFileList = ExternalFile; 311 Path = strtok (NULL, ","); 312 } 313 314 return (AE_OK); 315 } 316 317 318 /******************************************************************************* 319 * 320 * FUNCTION: AcpiDmClearExternalFileList 321 * 322 * PARAMETERS: None 323 * 324 * RETURN: None 325 * 326 * DESCRIPTION: Clear the external file list 327 * 328 ******************************************************************************/ 329 330 void 331 AcpiDmClearExternalFileList ( 332 void) 333 { 334 ACPI_EXTERNAL_FILE *NextExternal; 335 336 337 while (AcpiGbl_ExternalFileList) 338 { 339 NextExternal = AcpiGbl_ExternalFileList->Next; 340 ACPI_FREE (AcpiGbl_ExternalFileList->Path); 341 ACPI_FREE (AcpiGbl_ExternalFileList); 342 AcpiGbl_ExternalFileList = NextExternal; 343 } 344 } 345 346 347 /******************************************************************************* 348 * 349 * FUNCTION: AcpiDmAddToExternalList 350 * 351 * PARAMETERS: Op - Current parser Op 352 * Path - Internal (AML) path to the object 353 * Type - ACPI object type to be added 354 * Value - Arg count if adding a Method object 355 * 356 * RETURN: None 357 * 358 * DESCRIPTION: Insert a new name into the global list of Externals which 359 * will in turn be later emitted as an External() declaration 360 * in the disassembled output. 361 * 362 ******************************************************************************/ 363 364 void 365 AcpiDmAddToExternalList ( 366 ACPI_PARSE_OBJECT *Op, 367 char *Path, 368 UINT8 Type, 369 UINT32 Value) 370 { 371 char *ExternalPath; 372 char *Fullpath = NULL; 373 ACPI_EXTERNAL_LIST *NewExternal; 374 ACPI_EXTERNAL_LIST *NextExternal; 375 ACPI_EXTERNAL_LIST *PrevExternal = NULL; 376 ACPI_STATUS Status; 377 BOOLEAN Resolved = FALSE; 378 379 380 if (!Path) 381 { 382 return; 383 } 384 385 if (Type == ACPI_TYPE_METHOD) 386 { 387 if (Value & 0x80) 388 { 389 Resolved = TRUE; 390 } 391 Value &= 0x07; 392 } 393 394 /* 395 * We don't want External() statements to contain a leading '\'. 396 * This prevents duplicate external statements of the form: 397 * 398 * External (\ABCD) 399 * External (ABCD) 400 * 401 * This would cause a compile time error when the disassembled 402 * output file is recompiled. 403 */ 404 if ((*Path == AML_ROOT_PREFIX) && (Path[1])) 405 { 406 Path++; 407 } 408 409 /* Externalize the ACPI pathname */ 410 411 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path, 412 NULL, &ExternalPath); 413 if (ACPI_FAILURE (Status)) 414 { 415 return; 416 } 417 418 /* 419 * Get the full pathname from the root if "Path" has one or more 420 * parent prefixes (^). Note: path will not contain a leading '\'. 421 */ 422 if (*Path == (UINT8) AML_PARENT_PREFIX) 423 { 424 Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath); 425 if (Fullpath) 426 { 427 /* Set new external path */ 428 429 ACPI_FREE (ExternalPath); 430 ExternalPath = Fullpath; 431 } 432 } 433 434 /* Check all existing externals to ensure no duplicates */ 435 436 NextExternal = AcpiGbl_ExternalList; 437 while (NextExternal) 438 { 439 if (!ACPI_STRCMP (ExternalPath, NextExternal->Path)) 440 { 441 /* Duplicate method, check that the Value (ArgCount) is the same */ 442 443 if ((NextExternal->Type == ACPI_TYPE_METHOD) && 444 (NextExternal->Value != Value)) 445 { 446 ACPI_ERROR ((AE_INFO, 447 "Argument count mismatch for method %s %u %u", 448 NextExternal->Path, NextExternal->Value, Value)); 449 } 450 451 /* Allow upgrade of type from ANY */ 452 453 else if (NextExternal->Type == ACPI_TYPE_ANY) 454 { 455 NextExternal->Type = Type; 456 NextExternal->Value = Value; 457 } 458 459 ACPI_FREE (ExternalPath); 460 return; 461 } 462 463 NextExternal = NextExternal->Next; 464 } 465 466 /* Allocate and init a new External() descriptor */ 467 468 NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST)); 469 if (!NewExternal) 470 { 471 ACPI_FREE (ExternalPath); 472 return; 473 } 474 475 NewExternal->Path = ExternalPath; 476 NewExternal->Type = Type; 477 NewExternal->Value = Value; 478 NewExternal->Resolved = Resolved; 479 NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath); 480 481 /* Was the external path with parent prefix normalized to a fullpath? */ 482 483 if (Fullpath == ExternalPath) 484 { 485 /* Get new internal path */ 486 487 Status = AcpiNsInternalizeName (ExternalPath, &Path); 488 if (ACPI_FAILURE (Status)) 489 { 490 ACPI_FREE (ExternalPath); 491 ACPI_FREE (NewExternal); 492 return; 493 } 494 495 /* Set flag to indicate External->InternalPath need to be freed */ 496 497 NewExternal->Flags |= ACPI_IPATH_ALLOCATED; 498 } 499 500 NewExternal->InternalPath = Path; 501 502 /* Link the new descriptor into the global list, alphabetically ordered */ 503 504 NextExternal = AcpiGbl_ExternalList; 505 while (NextExternal) 506 { 507 if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0) 508 { 509 if (PrevExternal) 510 { 511 PrevExternal->Next = NewExternal; 512 } 513 else 514 { 515 AcpiGbl_ExternalList = NewExternal; 516 } 517 518 NewExternal->Next = NextExternal; 519 return; 520 } 521 522 PrevExternal = NextExternal; 523 NextExternal = NextExternal->Next; 524 } 525 526 if (PrevExternal) 527 { 528 PrevExternal->Next = NewExternal; 529 } 530 else 531 { 532 AcpiGbl_ExternalList = NewExternal; 533 } 534 } 535 536 537 /******************************************************************************* 538 * 539 * FUNCTION: AcpiDmAddExternalsToNamespace 540 * 541 * PARAMETERS: None 542 * 543 * RETURN: None 544 * 545 * DESCRIPTION: Add all externals to the namespace. Allows externals to be 546 * "resolved". 547 * 548 ******************************************************************************/ 549 550 void 551 AcpiDmAddExternalsToNamespace ( 552 void) 553 { 554 ACPI_STATUS Status; 555 ACPI_NAMESPACE_NODE *Node; 556 ACPI_OPERAND_OBJECT *ObjDesc; 557 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 558 559 560 while (External) 561 { 562 /* Add the external name (object) into the namespace */ 563 564 Status = AcpiNsLookup (NULL, External->InternalPath, External->Type, 565 ACPI_IMODE_LOAD_PASS1, 566 ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE, 567 NULL, &Node); 568 569 if (ACPI_FAILURE (Status)) 570 { 571 ACPI_EXCEPTION ((AE_INFO, Status, 572 "while adding external to namespace [%s]", 573 External->Path)); 574 } 575 576 else switch (External->Type) 577 { 578 case ACPI_TYPE_METHOD: 579 580 /* For methods, we need to save the argument count */ 581 582 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 583 ObjDesc->Method.ParamCount = (UINT8) External->Value; 584 Node->Object = ObjDesc; 585 break; 586 587 case ACPI_TYPE_REGION: 588 589 /* Regions require a region sub-object */ 590 591 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 592 ObjDesc->Region.Node = Node; 593 Node->Object = ObjDesc; 594 break; 595 596 default: 597 break; 598 } 599 600 External = External->Next; 601 } 602 } 603 604 605 /******************************************************************************* 606 * 607 * FUNCTION: AcpiDmGetExternalMethodCount 608 * 609 * PARAMETERS: None 610 * 611 * RETURN: The number of control method externals in the external list 612 * 613 * DESCRIPTION: Return the number of method externals that have been generated. 614 * If any control method externals have been found, we must 615 * re-parse the entire definition block with the new information 616 * (number of arguments for the methods.) This is limitation of 617 * AML, we don't know the number of arguments from the control 618 * method invocation itself. 619 * 620 ******************************************************************************/ 621 622 UINT32 623 AcpiDmGetExternalMethodCount ( 624 void) 625 { 626 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 627 UINT32 Count = 0; 628 629 630 while (External) 631 { 632 if (External->Type == ACPI_TYPE_METHOD) 633 { 634 Count++; 635 } 636 637 External = External->Next; 638 } 639 640 return (Count); 641 } 642 643 644 /******************************************************************************* 645 * 646 * FUNCTION: AcpiDmClearExternalList 647 * 648 * PARAMETERS: None 649 * 650 * RETURN: None 651 * 652 * DESCRIPTION: Free the entire External info list 653 * 654 ******************************************************************************/ 655 656 void 657 AcpiDmClearExternalList ( 658 void) 659 { 660 ACPI_EXTERNAL_LIST *NextExternal; 661 662 663 while (AcpiGbl_ExternalList) 664 { 665 NextExternal = AcpiGbl_ExternalList->Next; 666 ACPI_FREE (AcpiGbl_ExternalList->Path); 667 ACPI_FREE (AcpiGbl_ExternalList); 668 AcpiGbl_ExternalList = NextExternal; 669 } 670 } 671 672 673 /******************************************************************************* 674 * 675 * FUNCTION: AcpiDmEmitExternals 676 * 677 * PARAMETERS: None 678 * 679 * RETURN: None 680 * 681 * DESCRIPTION: Emit an External() ASL statement for each of the externals in 682 * the global external info list. 683 * 684 ******************************************************************************/ 685 686 void 687 AcpiDmEmitExternals ( 688 void) 689 { 690 ACPI_EXTERNAL_LIST *NextExternal; 691 692 693 if (!AcpiGbl_ExternalList) 694 { 695 return; 696 } 697 698 /* 699 * Determine the number of control methods in the external list, and 700 * also how many of those externals were resolved via the namespace. 701 */ 702 NextExternal = AcpiGbl_ExternalList; 703 while (NextExternal) 704 { 705 if (NextExternal->Type == ACPI_TYPE_METHOD) 706 { 707 AcpiGbl_NumExternalMethods++; 708 if (NextExternal->Resolved) 709 { 710 AcpiGbl_ResolvedExternalMethods++; 711 } 712 } 713 714 NextExternal = NextExternal->Next; 715 } 716 717 /* Check if any control methods were unresolved */ 718 719 AcpiDmUnresolvedWarning (1); 720 721 /* 722 * Walk the list of externals (unresolved references) 723 * found during the AML parsing 724 */ 725 while (AcpiGbl_ExternalList) 726 { 727 AcpiOsPrintf (" External (%s%s", 728 AcpiGbl_ExternalList->Path, 729 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); 730 731 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 732 { 733 if (AcpiGbl_ExternalList->Resolved) 734 { 735 AcpiOsPrintf (") // %u Arguments\n", 736 AcpiGbl_ExternalList->Value); 737 } 738 else 739 { 740 AcpiOsPrintf (") // Warning: unresolved Method, " 741 "assuming %u arguments (may be incorrect, see warning above)\n", 742 AcpiGbl_ExternalList->Value); 743 } 744 } 745 else 746 { 747 AcpiOsPrintf (")\n"); 748 } 749 750 /* Free this external info block and move on to next external */ 751 752 NextExternal = AcpiGbl_ExternalList->Next; 753 if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED) 754 { 755 ACPI_FREE (AcpiGbl_ExternalList->InternalPath); 756 } 757 758 ACPI_FREE (AcpiGbl_ExternalList->Path); 759 ACPI_FREE (AcpiGbl_ExternalList); 760 AcpiGbl_ExternalList = NextExternal; 761 } 762 763 AcpiOsPrintf ("\n"); 764 } 765 766 767 /******************************************************************************* 768 * 769 * FUNCTION: AcpiDmUnresolvedWarning 770 * 771 * PARAMETERS: Type - Where to output the warning. 772 * 0 means write to stderr 773 * 1 means write to AcpiOsPrintf 774 * 775 * RETURN: None 776 * 777 * DESCRIPTION: Issue warning message if there are unresolved external control 778 * methods within the disassembly. 779 * 780 ******************************************************************************/ 781 782 #if 0 783 Summary of the external control method problem: 784 785 When the -e option is used with disassembly, the various SSDTs are simply 786 loaded into a global namespace for the disassembler to use in order to 787 resolve control method references (invocations). 788 789 The disassembler tracks any such references, and will emit an External() 790 statement for these types of methods, with the proper number of arguments . 791 792 Without the SSDTs, the AML does not contain enough information to properly 793 disassemble the control method invocation -- because the disassembler does 794 not know how many arguments to parse. 795 796 An example: Assume we have two control methods. ABCD has one argument, and 797 EFGH has zero arguments. Further, we have two additional control methods 798 that invoke ABCD and EFGH, named T1 and T2: 799 800 Method (ABCD, 1) 801 { 802 } 803 Method (EFGH, 0) 804 { 805 } 806 Method (T1) 807 { 808 ABCD (Add (2, 7, Local0)) 809 } 810 Method (T2) 811 { 812 EFGH () 813 Add (2, 7, Local0) 814 } 815 816 Here is the AML code that is generated for T1 and T2: 817 818 185: Method (T1) 819 820 0000034C: 14 10 54 31 5F 5F 00 ... "..T1__." 821 822 186: { 823 187: ABCD (Add (2, 7, Local0)) 824 825 00000353: 41 42 43 44 ............ "ABCD" 826 00000357: 72 0A 02 0A 07 60 ...... "r....`" 827 828 188: } 829 830 190: Method (T2) 831 832 0000035D: 14 10 54 32 5F 5F 00 ... "..T2__." 833 834 191: { 835 192: EFGH () 836 837 00000364: 45 46 47 48 ............ "EFGH" 838 839 193: Add (2, 7, Local0) 840 841 00000368: 72 0A 02 0A 07 60 ...... "r....`" 842 194: } 843 844 Note that the AML code for T1 and T2 is essentially identical. When 845 disassembling this code, the methods ABCD and EFGH must be known to the 846 disassembler, otherwise it does not know how to handle the method invocations. 847 848 In other words, if ABCD and EFGH are actually external control methods 849 appearing in an SSDT, the disassembler does not know what to do unless 850 the owning SSDT has been loaded via the -e option. 851 #endif 852 853 void 854 AcpiDmUnresolvedWarning ( 855 UINT8 Type) 856 { 857 858 if (!AcpiGbl_NumExternalMethods) 859 { 860 return; 861 } 862 863 if (Type) 864 { 865 if (!AcpiGbl_ExternalFileList) 866 { 867 /* The -e option was not specified */ 868 869 AcpiOsPrintf (" /*\n" 870 " * iASL Warning: There were %u external control methods found during\n" 871 " * disassembly, but additional ACPI tables to resolve these externals\n" 872 " * were not specified. This resulting disassembler output file may not\n" 873 " * compile because the disassembler did not know how many arguments\n" 874 " * to assign to these methods. To specify the tables needed to resolve\n" 875 " * external control method references, use the one of the following\n" 876 " * example iASL invocations:\n" 877 " * iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n" 878 " * iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n" 879 " */\n", 880 AcpiGbl_NumExternalMethods); 881 } 882 else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods) 883 { 884 /* The -e option was specified, but there are still some unresolved externals */ 885 886 AcpiOsPrintf (" /*\n" 887 " * iASL Warning: There were %u external control methods found during\n" 888 " * disassembly, but only %u %s resolved (%u unresolved). Additional\n" 889 " * ACPI tables are required to properly disassemble the code. This\n" 890 " * resulting disassembler output file may not compile because the\n" 891 " * disassembler did not know how many arguments to assign to the\n" 892 " * unresolved methods.\n" 893 " */\n", 894 AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods, 895 (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"), 896 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods)); 897 } 898 } 899 else 900 { 901 if (!AcpiGbl_ExternalFileList) 902 { 903 /* The -e option was not specified */ 904 905 fprintf (stderr, "\n" 906 "iASL Warning: There were %u external control methods found during\n" 907 "disassembly, but additional ACPI tables to resolve these externals\n" 908 "were not specified. The resulting disassembler output file may not\n" 909 "compile because the disassembler did not know how many arguments\n" 910 "to assign to these methods. To specify the tables needed to resolve\n" 911 "external control method references, use the one of the following\n" 912 "example iASL invocations:\n" 913 " iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n" 914 " iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n", 915 AcpiGbl_NumExternalMethods); 916 } 917 else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods) 918 { 919 /* The -e option was specified, but there are still some unresolved externals */ 920 921 fprintf (stderr, "\n" 922 "iASL Warning: There were %u external control methods found during\n" 923 "disassembly, but only %u %s resolved (%u unresolved). Additional\n" 924 "ACPI tables are required to properly disassemble the code. The\n" 925 "resulting disassembler output file may not compile because the\n" 926 "disassembler did not know how many arguments to assign to the\n" 927 "unresolved methods.\n", 928 AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods, 929 (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"), 930 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods)); 931 } 932 } 933 934 } 935