1 /******************************************************************************
3 * Module Name: dmextern - Support for External() ASL statements
5 *****************************************************************************/
7 /******************************************************************************
11 * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.
12 * All rights reserved.
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
37 * The above copyright and patent license is granted only if the following
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
72 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
80 * 4. Disclaimer and Export Compliance
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
114 *****************************************************************************/
117 #include "accommon.h"
119 #include "acnamesp.h"
120 #include "acdisasm.h"
121 #include "aslcompiler.h"
127 * This module is used for application-level code (iASL disassembler) only.
129 * It contains the code to create and emit any necessary External() ASL
130 * statements for the module being disassembled.
132 #define _COMPONENT ACPI_CA_DISASSEMBLER
133 ACPI_MODULE_NAME ("dmextern")
137 * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
138 * ObjectTypeKeyword. Used to generate typed external declarations
140 static const char *AcpiGbl_DmTypeNames
[] =
142 /* 00 */ ", UnknownObj", /* Type ANY */
145 /* 03 */ ", BuffObj",
147 /* 05 */ ", FieldUnitObj",
148 /* 06 */ ", DeviceObj",
149 /* 07 */ ", EventObj",
150 /* 08 */ ", MethodObj",
151 /* 09 */ ", MutexObj",
152 /* 10 */ ", OpRegionObj",
153 /* 11 */ ", PowerResObj",
154 /* 12 */ ", ProcessorObj",
155 /* 13 */ ", ThermalZoneObj",
156 /* 14 */ ", BuffFieldObj",
157 /* 15 */ ", DDBHandleObj",
158 /* 16 */ "", /* Debug object */
159 /* 17 */ ", FieldUnitObj",
160 /* 18 */ ", FieldUnitObj",
161 /* 19 */ ", FieldUnitObj"
164 #define METHOD_SEPARATORS " \t,()\n"
167 /* Local prototypes */
170 AcpiDmGetObjectTypeName (
171 ACPI_OBJECT_TYPE Type
);
174 AcpiDmNormalizeParentPrefix (
175 ACPI_PARSE_OBJECT
*Op
,
179 AcpiDmAddPathToExternalList (
186 AcpiDmCreateNewExternal (
194 /*******************************************************************************
196 * FUNCTION: AcpiDmGetObjectTypeName
198 * PARAMETERS: Type - An ACPI_OBJECT_TYPE
200 * RETURN: Pointer to a string
202 * DESCRIPTION: Map an object type to the ASL object type string.
204 ******************************************************************************/
207 AcpiDmGetObjectTypeName (
208 ACPI_OBJECT_TYPE Type
)
211 if (Type
== ACPI_TYPE_LOCAL_SCOPE
)
213 Type
= ACPI_TYPE_DEVICE
;
216 else if (Type
> ACPI_TYPE_LOCAL_INDEX_FIELD
)
221 return (AcpiGbl_DmTypeNames
[Type
]);
225 /*******************************************************************************
227 * FUNCTION: AcpiDmNormalizeParentPrefix
229 * PARAMETERS: Op - Parse op
230 * Path - Path with parent prefix
232 * RETURN: The full pathname to the object (from the namespace root)
234 * DESCRIPTION: Returns the full pathname of a path with parent prefix
235 * The caller must free the fullpath returned.
237 ******************************************************************************/
240 AcpiDmNormalizeParentPrefix (
241 ACPI_PARSE_OBJECT
*Op
,
244 ACPI_NAMESPACE_NODE
*Node
;
256 /* Search upwards in the parse tree until we reach the next namespace node */
258 Op
= Op
->Common
.Parent
;
266 Op
= Op
->Common
.Parent
;
275 * Find the actual parent node for the reference:
276 * Remove all carat prefixes from the input path.
277 * There may be multiple parent prefixes (For example, ^^^M000)
279 Node
= Op
->Common
.Node
;
280 while (Node
&& (*Path
== (UINT8
) AML_PARENT_PREFIX
))
291 /* Get the full pathname for the parent node */
293 ParentPath
= AcpiNsGetExternalPathname (Node
);
299 Length
= (ACPI_STRLEN (ParentPath
) + ACPI_STRLEN (Path
) + 1);
303 * If ParentPath is not just a simple '\', increment the length
304 * for the required dot separator (ParentPath.Path)
308 /* For External() statements, we do not want a leading '\' */
310 if (*ParentPath
== AML_ROOT_PREFIX
)
316 Fullpath
= ACPI_ALLOCATE_ZEROED (Length
);
323 * Concatenate parent fullpath and path. For example,
324 * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
326 * Copy the parent path
328 ACPI_STRCPY (Fullpath
, &ParentPath
[Index
]);
332 * (don't need dot if parent fullpath is a single backslash)
336 ACPI_STRCAT (Fullpath
, ".");
339 /* Copy child path (carat parent prefix(es) were skipped above) */
341 ACPI_STRCAT (Fullpath
, Path
);
344 ACPI_FREE (ParentPath
);
349 /*******************************************************************************
351 * FUNCTION: AcpiDmAddToExternalFileList
353 * PARAMETERS: PathList - Single path or list separated by comma
357 * DESCRIPTION: Add external files to global list
359 ******************************************************************************/
362 AcpiDmAddToExternalFileList (
365 ACPI_EXTERNAL_FILE
*ExternalFile
;
374 LocalPathname
= ACPI_ALLOCATE (strlen (Pathname
) + 1);
377 return (AE_NO_MEMORY
);
380 ExternalFile
= ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE
));
383 ACPI_FREE (LocalPathname
);
384 return (AE_NO_MEMORY
);
387 /* Take a copy of the file pathname */
389 strcpy (LocalPathname
, Pathname
);
390 ExternalFile
->Path
= LocalPathname
;
392 if (AcpiGbl_ExternalFileList
)
394 ExternalFile
->Next
= AcpiGbl_ExternalFileList
;
397 AcpiGbl_ExternalFileList
= ExternalFile
;
402 /*******************************************************************************
404 * FUNCTION: AcpiDmClearExternalFileList
410 * DESCRIPTION: Clear the external file list
412 ******************************************************************************/
415 AcpiDmClearExternalFileList (
418 ACPI_EXTERNAL_FILE
*NextExternal
;
421 while (AcpiGbl_ExternalFileList
)
423 NextExternal
= AcpiGbl_ExternalFileList
->Next
;
424 ACPI_FREE (AcpiGbl_ExternalFileList
->Path
);
425 ACPI_FREE (AcpiGbl_ExternalFileList
);
426 AcpiGbl_ExternalFileList
= NextExternal
;
431 /*******************************************************************************
433 * FUNCTION: AcpiDmGetExternalsFromFile
439 * DESCRIPTION: Process the optional external reference file.
441 * Each line in the file should be of the form:
442 * External (<Method namepath>, MethodObj, <ArgCount>)
445 * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
447 ******************************************************************************/
450 AcpiDmGetExternalsFromFile (
453 FILE *ExternalRefFile
;
457 UINT32 ImportCount
= 0;
460 if (!Gbl_ExternalRefFilename
)
467 ExternalRefFile
= fopen (Gbl_ExternalRefFilename
, "r");
468 if (!ExternalRefFile
)
470 fprintf (stderr
, "Could not open external reference file \"%s\"\n",
471 Gbl_ExternalRefFilename
);
476 /* Each line defines a method */
478 while (fgets (StringBuffer
, ASL_MSG_BUFFER_SIZE
, ExternalRefFile
))
480 Token
= strtok (StringBuffer
, METHOD_SEPARATORS
); /* "External" */
485 if (strcmp (Token
, "External"))
490 MethodName
= strtok (NULL
, METHOD_SEPARATORS
); /* Method namepath */
496 Token
= strtok (NULL
, METHOD_SEPARATORS
); /* "MethodObj" */
502 if (strcmp (Token
, "MethodObj"))
507 Token
= strtok (NULL
, METHOD_SEPARATORS
); /* Arg count */
513 /* Convert arg count string to an integer */
516 ArgCount
= strtoul (Token
, NULL
, 0);
519 fprintf (stderr
, "Invalid argument count (%s)\n", Token
);
524 fprintf (stderr
, "Invalid argument count (%u)\n", ArgCount
);
528 /* Add this external to the global list */
530 AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
531 Gbl_ExternalRefFilename
, ArgCount
, MethodName
);
533 AcpiDmAddPathToExternalList (MethodName
, ACPI_TYPE_METHOD
,
534 ArgCount
, (ACPI_EXT_RESOLVED_REFERENCE
| ACPI_EXT_ORIGIN_FROM_FILE
));
540 fprintf (stderr
, "Did not find any external methods in reference file \"%s\"\n",
541 Gbl_ExternalRefFilename
);
545 /* Add the external(s) to the namespace */
547 AcpiDmAddExternalsToNamespace ();
549 AcpiOsPrintf ("%s: Imported %u external method definitions\n",
550 Gbl_ExternalRefFilename
, ImportCount
);
553 fclose (ExternalRefFile
);
557 /*******************************************************************************
559 * FUNCTION: AcpiDmAddOpToExternalList
561 * PARAMETERS: Op - Current parser Op
562 * Path - Internal (AML) path to the object
563 * Type - ACPI object type to be added
564 * Value - Arg count if adding a Method object
565 * Flags - To be passed to the external object
569 * DESCRIPTION: Insert a new name into the global list of Externals which
570 * will in turn be later emitted as an External() declaration
571 * in the disassembled output.
573 * This function handles the most common case where the referenced
574 * name is simply not found in the constructed namespace.
576 ******************************************************************************/
579 AcpiDmAddOpToExternalList (
580 ACPI_PARSE_OBJECT
*Op
,
587 char *InternalPath
= Path
;
592 ACPI_FUNCTION_TRACE (DmAddOpToExternalList
);
600 /* Remove a root backslash if present */
602 if ((*Path
== AML_ROOT_PREFIX
) && (Path
[1]))
607 /* Externalize the pathname */
609 Status
= AcpiNsExternalizeName (ACPI_UINT32_MAX
, Path
,
610 NULL
, &ExternalPath
);
611 if (ACPI_FAILURE (Status
))
617 * Get the full pathname from the root if "Path" has one or more
618 * parent prefixes (^). Note: path will not contain a leading '\'.
620 if (*Path
== (UINT8
) AML_PARENT_PREFIX
)
622 Temp
= AcpiDmNormalizeParentPrefix (Op
, ExternalPath
);
624 /* Set new external path */
626 ACPI_FREE (ExternalPath
);
633 /* Create the new internal pathname */
635 Flags
|= ACPI_EXT_INTERNAL_PATH_ALLOCATED
;
636 Status
= AcpiNsInternalizeName (ExternalPath
, &InternalPath
);
637 if (ACPI_FAILURE (Status
))
639 ACPI_FREE (ExternalPath
);
644 /* Create the new External() declaration node */
646 Status
= AcpiDmCreateNewExternal (ExternalPath
, InternalPath
,
648 if (ACPI_FAILURE (Status
))
650 ACPI_FREE (ExternalPath
);
651 if (Flags
& ACPI_EXT_INTERNAL_PATH_ALLOCATED
)
653 ACPI_FREE (InternalPath
);
661 /*******************************************************************************
663 * FUNCTION: AcpiDmAddNodeToExternalList
665 * PARAMETERS: Node - Namespace node for object to be added
666 * Type - ACPI object type to be added
667 * Value - Arg count if adding a Method object
668 * Flags - To be passed to the external object
672 * DESCRIPTION: Insert a new name into the global list of Externals which
673 * will in turn be later emitted as an External() declaration
674 * in the disassembled output.
676 * This function handles the case where the referenced name has
677 * been found in the namespace, but the name originated in a
678 * table other than the one that is being disassembled (such
679 * as a table that is added via the iASL -e option).
681 ******************************************************************************/
684 AcpiDmAddNodeToExternalList (
685 ACPI_NAMESPACE_NODE
*Node
,
696 ACPI_FUNCTION_TRACE (DmAddNodeToExternalList
);
704 /* Get the full external and internal pathnames to the node */
706 ExternalPath
= AcpiNsGetExternalPathname (Node
);
712 Status
= AcpiNsInternalizeName (ExternalPath
, &InternalPath
);
713 if (ACPI_FAILURE (Status
))
715 ACPI_FREE (ExternalPath
);
719 /* Remove the root backslash */
721 if ((*ExternalPath
== AML_ROOT_PREFIX
) && (ExternalPath
[1]))
723 Temp
= ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (ExternalPath
) + 1);
729 ACPI_STRCPY (Temp
, &ExternalPath
[1]);
730 ACPI_FREE (ExternalPath
);
734 /* Create the new External() declaration node */
736 Status
= AcpiDmCreateNewExternal (ExternalPath
, InternalPath
, Type
,
737 Value
, (Flags
| ACPI_EXT_INTERNAL_PATH_ALLOCATED
));
738 if (ACPI_FAILURE (Status
))
740 ACPI_FREE (ExternalPath
);
741 ACPI_FREE (InternalPath
);
748 /*******************************************************************************
750 * FUNCTION: AcpiDmAddPathToExternalList
752 * PARAMETERS: Path - External name of the object to be added
753 * Type - ACPI object type to be added
754 * Value - Arg count if adding a Method object
755 * Flags - To be passed to the external object
759 * DESCRIPTION: Insert a new name into the global list of Externals which
760 * will in turn be later emitted as an External() declaration
761 * in the disassembled output.
763 * This function currently is used to add externals via a
764 * reference file (via the -fe iASL option).
766 ******************************************************************************/
769 AcpiDmAddPathToExternalList (
780 ACPI_FUNCTION_TRACE (DmAddPathToExternalList
);
788 /* Remove a root backslash if present */
790 if ((*Path
== AML_ROOT_PREFIX
) && (Path
[1]))
795 /* Create the internal and external pathnames */
797 Status
= AcpiNsInternalizeName (Path
, &InternalPath
);
798 if (ACPI_FAILURE (Status
))
803 Status
= AcpiNsExternalizeName (ACPI_UINT32_MAX
, InternalPath
,
804 NULL
, &ExternalPath
);
805 if (ACPI_FAILURE (Status
))
807 ACPI_FREE (InternalPath
);
811 /* Create the new External() declaration node */
813 Status
= AcpiDmCreateNewExternal (ExternalPath
, InternalPath
,
814 Type
, Value
, (Flags
| ACPI_EXT_INTERNAL_PATH_ALLOCATED
));
815 if (ACPI_FAILURE (Status
))
817 ACPI_FREE (ExternalPath
);
818 ACPI_FREE (InternalPath
);
825 /*******************************************************************************
827 * FUNCTION: AcpiDmCreateNewExternal
829 * PARAMETERS: ExternalPath - External path to the object
830 * InternalPath - Internal (AML) path to the object
831 * Type - ACPI object type to be added
832 * Value - Arg count if adding a Method object
833 * Flags - To be passed to the external object
837 * DESCRIPTION: Common low-level function to insert a new name into the global
838 * list of Externals which will in turn be later emitted as
839 * External() declarations in the disassembled output.
841 * Note: The external name should not include a root prefix
842 * (backslash). We do not want External() statements to contain
843 * a leading '\', as this prevents duplicate external statements
849 * This would cause a compile time error when the disassembled
850 * output file is recompiled.
852 * There are two cases that are handled here. For both, we emit
853 * an External() statement:
854 * 1) The name was simply not found in the namespace.
855 * 2) The name was found, but it originated in a table other than
856 * the table that is being disassembled.
858 ******************************************************************************/
861 AcpiDmCreateNewExternal (
868 ACPI_EXTERNAL_LIST
*NewExternal
;
869 ACPI_EXTERNAL_LIST
*NextExternal
;
870 ACPI_EXTERNAL_LIST
*PrevExternal
= NULL
;
873 ACPI_FUNCTION_TRACE (DmCreateNewExternal
);
876 /* Check all existing externals to ensure no duplicates */
878 NextExternal
= AcpiGbl_ExternalList
;
881 if (!ACPI_STRCMP (ExternalPath
, NextExternal
->Path
))
883 /* Duplicate method, check that the Value (ArgCount) is the same */
885 if ((NextExternal
->Type
== ACPI_TYPE_METHOD
) &&
886 (NextExternal
->Value
!= Value
) &&
889 ACPI_ERROR ((AE_INFO
,
890 "External method arg count mismatch %s: Current %u, attempted %u",
891 NextExternal
->Path
, NextExternal
->Value
, Value
));
894 /* Allow upgrade of type from ANY */
896 else if (NextExternal
->Type
== ACPI_TYPE_ANY
)
898 NextExternal
->Type
= Type
;
899 NextExternal
->Value
= Value
;
902 return_ACPI_STATUS (AE_ALREADY_EXISTS
);
905 NextExternal
= NextExternal
->Next
;
908 /* Allocate and init a new External() descriptor */
910 NewExternal
= ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST
));
913 return_ACPI_STATUS (AE_NO_MEMORY
);
916 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES
,
917 "Adding external reference node (%s) type [%s]\n",
918 ExternalPath
, AcpiUtGetTypeName (Type
)));
920 NewExternal
->Flags
= Flags
;
921 NewExternal
->Value
= Value
;
922 NewExternal
->Path
= ExternalPath
;
923 NewExternal
->Type
= Type
;
924 NewExternal
->Length
= (UINT16
) ACPI_STRLEN (ExternalPath
);
925 NewExternal
->InternalPath
= InternalPath
;
927 /* Link the new descriptor into the global list, alphabetically ordered */
929 NextExternal
= AcpiGbl_ExternalList
;
932 if (AcpiUtStricmp (NewExternal
->Path
, NextExternal
->Path
) < 0)
936 PrevExternal
->Next
= NewExternal
;
940 AcpiGbl_ExternalList
= NewExternal
;
943 NewExternal
->Next
= NextExternal
;
944 return_ACPI_STATUS (AE_OK
);
947 PrevExternal
= NextExternal
;
948 NextExternal
= NextExternal
->Next
;
953 PrevExternal
->Next
= NewExternal
;
957 AcpiGbl_ExternalList
= NewExternal
;
960 return_ACPI_STATUS (AE_OK
);
964 /*******************************************************************************
966 * FUNCTION: AcpiDmAddExternalsToNamespace
972 * DESCRIPTION: Add all externals to the namespace. Allows externals to be
975 ******************************************************************************/
978 AcpiDmAddExternalsToNamespace (
982 ACPI_NAMESPACE_NODE
*Node
;
983 ACPI_OPERAND_OBJECT
*ObjDesc
;
984 ACPI_EXTERNAL_LIST
*External
= AcpiGbl_ExternalList
;
989 /* Add the external name (object) into the namespace */
991 Status
= AcpiNsLookup (NULL
, External
->InternalPath
, External
->Type
,
992 ACPI_IMODE_LOAD_PASS1
,
993 ACPI_NS_ERROR_IF_FOUND
| ACPI_NS_EXTERNAL
| ACPI_NS_DONT_OPEN_SCOPE
,
996 if (ACPI_FAILURE (Status
))
998 ACPI_EXCEPTION ((AE_INFO
, Status
,
999 "while adding external to namespace [%s]",
1003 else switch (External
->Type
)
1005 case ACPI_TYPE_METHOD
:
1007 /* For methods, we need to save the argument count */
1009 ObjDesc
= AcpiUtCreateInternalObject (ACPI_TYPE_METHOD
);
1010 ObjDesc
->Method
.ParamCount
= (UINT8
) External
->Value
;
1011 Node
->Object
= ObjDesc
;
1014 case ACPI_TYPE_REGION
:
1016 /* Regions require a region sub-object */
1018 ObjDesc
= AcpiUtCreateInternalObject (ACPI_TYPE_REGION
);
1019 ObjDesc
->Region
.Node
= Node
;
1020 Node
->Object
= ObjDesc
;
1028 External
= External
->Next
;
1033 /*******************************************************************************
1035 * FUNCTION: AcpiDmGetExternalMethodCount
1039 * RETURN: The number of control method externals in the external list
1041 * DESCRIPTION: Return the number of method externals that have been generated.
1042 * If any control method externals have been found, we must
1043 * re-parse the entire definition block with the new information
1044 * (number of arguments for the methods.) This is limitation of
1045 * AML, we don't know the number of arguments from the control
1046 * method invocation itself.
1048 ******************************************************************************/
1051 AcpiDmGetExternalMethodCount (
1054 ACPI_EXTERNAL_LIST
*External
= AcpiGbl_ExternalList
;
1060 if (External
->Type
== ACPI_TYPE_METHOD
)
1065 External
= External
->Next
;
1072 /*******************************************************************************
1074 * FUNCTION: AcpiDmClearExternalList
1080 * DESCRIPTION: Free the entire External info list
1082 ******************************************************************************/
1085 AcpiDmClearExternalList (
1088 ACPI_EXTERNAL_LIST
*NextExternal
;
1091 while (AcpiGbl_ExternalList
)
1093 NextExternal
= AcpiGbl_ExternalList
->Next
;
1094 ACPI_FREE (AcpiGbl_ExternalList
->Path
);
1095 ACPI_FREE (AcpiGbl_ExternalList
);
1096 AcpiGbl_ExternalList
= NextExternal
;
1101 /*******************************************************************************
1103 * FUNCTION: AcpiDmEmitExternals
1109 * DESCRIPTION: Emit an External() ASL statement for each of the externals in
1110 * the global external info list.
1112 ******************************************************************************/
1115 AcpiDmEmitExternals (
1118 ACPI_EXTERNAL_LIST
*NextExternal
;
1121 if (!AcpiGbl_ExternalList
)
1127 * Determine the number of control methods in the external list, and
1128 * also how many of those externals were resolved via the namespace.
1130 NextExternal
= AcpiGbl_ExternalList
;
1131 while (NextExternal
)
1133 if (NextExternal
->Type
== ACPI_TYPE_METHOD
)
1135 AcpiGbl_NumExternalMethods
++;
1136 if (NextExternal
->Flags
& ACPI_EXT_RESOLVED_REFERENCE
)
1138 AcpiGbl_ResolvedExternalMethods
++;
1142 NextExternal
= NextExternal
->Next
;
1145 /* Check if any control methods were unresolved */
1147 AcpiDmUnresolvedWarning (1);
1149 /* Emit any unresolved method externals in a single text block */
1151 NextExternal
= AcpiGbl_ExternalList
;
1152 while (NextExternal
)
1154 if ((NextExternal
->Type
== ACPI_TYPE_METHOD
) &&
1155 (!(NextExternal
->Flags
& ACPI_EXT_RESOLVED_REFERENCE
)))
1157 AcpiOsPrintf (" External (%s%s",
1159 AcpiDmGetObjectTypeName (NextExternal
->Type
));
1161 AcpiOsPrintf (") // Warning: Unresolved method, "
1162 "guessing %u arguments\n",
1163 NextExternal
->Value
);
1165 NextExternal
->Flags
|= ACPI_EXT_EXTERNAL_EMITTED
;
1168 NextExternal
= NextExternal
->Next
;
1171 AcpiOsPrintf ("\n");
1174 /* Emit externals that were imported from a file */
1176 if (Gbl_ExternalRefFilename
)
1179 " /*\n * External declarations that were imported from\n"
1180 " * the reference file [%s]\n */\n",
1181 Gbl_ExternalRefFilename
);
1183 NextExternal
= AcpiGbl_ExternalList
;
1184 while (NextExternal
)
1186 if (!(NextExternal
->Flags
& ACPI_EXT_EXTERNAL_EMITTED
) &&
1187 (NextExternal
->Flags
& ACPI_EXT_ORIGIN_FROM_FILE
))
1189 AcpiOsPrintf (" External (%s%s",
1191 AcpiDmGetObjectTypeName (NextExternal
->Type
));
1193 if (NextExternal
->Type
== ACPI_TYPE_METHOD
)
1195 AcpiOsPrintf (") // %u Arguments\n",
1196 NextExternal
->Value
);
1200 AcpiOsPrintf (")\n");
1202 NextExternal
->Flags
|= ACPI_EXT_EXTERNAL_EMITTED
;
1205 NextExternal
= NextExternal
->Next
;
1208 AcpiOsPrintf ("\n");
1212 * Walk the list of externals found during the AML parsing
1214 while (AcpiGbl_ExternalList
)
1216 if (!(AcpiGbl_ExternalList
->Flags
& ACPI_EXT_EXTERNAL_EMITTED
))
1218 AcpiOsPrintf (" External (%s%s",
1219 AcpiGbl_ExternalList
->Path
,
1220 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList
->Type
));
1222 /* For methods, add a comment with the number of arguments */
1224 if (AcpiGbl_ExternalList
->Type
== ACPI_TYPE_METHOD
)
1226 AcpiOsPrintf (") // %u Arguments\n",
1227 AcpiGbl_ExternalList
->Value
);
1231 AcpiOsPrintf (")\n");
1235 /* Free this external info block and move on to next external */
1237 NextExternal
= AcpiGbl_ExternalList
->Next
;
1238 if (AcpiGbl_ExternalList
->Flags
& ACPI_EXT_INTERNAL_PATH_ALLOCATED
)
1240 ACPI_FREE (AcpiGbl_ExternalList
->InternalPath
);
1243 ACPI_FREE (AcpiGbl_ExternalList
->Path
);
1244 ACPI_FREE (AcpiGbl_ExternalList
);
1245 AcpiGbl_ExternalList
= NextExternal
;
1248 AcpiOsPrintf ("\n");
1252 /*******************************************************************************
1254 * FUNCTION: AcpiDmUnresolvedWarning
1256 * PARAMETERS: Type - Where to output the warning.
1257 * 0 means write to stderr
1258 * 1 means write to AcpiOsPrintf
1262 * DESCRIPTION: Issue warning message if there are unresolved external control
1263 * methods within the disassembly.
1265 ******************************************************************************/
1268 Summary of the external control method problem
:
1270 When the
-e option is used with disassembly
, the various SSDTs are simply
1271 loaded into a global
namespace for the disassembler to use in order to
1272 resolve control method
references (invocations
).
1274 The disassembler tracks any such references
, and will emit an
External()
1275 statement
for these types of methods
, with the proper number of arguments
.
1277 Without the SSDTs
, the AML does
not contain enough information to properly
1278 disassemble the control method invocation
-- because the disassembler does
1279 not know how many arguments to parse
.
1281 An example
: Assume we have two control methods
. ABCD has one argument
, and
1282 EFGH has zero arguments
. Further
, we have two additional control methods
1283 that invoke ABCD
and EFGH
, named T1
and T2
:
1293 ABCD (Add (2, 7, Local0
))
1301 Here is the AML code that is generated
for T1
and T2
:
1305 0000034C
: 14 10 54 31 5F
5F
00 ... "..T1__."
1308 187: ABCD (Add (2, 7, Local0
))
1310 00000353: 41 42 43 44 ............ "ABCD"
1311 00000357: 72 0A
02 0A
07 60 ...... "r....`"
1317 0000035D
: 14 10 54 32 5F
5F
00 ... "..T2__."
1322 00000364: 45 46 47 48 ............ "EFGH"
1324 193: Add (2, 7, Local0
)
1326 00000368: 72 0A
02 0A
07 60 ...... "r....`"
1329 Note that the AML code
for T1
and T2 is essentially identical
. When
1330 disassembling
this code
, the methods ABCD
and EFGH must be known to the
1331 disassembler
, otherwise it does
not know how to handle the method invocations
.
1333 In other words
, if ABCD
and EFGH are actually external control methods
1334 appearing in an SSDT
, the disassembler does
not know what to
do unless
1335 the owning SSDT has been loaded via the
-e option
.
1339 AcpiDmUnresolvedWarning (
1343 if (!AcpiGbl_NumExternalMethods
)
1350 if (!AcpiGbl_ExternalFileList
)
1352 /* The -e option was not specified */
1354 AcpiOsPrintf (" /*\n"
1355 " * iASL Warning: There were %u external control methods found during\n"
1356 " * disassembly, but additional ACPI tables to resolve these externals\n"
1357 " * were not specified. This resulting disassembler output file may not\n"
1358 " * compile because the disassembler did not know how many arguments\n"
1359 " * to assign to these methods. To specify the tables needed to resolve\n"
1360 " * external control method references, the -e option can be used to\n"
1361 " * specify the filenames. Example iASL invocations:\n"
1362 " * iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
1363 " * iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
1364 " * iasl -e ssdt*.aml -d dsdt.aml\n"
1366 " * In addition, the -fe option can be used to specify a file containing\n"
1367 " * control method external declarations with the associated method\n"
1368 " * argument counts. Each line of the file must be of the form:\n"
1369 " * External (<method pathname>, MethodObj, <argument count>)\n"
1371 " * iasl -fe refs.txt -d dsdt.aml\n"
1373 " * The following methods were unresolved and many not compile properly\n"
1374 " * because the disassembler had to guess at the number of arguments\n"
1375 " * required for each:\n"
1377 AcpiGbl_NumExternalMethods
);
1379 else if (AcpiGbl_NumExternalMethods
!= AcpiGbl_ResolvedExternalMethods
)
1381 /* The -e option was specified, but there are still some unresolved externals */
1383 AcpiOsPrintf (" /*\n"
1384 " * iASL Warning: There were %u external control methods found during\n"
1385 " * disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1386 " * ACPI tables may be required to properly disassemble the code. This\n"
1387 " * resulting disassembler output file may not compile because the\n"
1388 " * disassembler did not know how many arguments to assign to the\n"
1389 " * unresolved methods.\n"
1391 " * If necessary, the -fe option can be used to specify a file containing\n"
1392 " * control method external declarations with the associated method\n"
1393 " * argument counts. Each line of the file must be of the form:\n"
1394 " * External (<method pathname>, MethodObj, <argument count>)\n"
1396 " * iasl -fe refs.txt -d dsdt.aml\n"
1398 " * The following methods were unresolved and many not compile properly\n"
1399 " * because the disassembler had to guess at the number of arguments\n"
1400 " * required for each:\n"
1402 AcpiGbl_NumExternalMethods
, AcpiGbl_ResolvedExternalMethods
,
1403 (AcpiGbl_ResolvedExternalMethods
> 1 ? "were" : "was"),
1404 (AcpiGbl_NumExternalMethods
- AcpiGbl_ResolvedExternalMethods
));
1409 if (!AcpiGbl_ExternalFileList
)
1411 /* The -e option was not specified */
1413 fprintf (stderr
, "\n"
1414 "iASL Warning: There were %u external control methods found during\n"
1415 "disassembly, but additional ACPI tables to resolve these externals\n"
1416 "were not specified. The resulting disassembler output file may not\n"
1417 "compile because the disassembler did not know how many arguments\n"
1418 "to assign to these methods. To specify the tables needed to resolve\n"
1419 "external control method references, the -e option can be used to\n"
1420 "specify the filenames. Example iASL invocations:\n"
1421 " iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
1422 " iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
1423 " iasl -e ssdt*.aml -d dsdt.aml\n"
1425 "In addition, the -fe option can be used to specify a file containing\n"
1426 "control method external declarations with the associated method\n"
1427 "argument counts. Each line of the file must be of the form:\n"
1428 " External (<method pathname>, MethodObj, <argument count>)\n"
1430 " iasl -fe refs.txt -d dsdt.aml\n",
1431 AcpiGbl_NumExternalMethods
);
1433 else if (AcpiGbl_NumExternalMethods
!= AcpiGbl_ResolvedExternalMethods
)
1435 /* The -e option was specified, but there are still some unresolved externals */
1437 fprintf (stderr
, "\n"
1438 "iASL Warning: There were %u external control methods found during\n"
1439 "disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1440 "ACPI tables may be required to properly disassemble the code. The\n"
1441 "resulting disassembler output file may not compile because the\n"
1442 "disassembler did not know how many arguments to assign to the\n"
1443 "unresolved methods.\n"
1445 "If necessary, the -fe option can be used to specify a file containing\n"
1446 "control method external declarations with the associated method\n"
1447 "argument counts. Each line of the file must be of the form:\n"
1448 " External (<method pathname>, MethodObj, <argument count>)\n"
1450 " iasl -fe refs.txt -d dsdt.aml\n",
1451 AcpiGbl_NumExternalMethods
, AcpiGbl_ResolvedExternalMethods
,
1452 (AcpiGbl_ResolvedExternalMethods
> 1 ? "were" : "was"),
1453 (AcpiGbl_NumExternalMethods
- AcpiGbl_ResolvedExternalMethods
));