1 /******************************************************************************
3 * Module Name: dmextern - Support for External() ASL statements
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
49 #include "aslcompiler.h"
55 * This module is used for application-level code (iASL disassembler) only.
57 * It contains the code to create and emit any necessary External() ASL
58 * statements for the module being disassembled.
60 #define _COMPONENT ACPI_CA_DISASSEMBLER
61 ACPI_MODULE_NAME ("dmextern")
65 * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
66 * ObjectTypeKeyword. Used to generate typed external declarations
68 static const char *AcpiGbl_DmTypeNames
[] =
70 /* 00 */ "", /* Type ANY */
75 /* 05 */ ", FieldUnitObj",
76 /* 06 */ ", DeviceObj",
77 /* 07 */ ", EventObj",
78 /* 08 */ ", MethodObj",
79 /* 09 */ ", MutexObj",
80 /* 10 */ ", OpRegionObj",
81 /* 11 */ ", PowerResObj",
82 /* 12 */ ", ProcessorObj",
83 /* 13 */ ", ThermalZoneObj",
84 /* 14 */ ", BuffFieldObj",
85 /* 15 */ ", DDBHandleObj",
86 /* 16 */ "", /* Debug object */
87 /* 17 */ ", FieldUnitObj",
88 /* 18 */ ", FieldUnitObj",
89 /* 19 */ ", FieldUnitObj"
92 #define METHOD_SEPARATORS " \t,()\n"
95 /* Local prototypes */
98 AcpiDmGetObjectTypeName (
99 ACPI_OBJECT_TYPE Type
);
102 AcpiDmNormalizeParentPrefix (
103 ACPI_PARSE_OBJECT
*Op
,
107 AcpiDmAddToExternalListFromFile (
113 /*******************************************************************************
115 * FUNCTION: AcpiDmGetObjectTypeName
117 * PARAMETERS: Type - An ACPI_OBJECT_TYPE
119 * RETURN: Pointer to a string
121 * DESCRIPTION: Map an object type to the ASL object type string.
123 ******************************************************************************/
126 AcpiDmGetObjectTypeName (
127 ACPI_OBJECT_TYPE Type
)
130 if (Type
== ACPI_TYPE_LOCAL_SCOPE
)
132 Type
= ACPI_TYPE_DEVICE
;
135 else if (Type
> ACPI_TYPE_LOCAL_INDEX_FIELD
)
140 return (AcpiGbl_DmTypeNames
[Type
]);
144 /*******************************************************************************
146 * FUNCTION: AcpiDmNormalizeParentPrefix
148 * PARAMETERS: Op - Parse op
149 * Path - Path with parent prefix
151 * RETURN: The full pathname to the object (from the namespace root)
153 * DESCRIPTION: Returns the full pathname of a path with parent prefix
154 * The caller must free the fullpath returned.
156 ******************************************************************************/
159 AcpiDmNormalizeParentPrefix (
160 ACPI_PARSE_OBJECT
*Op
,
163 ACPI_NAMESPACE_NODE
*Node
;
175 /* Search upwards in the parse tree until we reach the next namespace node */
177 Op
= Op
->Common
.Parent
;
185 Op
= Op
->Common
.Parent
;
194 * Find the actual parent node for the reference:
195 * Remove all carat prefixes from the input path.
196 * There may be multiple parent prefixes (For example, ^^^M000)
198 Node
= Op
->Common
.Node
;
199 while (Node
&& (*Path
== (UINT8
) AML_PARENT_PREFIX
))
210 /* Get the full pathname for the parent node */
212 ParentPath
= AcpiNsGetExternalPathname (Node
);
218 Length
= (ACPI_STRLEN (ParentPath
) + ACPI_STRLEN (Path
) + 1);
222 * If ParentPath is not just a simple '\', increment the length
223 * for the required dot separator (ParentPath.Path)
227 /* For External() statements, we do not want a leading '\' */
229 if (*ParentPath
== AML_ROOT_PREFIX
)
235 Fullpath
= ACPI_ALLOCATE_ZEROED (Length
);
242 * Concatenate parent fullpath and path. For example,
243 * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
245 * Copy the parent path
247 ACPI_STRCPY (Fullpath
, &ParentPath
[Index
]);
251 * (don't need dot if parent fullpath is a single backslash)
255 ACPI_STRCAT (Fullpath
, ".");
258 /* Copy child path (carat parent prefix(es) were skipped above) */
260 ACPI_STRCAT (Fullpath
, Path
);
263 ACPI_FREE (ParentPath
);
268 /*******************************************************************************
270 * FUNCTION: AcpiDmAddToExternalFileList
272 * PARAMETERS: PathList - Single path or list separated by comma
276 * DESCRIPTION: Add external files to global list
278 ******************************************************************************/
281 AcpiDmAddToExternalFileList (
284 ACPI_EXTERNAL_FILE
*ExternalFile
;
293 LocalPathname
= ACPI_ALLOCATE (strlen (Pathname
) + 1);
296 return (AE_NO_MEMORY
);
299 ExternalFile
= ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE
));
302 ACPI_FREE (LocalPathname
);
303 return (AE_NO_MEMORY
);
306 /* Take a copy of the file pathname */
308 strcpy (LocalPathname
, Pathname
);
309 ExternalFile
->Path
= LocalPathname
;
311 if (AcpiGbl_ExternalFileList
)
313 ExternalFile
->Next
= AcpiGbl_ExternalFileList
;
316 AcpiGbl_ExternalFileList
= ExternalFile
;
321 /*******************************************************************************
323 * FUNCTION: AcpiDmClearExternalFileList
329 * DESCRIPTION: Clear the external file list
331 ******************************************************************************/
334 AcpiDmClearExternalFileList (
337 ACPI_EXTERNAL_FILE
*NextExternal
;
340 while (AcpiGbl_ExternalFileList
)
342 NextExternal
= AcpiGbl_ExternalFileList
->Next
;
343 ACPI_FREE (AcpiGbl_ExternalFileList
->Path
);
344 ACPI_FREE (AcpiGbl_ExternalFileList
);
345 AcpiGbl_ExternalFileList
= NextExternal
;
350 /*******************************************************************************
352 * FUNCTION: AcpiDmAddToExternalList
354 * PARAMETERS: Op - Current parser Op
355 * Path - Internal (AML) path to the object
356 * Type - ACPI object type to be added
357 * Value - Arg count if adding a Method object
361 * DESCRIPTION: Insert a new name into the global list of Externals which
362 * will in turn be later emitted as an External() declaration
363 * in the disassembled output.
365 ******************************************************************************/
368 AcpiDmAddToExternalList (
369 ACPI_PARSE_OBJECT
*Op
,
375 char *Fullpath
= NULL
;
376 ACPI_EXTERNAL_LIST
*NewExternal
;
377 ACPI_EXTERNAL_LIST
*NextExternal
;
378 ACPI_EXTERNAL_LIST
*PrevExternal
= NULL
;
380 BOOLEAN Resolved
= FALSE
;
388 if (Type
== ACPI_TYPE_METHOD
)
398 * We don't want External() statements to contain a leading '\'.
399 * This prevents duplicate external statements of the form:
404 * This would cause a compile time error when the disassembled
405 * output file is recompiled.
407 if ((*Path
== AML_ROOT_PREFIX
) && (Path
[1]))
412 /* Externalize the ACPI pathname */
414 Status
= AcpiNsExternalizeName (ACPI_UINT32_MAX
, Path
,
415 NULL
, &ExternalPath
);
416 if (ACPI_FAILURE (Status
))
422 * Get the full pathname from the root if "Path" has one or more
423 * parent prefixes (^). Note: path will not contain a leading '\'.
425 if (*Path
== (UINT8
) AML_PARENT_PREFIX
)
427 Fullpath
= AcpiDmNormalizeParentPrefix (Op
, ExternalPath
);
430 /* Set new external path */
432 ACPI_FREE (ExternalPath
);
433 ExternalPath
= Fullpath
;
437 /* Check all existing externals to ensure no duplicates */
439 NextExternal
= AcpiGbl_ExternalList
;
442 if (!ACPI_STRCMP (ExternalPath
, NextExternal
->Path
))
444 /* Duplicate method, check that the Value (ArgCount) is the same */
446 if ((NextExternal
->Type
== ACPI_TYPE_METHOD
) &&
447 (NextExternal
->Value
!= Value
))
449 ACPI_ERROR ((AE_INFO
,
450 "External method arg count mismatch %s: Current %u, attempted %u",
451 NextExternal
->Path
, NextExternal
->Value
, Value
));
454 /* Allow upgrade of type from ANY */
456 else if (NextExternal
->Type
== ACPI_TYPE_ANY
)
458 NextExternal
->Type
= Type
;
459 NextExternal
->Value
= Value
;
462 ACPI_FREE (ExternalPath
);
466 NextExternal
= NextExternal
->Next
;
469 /* Allocate and init a new External() descriptor */
471 NewExternal
= ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST
));
474 ACPI_FREE (ExternalPath
);
478 NewExternal
->Path
= ExternalPath
;
479 NewExternal
->Type
= Type
;
480 NewExternal
->Value
= Value
;
481 NewExternal
->Resolved
= Resolved
;
482 NewExternal
->Length
= (UINT16
) ACPI_STRLEN (ExternalPath
);
484 /* Was the external path with parent prefix normalized to a fullpath? */
486 if (Fullpath
== ExternalPath
)
488 /* Get new internal path */
490 Status
= AcpiNsInternalizeName (ExternalPath
, &Path
);
491 if (ACPI_FAILURE (Status
))
493 ACPI_FREE (ExternalPath
);
494 ACPI_FREE (NewExternal
);
498 /* Set flag to indicate External->InternalPath need to be freed */
500 NewExternal
->Flags
|= ACPI_IPATH_ALLOCATED
;
503 NewExternal
->InternalPath
= Path
;
505 /* Link the new descriptor into the global list, alphabetically ordered */
507 NextExternal
= AcpiGbl_ExternalList
;
510 if (AcpiUtStricmp (NewExternal
->Path
, NextExternal
->Path
) < 0)
514 PrevExternal
->Next
= NewExternal
;
518 AcpiGbl_ExternalList
= NewExternal
;
521 NewExternal
->Next
= NextExternal
;
525 PrevExternal
= NextExternal
;
526 NextExternal
= NextExternal
->Next
;
531 PrevExternal
->Next
= NewExternal
;
535 AcpiGbl_ExternalList
= NewExternal
;
540 /*******************************************************************************
542 * FUNCTION: AcpiDmGetExternalsFromFile
548 * DESCRIPTION: Process the optional external reference file.
550 * Each line in the file should be of the form:
551 * External (<Method namepath>, MethodObj, <ArgCount>)
554 * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
556 ******************************************************************************/
559 AcpiDmGetExternalsFromFile (
562 FILE *ExternalRefFile
;
566 UINT32 ImportCount
= 0;
569 if (!Gbl_ExternalRefFilename
)
576 ExternalRefFile
= fopen (Gbl_ExternalRefFilename
, "r");
577 if (!ExternalRefFile
)
579 fprintf (stderr
, "Could not open external reference file \"%s\"\n",
580 Gbl_ExternalRefFilename
);
584 /* Each line defines a method */
586 while (fgets (StringBuffer
, ASL_MSG_BUFFER_SIZE
, ExternalRefFile
))
588 Token
= strtok (StringBuffer
, METHOD_SEPARATORS
); /* "External" */
589 if (!Token
) continue;
590 if (strcmp (Token
, "External")) continue;
592 MethodName
= strtok (NULL
, METHOD_SEPARATORS
); /* Method namepath */
593 if (!MethodName
) continue;
595 Token
= strtok (NULL
, METHOD_SEPARATORS
); /* "MethodObj" */
596 if (!Token
) continue;
597 if (strcmp (Token
, "MethodObj")) continue;
599 Token
= strtok (NULL
, METHOD_SEPARATORS
); /* Arg count */
600 if (!Token
) continue;
602 /* Convert arg count string to an integer */
605 ArgCount
= strtoul (Token
, NULL
, 0);
608 fprintf (stderr
, "Invalid argument count (%s)\n", Token
);
613 fprintf (stderr
, "Invalid argument count (%u)\n", ArgCount
);
617 /* Add this external to the global list */
619 AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
620 Gbl_ExternalRefFilename
, ArgCount
, MethodName
);
622 AcpiDmAddToExternalListFromFile (MethodName
, ACPI_TYPE_METHOD
, ArgCount
| 0x80);
628 fprintf (stderr
, "Did not find any external methods in reference file \"%s\"\n",
629 Gbl_ExternalRefFilename
);
633 /* Add the external(s) to the namespace */
635 AcpiDmAddExternalsToNamespace ();
637 AcpiOsPrintf ("%s: Imported %u external method definitions\n",
638 Gbl_ExternalRefFilename
, ImportCount
);
641 fclose (ExternalRefFile
);
645 /*******************************************************************************
647 * FUNCTION: AcpiDmAddToExternalListFromFile
649 * PARAMETERS: Path - Internal (AML) path to the object
650 * Type - ACPI object type to be added
651 * Value - Arg count if adding a Method object
655 * DESCRIPTION: Insert a new name into the global list of Externals which
656 * will in turn be later emitted as an External() declaration
657 * in the disassembled output.
659 ******************************************************************************/
662 AcpiDmAddToExternalListFromFile (
669 ACPI_EXTERNAL_LIST
*NewExternal
;
670 ACPI_EXTERNAL_LIST
*NextExternal
;
671 ACPI_EXTERNAL_LIST
*PrevExternal
= NULL
;
673 BOOLEAN Resolved
= FALSE
;
681 /* TBD: Add a flags parameter */
683 if (Type
== ACPI_TYPE_METHOD
)
693 * We don't want External() statements to contain a leading '\'.
694 * This prevents duplicate external statements of the form:
699 * This would cause a compile time error when the disassembled
700 * output file is recompiled.
702 if ((*Path
== AML_ROOT_PREFIX
) && (Path
[1]))
707 /* Check all existing externals to ensure no duplicates */
709 NextExternal
= AcpiGbl_ExternalList
;
712 if (!ACPI_STRCMP (Path
, NextExternal
->Path
))
714 /* Duplicate method, check that the Value (ArgCount) is the same */
716 if ((NextExternal
->Type
== ACPI_TYPE_METHOD
) &&
717 (NextExternal
->Value
!= Value
))
719 ACPI_ERROR ((AE_INFO
,
720 "(File) External method arg count mismatch %s: Current %u, override to %u",
721 NextExternal
->Path
, NextExternal
->Value
, Value
));
723 /* Override, since new value came from external reference file */
725 NextExternal
->Value
= Value
;
728 /* Allow upgrade of type from ANY */
730 else if (NextExternal
->Type
== ACPI_TYPE_ANY
)
732 NextExternal
->Type
= Type
;
733 NextExternal
->Value
= Value
;
739 NextExternal
= NextExternal
->Next
;
742 /* Get the internal pathname (AML format) */
744 Status
= AcpiNsInternalizeName (Path
, &InternalPath
);
745 if (ACPI_FAILURE (Status
))
750 /* Allocate and init a new External() descriptor */
752 NewExternal
= ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST
));
755 ACPI_FREE (InternalPath
);
759 /* Must copy and normalize the input path */
761 AcpiNsExternalizeName (ACPI_UINT32_MAX
, InternalPath
, NULL
, &ExternalPath
);
763 NewExternal
->Path
= ExternalPath
;
764 NewExternal
->Type
= Type
;
765 NewExternal
->Value
= Value
;
766 NewExternal
->Resolved
= Resolved
;
767 NewExternal
->Length
= (UINT16
) ACPI_STRLEN (Path
);
768 NewExternal
->InternalPath
= InternalPath
;
770 /* Set flag to indicate External->InternalPath needs to be freed */
772 NewExternal
->Flags
|= ACPI_IPATH_ALLOCATED
| ACPI_FROM_REFERENCE_FILE
;
774 /* Link the new descriptor into the global list, alphabetically ordered */
776 NextExternal
= AcpiGbl_ExternalList
;
779 if (AcpiUtStricmp (NewExternal
->Path
, NextExternal
->Path
) < 0)
783 PrevExternal
->Next
= NewExternal
;
787 AcpiGbl_ExternalList
= NewExternal
;
790 NewExternal
->Next
= NextExternal
;
794 PrevExternal
= NextExternal
;
795 NextExternal
= NextExternal
->Next
;
800 PrevExternal
->Next
= NewExternal
;
804 AcpiGbl_ExternalList
= NewExternal
;
809 /*******************************************************************************
811 * FUNCTION: AcpiDmAddExternalsToNamespace
817 * DESCRIPTION: Add all externals to the namespace. Allows externals to be
820 ******************************************************************************/
823 AcpiDmAddExternalsToNamespace (
827 ACPI_NAMESPACE_NODE
*Node
;
828 ACPI_OPERAND_OBJECT
*ObjDesc
;
829 ACPI_EXTERNAL_LIST
*External
= AcpiGbl_ExternalList
;
834 /* Add the external name (object) into the namespace */
836 Status
= AcpiNsLookup (NULL
, External
->InternalPath
, External
->Type
,
837 ACPI_IMODE_LOAD_PASS1
,
838 ACPI_NS_ERROR_IF_FOUND
| ACPI_NS_EXTERNAL
| ACPI_NS_DONT_OPEN_SCOPE
,
841 if (ACPI_FAILURE (Status
))
843 ACPI_EXCEPTION ((AE_INFO
, Status
,
844 "while adding external to namespace [%s]",
848 else switch (External
->Type
)
850 case ACPI_TYPE_METHOD
:
852 /* For methods, we need to save the argument count */
854 ObjDesc
= AcpiUtCreateInternalObject (ACPI_TYPE_METHOD
);
855 ObjDesc
->Method
.ParamCount
= (UINT8
) External
->Value
;
856 Node
->Object
= ObjDesc
;
859 case ACPI_TYPE_REGION
:
861 /* Regions require a region sub-object */
863 ObjDesc
= AcpiUtCreateInternalObject (ACPI_TYPE_REGION
);
864 ObjDesc
->Region
.Node
= Node
;
865 Node
->Object
= ObjDesc
;
873 External
= External
->Next
;
878 /*******************************************************************************
880 * FUNCTION: AcpiDmGetExternalMethodCount
884 * RETURN: The number of control method externals in the external list
886 * DESCRIPTION: Return the number of method externals that have been generated.
887 * If any control method externals have been found, we must
888 * re-parse the entire definition block with the new information
889 * (number of arguments for the methods.) This is limitation of
890 * AML, we don't know the number of arguments from the control
891 * method invocation itself.
893 ******************************************************************************/
896 AcpiDmGetExternalMethodCount (
899 ACPI_EXTERNAL_LIST
*External
= AcpiGbl_ExternalList
;
905 if (External
->Type
== ACPI_TYPE_METHOD
)
910 External
= External
->Next
;
917 /*******************************************************************************
919 * FUNCTION: AcpiDmClearExternalList
925 * DESCRIPTION: Free the entire External info list
927 ******************************************************************************/
930 AcpiDmClearExternalList (
933 ACPI_EXTERNAL_LIST
*NextExternal
;
936 while (AcpiGbl_ExternalList
)
938 NextExternal
= AcpiGbl_ExternalList
->Next
;
939 ACPI_FREE (AcpiGbl_ExternalList
->Path
);
940 ACPI_FREE (AcpiGbl_ExternalList
);
941 AcpiGbl_ExternalList
= NextExternal
;
946 /*******************************************************************************
948 * FUNCTION: AcpiDmEmitExternals
954 * DESCRIPTION: Emit an External() ASL statement for each of the externals in
955 * the global external info list.
957 ******************************************************************************/
960 AcpiDmEmitExternals (
963 ACPI_EXTERNAL_LIST
*NextExternal
;
966 if (!AcpiGbl_ExternalList
)
972 * Determine the number of control methods in the external list, and
973 * also how many of those externals were resolved via the namespace.
975 NextExternal
= AcpiGbl_ExternalList
;
978 if (NextExternal
->Type
== ACPI_TYPE_METHOD
)
980 AcpiGbl_NumExternalMethods
++;
981 if (NextExternal
->Resolved
)
983 AcpiGbl_ResolvedExternalMethods
++;
987 NextExternal
= NextExternal
->Next
;
990 /* Check if any control methods were unresolved */
992 AcpiDmUnresolvedWarning (1);
994 /* Emit any unresolved method externals in a single text block */
996 NextExternal
= AcpiGbl_ExternalList
;
999 if ((NextExternal
->Type
== ACPI_TYPE_METHOD
) &&
1000 (!NextExternal
->Resolved
))
1002 AcpiOsPrintf (" External (%s%s",
1004 AcpiDmGetObjectTypeName (NextExternal
->Type
));
1007 ") // Warning: Unresolved Method, "
1008 "guessing %u arguments (may be incorrect, see warning above)\n",
1009 NextExternal
->Value
);
1011 NextExternal
->Emitted
= TRUE
;
1014 NextExternal
= NextExternal
->Next
;
1017 AcpiOsPrintf ("\n");
1020 /* Emit externals that were imported from a file */
1022 if (Gbl_ExternalRefFilename
)
1025 " /*\n * External declarations that were imported from\n"
1026 " * the reference file [%s]\n */\n",
1027 Gbl_ExternalRefFilename
);
1029 NextExternal
= AcpiGbl_ExternalList
;
1030 while (NextExternal
)
1032 if (!NextExternal
->Emitted
&& (NextExternal
->Flags
& ACPI_FROM_REFERENCE_FILE
))
1034 AcpiOsPrintf (" External (%s%s",
1036 AcpiDmGetObjectTypeName (NextExternal
->Type
));
1038 if (NextExternal
->Type
== ACPI_TYPE_METHOD
)
1040 AcpiOsPrintf (") // %u Arguments\n",
1041 NextExternal
->Value
);
1045 AcpiOsPrintf (")\n");
1047 NextExternal
->Emitted
= TRUE
;
1050 NextExternal
= NextExternal
->Next
;
1053 AcpiOsPrintf ("\n");
1057 * Walk the list of externals found during the AML parsing
1059 while (AcpiGbl_ExternalList
)
1061 if (!AcpiGbl_ExternalList
->Emitted
)
1063 AcpiOsPrintf (" External (%s%s",
1064 AcpiGbl_ExternalList
->Path
,
1065 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList
->Type
));
1067 /* For methods, add a comment with the number of arguments */
1069 if (AcpiGbl_ExternalList
->Type
== ACPI_TYPE_METHOD
)
1071 AcpiOsPrintf (") // %u Arguments\n",
1072 AcpiGbl_ExternalList
->Value
);
1076 AcpiOsPrintf (")\n");
1080 /* Free this external info block and move on to next external */
1082 NextExternal
= AcpiGbl_ExternalList
->Next
;
1083 if (AcpiGbl_ExternalList
->Flags
& ACPI_IPATH_ALLOCATED
)
1085 ACPI_FREE (AcpiGbl_ExternalList
->InternalPath
);
1088 ACPI_FREE (AcpiGbl_ExternalList
->Path
);
1089 ACPI_FREE (AcpiGbl_ExternalList
);
1090 AcpiGbl_ExternalList
= NextExternal
;
1093 AcpiOsPrintf ("\n");
1097 /*******************************************************************************
1099 * FUNCTION: AcpiDmUnresolvedWarning
1101 * PARAMETERS: Type - Where to output the warning.
1102 * 0 means write to stderr
1103 * 1 means write to AcpiOsPrintf
1107 * DESCRIPTION: Issue warning message if there are unresolved external control
1108 * methods within the disassembly.
1110 ******************************************************************************/
1113 Summary of the external control method problem
:
1115 When the
-e option is used with disassembly
, the various SSDTs are simply
1116 loaded into a global
namespace for the disassembler to use in order to
1117 resolve control method
references (invocations
).
1119 The disassembler tracks any such references
, and will emit an
External()
1120 statement
for these types of methods
, with the proper number of arguments
.
1122 Without the SSDTs
, the AML does
not contain enough information to properly
1123 disassemble the control method invocation
-- because the disassembler does
1124 not know how many arguments to parse
.
1126 An example
: Assume we have two control methods
. ABCD has one argument
, and
1127 EFGH has zero arguments
. Further
, we have two additional control methods
1128 that invoke ABCD
and EFGH
, named T1
and T2
:
1138 ABCD (Add (2, 7, Local0
))
1146 Here is the AML code that is generated
for T1
and T2
:
1150 0000034C
: 14 10 54 31 5F
5F
00 ... "..T1__."
1153 187: ABCD (Add (2, 7, Local0
))
1155 00000353: 41 42 43 44 ............ "ABCD"
1156 00000357: 72 0A
02 0A
07 60 ...... "r....`"
1162 0000035D
: 14 10 54 32 5F
5F
00 ... "..T2__."
1167 00000364: 45 46 47 48 ............ "EFGH"
1169 193: Add (2, 7, Local0
)
1171 00000368: 72 0A
02 0A
07 60 ...... "r....`"
1174 Note that the AML code
for T1
and T2 is essentially identical
. When
1175 disassembling
this code
, the methods ABCD
and EFGH must be known to the
1176 disassembler
, otherwise it does
not know how to handle the method invocations
.
1178 In other words
, if ABCD
and EFGH are actually external control methods
1179 appearing in an SSDT
, the disassembler does
not know what to
do unless
1180 the owning SSDT has been loaded via the
-e option
.
1184 AcpiDmUnresolvedWarning (
1188 if (!AcpiGbl_NumExternalMethods
)
1195 if (!AcpiGbl_ExternalFileList
)
1197 /* The -e option was not specified */
1199 AcpiOsPrintf (" /*\n"
1200 " * iASL Warning: There were %u external control methods found during\n"
1201 " * disassembly, but additional ACPI tables to resolve these externals\n"
1202 " * were not specified. This resulting disassembler output file may not\n"
1203 " * compile because the disassembler did not know how many arguments\n"
1204 " * to assign to these methods. To specify the tables needed to resolve\n"
1205 " * external control method references, use the one of the following\n"
1206 " * example iASL invocations:\n"
1207 " * iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n"
1208 " * iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n"
1210 AcpiGbl_NumExternalMethods
);
1212 else if (AcpiGbl_NumExternalMethods
!= AcpiGbl_ResolvedExternalMethods
)
1214 /* The -e option was specified, but there are still some unresolved externals */
1216 AcpiOsPrintf (" /*\n"
1217 " * iASL Warning: There were %u external control methods found during\n"
1218 " * disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1219 " * ACPI tables are required to properly disassemble the code. This\n"
1220 " * resulting disassembler output file may not compile because the\n"
1221 " * disassembler did not know how many arguments to assign to the\n"
1222 " * unresolved methods.\n"
1224 AcpiGbl_NumExternalMethods
, AcpiGbl_ResolvedExternalMethods
,
1225 (AcpiGbl_ResolvedExternalMethods
> 1 ? "were" : "was"),
1226 (AcpiGbl_NumExternalMethods
- AcpiGbl_ResolvedExternalMethods
));
1231 if (!AcpiGbl_ExternalFileList
)
1233 /* The -e option was not specified */
1235 fprintf (stderr
, "\n"
1236 "iASL Warning: There were %u external control methods found during\n"
1237 "disassembly, but additional ACPI tables to resolve these externals\n"
1238 "were not specified. The resulting disassembler output file may not\n"
1239 "compile because the disassembler did not know how many arguments\n"
1240 "to assign to these methods. To specify the tables needed to resolve\n"
1241 "external control method references, use the one of the following\n"
1242 "example iASL invocations:\n"
1243 " iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n"
1244 " iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n",
1245 AcpiGbl_NumExternalMethods
);
1247 else if (AcpiGbl_NumExternalMethods
!= AcpiGbl_ResolvedExternalMethods
)
1249 /* The -e option was specified, but there are still some unresolved externals */
1251 fprintf (stderr
, "\n"
1252 "iASL Warning: There were %u external control methods found during\n"
1253 "disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1254 "ACPI tables are required to properly disassemble the code. The\n"
1255 "resulting disassembler output file may not compile because the\n"
1256 "disassembler did not know how many arguments to assign to the\n"
1257 "unresolved methods.\n",
1258 AcpiGbl_NumExternalMethods
, AcpiGbl_ResolvedExternalMethods
,
1259 (AcpiGbl_ResolvedExternalMethods
> 1 ? "were" : "was"),
1260 (AcpiGbl_NumExternalMethods
- AcpiGbl_ResolvedExternalMethods
));