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 598 break; 599 } 600 601 External = External->Next; 602 } 603 } 604 605 606 /******************************************************************************* 607 * 608 * FUNCTION: AcpiDmGetExternalMethodCount 609 * 610 * PARAMETERS: None 611 * 612 * RETURN: The number of control method externals in the external list 613 * 614 * DESCRIPTION: Return the number of method externals that have been generated. 615 * If any control method externals have been found, we must 616 * re-parse the entire definition block with the new information 617 * (number of arguments for the methods.) This is limitation of 618 * AML, we don't know the number of arguments from the control 619 * method invocation itself. 620 * 621 ******************************************************************************/ 622 623 UINT32 624 AcpiDmGetExternalMethodCount ( 625 void) 626 { 627 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 628 UINT32 Count = 0; 629 630 631 while (External) 632 { 633 if (External->Type == ACPI_TYPE_METHOD) 634 { 635 Count++; 636 } 637 638 External = External->Next; 639 } 640 641 return (Count); 642 } 643 644 645 /******************************************************************************* 646 * 647 * FUNCTION: AcpiDmClearExternalList 648 * 649 * PARAMETERS: None 650 * 651 * RETURN: None 652 * 653 * DESCRIPTION: Free the entire External info list 654 * 655 ******************************************************************************/ 656 657 void 658 AcpiDmClearExternalList ( 659 void) 660 { 661 ACPI_EXTERNAL_LIST *NextExternal; 662 663 664 while (AcpiGbl_ExternalList) 665 { 666 NextExternal = AcpiGbl_ExternalList->Next; 667 ACPI_FREE (AcpiGbl_ExternalList->Path); 668 ACPI_FREE (AcpiGbl_ExternalList); 669 AcpiGbl_ExternalList = NextExternal; 670 } 671 } 672 673 674 /******************************************************************************* 675 * 676 * FUNCTION: AcpiDmEmitExternals 677 * 678 * PARAMETERS: None 679 * 680 * RETURN: None 681 * 682 * DESCRIPTION: Emit an External() ASL statement for each of the externals in 683 * the global external info list. 684 * 685 ******************************************************************************/ 686 687 void 688 AcpiDmEmitExternals ( 689 void) 690 { 691 ACPI_EXTERNAL_LIST *NextExternal; 692 693 694 if (!AcpiGbl_ExternalList) 695 { 696 return; 697 } 698 699 /* 700 * Determine the number of control methods in the external list, and 701 * also how many of those externals were resolved via the namespace. 702 */ 703 NextExternal = AcpiGbl_ExternalList; 704 while (NextExternal) 705 { 706 if (NextExternal->Type == ACPI_TYPE_METHOD) 707 { 708 AcpiGbl_NumExternalMethods++; 709 if (NextExternal->Resolved) 710 { 711 AcpiGbl_ResolvedExternalMethods++; 712 } 713 } 714 715 NextExternal = NextExternal->Next; 716 } 717 718 /* Check if any control methods were unresolved */ 719 720 AcpiDmUnresolvedWarning (1); 721 722 /* Emit any unresolved method externals in a single text block */ 723 724 NextExternal = AcpiGbl_ExternalList; 725 while (NextExternal) 726 { 727 if ((NextExternal->Type == ACPI_TYPE_METHOD) && 728 (!NextExternal->Resolved)) 729 { 730 AcpiOsPrintf (" External (%s%s", 731 NextExternal->Path, 732 AcpiDmGetObjectTypeName (NextExternal->Type)); 733 734 AcpiOsPrintf (") // Warning: Unresolved Method, " 735 "guessing %u arguments (may be incorrect, see warning above)\n", 736 NextExternal->Value); 737 738 NextExternal->Emitted = TRUE; 739 } 740 741 NextExternal = NextExternal->Next; 742 } 743 744 AcpiOsPrintf ("\n"); 745 746 /* 747 * Walk the list of externals (unresolved references) 748 * found during the AML parsing 749 */ 750 while (AcpiGbl_ExternalList) 751 { 752 if (!AcpiGbl_ExternalList->Emitted) 753 { 754 AcpiOsPrintf (" External (%s%s", 755 AcpiGbl_ExternalList->Path, 756 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); 757 758 /* For methods, add a comment with the number of arguments */ 759 760 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 761 { 762 AcpiOsPrintf (") // %u Arguments\n", 763 AcpiGbl_ExternalList->Value); 764 } 765 else 766 { 767 AcpiOsPrintf (")\n"); 768 } 769 } 770 771 /* Free this external info block and move on to next external */ 772 773 NextExternal = AcpiGbl_ExternalList->Next; 774 if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED) 775 { 776 ACPI_FREE (AcpiGbl_ExternalList->InternalPath); 777 } 778 779 ACPI_FREE (AcpiGbl_ExternalList->Path); 780 ACPI_FREE (AcpiGbl_ExternalList); 781 AcpiGbl_ExternalList = NextExternal; 782 } 783 784 AcpiOsPrintf ("\n"); 785 } 786 787 788 /******************************************************************************* 789 * 790 * FUNCTION: AcpiDmUnresolvedWarning 791 * 792 * PARAMETERS: Type - Where to output the warning. 793 * 0 means write to stderr 794 * 1 means write to AcpiOsPrintf 795 * 796 * RETURN: None 797 * 798 * DESCRIPTION: Issue warning message if there are unresolved external control 799 * methods within the disassembly. 800 * 801 ******************************************************************************/ 802 803 #if 0 804 Summary of the external control method problem: 805 806 When the -e option is used with disassembly, the various SSDTs are simply 807 loaded into a global namespace for the disassembler to use in order to 808 resolve control method references (invocations). 809 810 The disassembler tracks any such references, and will emit an External() 811 statement for these types of methods, with the proper number of arguments . 812 813 Without the SSDTs, the AML does not contain enough information to properly 814 disassemble the control method invocation -- because the disassembler does 815 not know how many arguments to parse. 816 817 An example: Assume we have two control methods. ABCD has one argument, and 818 EFGH has zero arguments. Further, we have two additional control methods 819 that invoke ABCD and EFGH, named T1 and T2: 820 821 Method (ABCD, 1) 822 { 823 } 824 Method (EFGH, 0) 825 { 826 } 827 Method (T1) 828 { 829 ABCD (Add (2, 7, Local0)) 830 } 831 Method (T2) 832 { 833 EFGH () 834 Add (2, 7, Local0) 835 } 836 837 Here is the AML code that is generated for T1 and T2: 838 839 185: Method (T1) 840 841 0000034C: 14 10 54 31 5F 5F 00 ... "..T1__." 842 843 186: { 844 187: ABCD (Add (2, 7, Local0)) 845 846 00000353: 41 42 43 44 ............ "ABCD" 847 00000357: 72 0A 02 0A 07 60 ...... "r....`" 848 849 188: } 850 851 190: Method (T2) 852 853 0000035D: 14 10 54 32 5F 5F 00 ... "..T2__." 854 855 191: { 856 192: EFGH () 857 858 00000364: 45 46 47 48 ............ "EFGH" 859 860 193: Add (2, 7, Local0) 861 862 00000368: 72 0A 02 0A 07 60 ...... "r....`" 863 194: } 864 865 Note that the AML code for T1 and T2 is essentially identical. When 866 disassembling this code, the methods ABCD and EFGH must be known to the 867 disassembler, otherwise it does not know how to handle the method invocations. 868 869 In other words, if ABCD and EFGH are actually external control methods 870 appearing in an SSDT, the disassembler does not know what to do unless 871 the owning SSDT has been loaded via the -e option. 872 #endif 873 874 void 875 AcpiDmUnresolvedWarning ( 876 UINT8 Type) 877 { 878 879 if (!AcpiGbl_NumExternalMethods) 880 { 881 return; 882 } 883 884 if (Type) 885 { 886 if (!AcpiGbl_ExternalFileList) 887 { 888 /* The -e option was not specified */ 889 890 AcpiOsPrintf (" /*\n" 891 " * iASL Warning: There were %u external control methods found during\n" 892 " * disassembly, but additional ACPI tables to resolve these externals\n" 893 " * were not specified. This resulting disassembler output file may not\n" 894 " * compile because the disassembler did not know how many arguments\n" 895 " * to assign to these methods. To specify the tables needed to resolve\n" 896 " * external control method references, use the one of the following\n" 897 " * example iASL invocations:\n" 898 " * iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n" 899 " * iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n" 900 " */\n", 901 AcpiGbl_NumExternalMethods); 902 } 903 else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods) 904 { 905 /* The -e option was specified, but there are still some unresolved externals */ 906 907 AcpiOsPrintf (" /*\n" 908 " * iASL Warning: There were %u external control methods found during\n" 909 " * disassembly, but only %u %s resolved (%u unresolved). Additional\n" 910 " * ACPI tables are required to properly disassemble the code. This\n" 911 " * resulting disassembler output file may not compile because the\n" 912 " * disassembler did not know how many arguments to assign to the\n" 913 " * unresolved methods.\n" 914 " */\n", 915 AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods, 916 (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"), 917 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods)); 918 } 919 } 920 else 921 { 922 if (!AcpiGbl_ExternalFileList) 923 { 924 /* The -e option was not specified */ 925 926 fprintf (stderr, "\n" 927 "iASL Warning: There were %u external control methods found during\n" 928 "disassembly, but additional ACPI tables to resolve these externals\n" 929 "were not specified. The resulting disassembler output file may not\n" 930 "compile because the disassembler did not know how many arguments\n" 931 "to assign to these methods. To specify the tables needed to resolve\n" 932 "external control method references, use the one of the following\n" 933 "example iASL invocations:\n" 934 " iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n" 935 " iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n", 936 AcpiGbl_NumExternalMethods); 937 } 938 else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods) 939 { 940 /* The -e option was specified, but there are still some unresolved externals */ 941 942 fprintf (stderr, "\n" 943 "iASL Warning: There were %u external control methods found during\n" 944 "disassembly, but only %u %s resolved (%u unresolved). Additional\n" 945 "ACPI tables are required to properly disassemble the code. The\n" 946 "resulting disassembler output file may not compile because the\n" 947 "disassembler did not know how many arguments to assign to the\n" 948 "unresolved methods.\n", 949 AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods, 950 (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"), 951 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods)); 952 } 953 } 954 } 955