1 /******************************************************************************
3 * Module Name: dmextern - Support for External() ASL statements
5 *****************************************************************************/
7 /******************************************************************************
11 * Some or all of this work - Copyright (c) 1999 - 2017, 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 *****************************************************************************
116 * Alternatively, you may choose to be licensed under the terms of the
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
122 * 1. Redistributions of source code must retain the above copyright
123 * notice, this list of conditions, and the following disclaimer,
124 * without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 * substantially similar to the "NO WARRANTY" disclaimer below
127 * ("Disclaimer") and any redistribution must be conditioned upon
128 * including a substantially similar Disclaimer requirement for further
129 * binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 * of any contributors may be used to endorse or promote products derived
132 * from this software without specific prior written permission.
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
150 *****************************************************************************/
152 #include <contrib/dev/acpica/include/acpi.h>
153 #include <contrib/dev/acpica/include/accommon.h>
154 #include <contrib/dev/acpica/include/amlcode.h>
155 #include <contrib/dev/acpica/include/acnamesp.h>
156 #include <contrib/dev/acpica/include/acdisasm.h>
157 #include <contrib/dev/acpica/compiler/aslcompiler.h>
163 * This module is used for application-level code (iASL disassembler) only.
165 * It contains the code to create and emit any necessary External() ASL
166 * statements for the module being disassembled.
168 #define _COMPONENT ACPI_CA_DISASSEMBLER
169 ACPI_MODULE_NAME ("dmextern")
173 * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
174 * ObjectTypeKeyword. Used to generate typed external declarations
176 static const char *AcpiGbl_DmTypeNames[] =
178 /* 00 */ ", UnknownObj", /* Type ANY */
181 /* 03 */ ", BuffObj",
183 /* 05 */ ", FieldUnitObj",
184 /* 06 */ ", DeviceObj",
185 /* 07 */ ", EventObj",
186 /* 08 */ ", MethodObj",
187 /* 09 */ ", MutexObj",
188 /* 10 */ ", OpRegionObj",
189 /* 11 */ ", PowerResObj",
190 /* 12 */ ", ProcessorObj",
191 /* 13 */ ", ThermalZoneObj",
192 /* 14 */ ", BuffFieldObj",
193 /* 15 */ ", DDBHandleObj",
194 /* 16 */ "", /* Debug object */
195 /* 17 */ ", FieldUnitObj",
196 /* 18 */ ", FieldUnitObj",
197 /* 19 */ ", FieldUnitObj"
200 #define METHOD_SEPARATORS " \t,()\n"
203 /* Local prototypes */
206 AcpiDmGetObjectTypeName (
207 ACPI_OBJECT_TYPE Type);
210 AcpiDmNormalizeParentPrefix (
211 ACPI_PARSE_OBJECT *Op,
215 AcpiDmAddPathToExternalList (
222 AcpiDmCreateNewExternal (
230 /*******************************************************************************
232 * FUNCTION: AcpiDmGetObjectTypeName
234 * PARAMETERS: Type - An ACPI_OBJECT_TYPE
236 * RETURN: Pointer to a string
238 * DESCRIPTION: Map an object type to the ASL object type string.
240 ******************************************************************************/
243 AcpiDmGetObjectTypeName (
244 ACPI_OBJECT_TYPE Type)
247 if (Type == ACPI_TYPE_LOCAL_SCOPE)
249 Type = ACPI_TYPE_DEVICE;
251 else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
256 return (AcpiGbl_DmTypeNames[Type]);
260 /*******************************************************************************
262 * FUNCTION: AcpiDmNormalizeParentPrefix
264 * PARAMETERS: Op - Parse op
265 * Path - Path with parent prefix
267 * RETURN: The full pathname to the object (from the namespace root)
269 * DESCRIPTION: Returns the full pathname of a path with parent prefix
270 * The caller must free the fullpath returned.
272 ******************************************************************************/
275 AcpiDmNormalizeParentPrefix (
276 ACPI_PARSE_OBJECT *Op,
279 ACPI_NAMESPACE_NODE *Node;
291 /* Search upwards in the parse tree until we reach the next namespace node */
293 Op = Op->Common.Parent;
301 Op = Op->Common.Parent;
310 * Find the actual parent node for the reference:
311 * Remove all carat prefixes from the input path.
312 * There may be multiple parent prefixes (For example, ^^^M000)
314 Node = Op->Common.Node;
315 while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
326 /* Get the full pathname for the parent node */
328 ParentPath = AcpiNsGetExternalPathname (Node);
334 Length = (strlen (ParentPath) + strlen (Path) + 1);
338 * If ParentPath is not just a simple '\', increment the length
339 * for the required dot separator (ParentPath.Path)
343 /* For External() statements, we do not want a leading '\' */
345 if (*ParentPath == AML_ROOT_PREFIX)
351 Fullpath = ACPI_ALLOCATE_ZEROED (Length);
358 * Concatenate parent fullpath and path. For example,
359 * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
361 * Copy the parent path
363 strcpy (Fullpath, &ParentPath[Index]);
367 * (don't need dot if parent fullpath is a single backslash)
371 strcat (Fullpath, ".");
374 /* Copy child path (carat parent prefix(es) were skipped above) */
376 strcat (Fullpath, Path);
379 ACPI_FREE (ParentPath);
384 /*******************************************************************************
386 * FUNCTION: AcpiDmAddToExternalFileList
388 * PARAMETERS: PathList - Single path or list separated by comma
392 * DESCRIPTION: Add external files to global list
394 ******************************************************************************/
397 AcpiDmAddToExternalFileList (
400 ACPI_EXTERNAL_FILE *ExternalFile;
409 LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
412 return (AE_NO_MEMORY);
415 ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
418 ACPI_FREE (LocalPathname);
419 return (AE_NO_MEMORY);
422 /* Take a copy of the file pathname */
424 strcpy (LocalPathname, Pathname);
425 ExternalFile->Path = LocalPathname;
427 if (AcpiGbl_ExternalFileList)
429 ExternalFile->Next = AcpiGbl_ExternalFileList;
432 AcpiGbl_ExternalFileList = ExternalFile;
437 /*******************************************************************************
439 * FUNCTION: AcpiDmClearExternalFileList
445 * DESCRIPTION: Clear the external file list
447 ******************************************************************************/
450 AcpiDmClearExternalFileList (
453 ACPI_EXTERNAL_FILE *NextExternal;
456 while (AcpiGbl_ExternalFileList)
458 NextExternal = AcpiGbl_ExternalFileList->Next;
459 ACPI_FREE (AcpiGbl_ExternalFileList->Path);
460 ACPI_FREE (AcpiGbl_ExternalFileList);
461 AcpiGbl_ExternalFileList = NextExternal;
466 /*******************************************************************************
468 * FUNCTION: AcpiDmGetExternalsFromFile
474 * DESCRIPTION: Process the optional external reference file.
476 * Each line in the file should be of the form:
477 * External (<Method namepath>, MethodObj, <ArgCount>)
480 * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
482 ******************************************************************************/
485 AcpiDmGetExternalsFromFile (
488 FILE *ExternalRefFile;
492 UINT32 ImportCount = 0;
495 if (!Gbl_ExternalRefFilename)
502 ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
503 if (!ExternalRefFile)
505 fprintf (stderr, "Could not open external reference file \"%s\"\n",
506 Gbl_ExternalRefFilename);
511 /* Each line defines a method */
513 while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile))
515 Token = strtok (StringBuffer, METHOD_SEPARATORS); /* "External" */
521 if (strcmp (Token, "External"))
526 MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */
532 Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */
538 if (strcmp (Token, "MethodObj"))
543 Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */
549 /* Convert arg count string to an integer */
552 ArgCount = strtoul (Token, NULL, 0);
555 fprintf (stderr, "Invalid argument count (%s)\n", Token);
561 fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
565 /* Add this external to the global list */
567 AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
568 Gbl_ExternalRefFilename, ArgCount, MethodName);
570 AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
571 ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
578 "Did not find any external methods in reference file \"%s\"\n",
579 Gbl_ExternalRefFilename);
583 /* Add the external(s) to the namespace */
585 AcpiDmAddExternalsToNamespace ();
587 AcpiOsPrintf ("%s: Imported %u external method definitions\n",
588 Gbl_ExternalRefFilename, ImportCount);
591 fclose (ExternalRefFile);
595 /*******************************************************************************
597 * FUNCTION: AcpiDmAddOpToExternalList
599 * PARAMETERS: Op - Current parser Op
600 * Path - Internal (AML) path to the object
601 * Type - ACPI object type to be added
602 * Value - Arg count if adding a Method object
603 * Flags - To be passed to the external object
607 * DESCRIPTION: Insert a new name into the global list of Externals which
608 * will in turn be later emitted as an External() declaration
609 * in the disassembled output.
611 * This function handles the most common case where the referenced
612 * name is simply not found in the constructed namespace.
614 ******************************************************************************/
617 AcpiDmAddOpToExternalList (
618 ACPI_PARSE_OBJECT *Op,
625 char *InternalPath = Path;
630 ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
638 /* Remove a root backslash if present */
640 if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
645 /* Externalize the pathname */
647 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
648 NULL, &ExternalPath);
649 if (ACPI_FAILURE (Status))
655 * Get the full pathname from the root if "Path" has one or more
656 * parent prefixes (^). Note: path will not contain a leading '\'.
658 if (*Path == (UINT8) AML_PARENT_PREFIX)
660 Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
662 /* Set new external path */
664 ACPI_FREE (ExternalPath);
671 /* Create the new internal pathname */
673 Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
674 Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
675 if (ACPI_FAILURE (Status))
677 ACPI_FREE (ExternalPath);
682 /* Create the new External() declaration node */
684 Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
686 if (ACPI_FAILURE (Status))
688 ACPI_FREE (ExternalPath);
689 if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
691 ACPI_FREE (InternalPath);
699 /*******************************************************************************
701 * FUNCTION: AcpiDmAddNodeToExternalList
703 * PARAMETERS: Node - Namespace node for object to be added
704 * Type - ACPI object type to be added
705 * Value - Arg count if adding a Method object
706 * Flags - To be passed to the external object
710 * DESCRIPTION: Insert a new name into the global list of Externals which
711 * will in turn be later emitted as an External() declaration
712 * in the disassembled output.
714 * This function handles the case where the referenced name has
715 * been found in the namespace, but the name originated in a
716 * table other than the one that is being disassembled (such
717 * as a table that is added via the iASL -e option).
719 ******************************************************************************/
722 AcpiDmAddNodeToExternalList (
723 ACPI_NAMESPACE_NODE *Node,
734 ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
742 /* Get the full external and internal pathnames to the node */
744 ExternalPath = AcpiNsGetExternalPathname (Node);
750 Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
751 if (ACPI_FAILURE (Status))
753 ACPI_FREE (ExternalPath);
757 /* Remove the root backslash */
759 if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1]))
761 Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1);
767 strcpy (Temp, &ExternalPath[1]);
768 ACPI_FREE (ExternalPath);
772 /* Create the new External() declaration node */
774 Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
775 Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
776 if (ACPI_FAILURE (Status))
778 ACPI_FREE (ExternalPath);
779 ACPI_FREE (InternalPath);
786 /*******************************************************************************
788 * FUNCTION: AcpiDmAddPathToExternalList
790 * PARAMETERS: Path - External name of the object to be added
791 * Type - ACPI object type to be added
792 * Value - Arg count if adding a Method object
793 * Flags - To be passed to the external object
797 * DESCRIPTION: Insert a new name into the global list of Externals which
798 * will in turn be later emitted as an External() declaration
799 * in the disassembled output.
801 * This function currently is used to add externals via a
802 * reference file (via the -fe iASL option).
804 ******************************************************************************/
807 AcpiDmAddPathToExternalList (
818 ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
826 /* Remove a root backslash if present */
828 if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
833 /* Create the internal and external pathnames */
835 Status = AcpiNsInternalizeName (Path, &InternalPath);
836 if (ACPI_FAILURE (Status))
841 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
842 NULL, &ExternalPath);
843 if (ACPI_FAILURE (Status))
845 ACPI_FREE (InternalPath);
849 /* Create the new External() declaration node */
851 Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
852 Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
853 if (ACPI_FAILURE (Status))
855 ACPI_FREE (ExternalPath);
856 ACPI_FREE (InternalPath);
863 /*******************************************************************************
865 * FUNCTION: AcpiDmCreateNewExternal
867 * PARAMETERS: ExternalPath - External path to the object
868 * InternalPath - Internal (AML) path to the object
869 * Type - ACPI object type to be added
870 * Value - Arg count if adding a Method object
871 * Flags - To be passed to the external object
875 * DESCRIPTION: Common low-level function to insert a new name into the global
876 * list of Externals which will in turn be later emitted as
877 * External() declarations in the disassembled output.
879 * Note: The external name should not include a root prefix
880 * (backslash). We do not want External() statements to contain
881 * a leading '\', as this prevents duplicate external statements
887 * This would cause a compile time error when the disassembled
888 * output file is recompiled.
890 * There are two cases that are handled here. For both, we emit
891 * an External() statement:
892 * 1) The name was simply not found in the namespace.
893 * 2) The name was found, but it originated in a table other than
894 * the table that is being disassembled.
896 ******************************************************************************/
899 AcpiDmCreateNewExternal (
906 ACPI_EXTERNAL_LIST *NewExternal;
907 ACPI_EXTERNAL_LIST *NextExternal;
908 ACPI_EXTERNAL_LIST *PrevExternal = NULL;
911 ACPI_FUNCTION_TRACE (DmCreateNewExternal);
914 /* Check all existing externals to ensure no duplicates */
916 NextExternal = AcpiGbl_ExternalList;
919 /* Check for duplicates */
921 if (!strcmp (ExternalPath, NextExternal->Path))
924 * If this external came from an External() opcode, we are
925 * finished with this one. (No need to check any further).
927 if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
929 return_ACPI_STATUS (AE_ALREADY_EXISTS);
932 /* Allow upgrade of type from ANY */
934 else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
935 (Type != ACPI_TYPE_ANY))
937 NextExternal->Type = Type;
940 /* Update the argument count as necessary */
942 if (Value < NextExternal->Value)
944 NextExternal->Value = Value;
949 NextExternal->Flags |= Flags;
950 NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
952 return_ACPI_STATUS (AE_ALREADY_EXISTS);
955 NextExternal = NextExternal->Next;
958 /* Allocate and init a new External() descriptor */
960 NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
963 return_ACPI_STATUS (AE_NO_MEMORY);
966 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
967 "Adding external reference node (%s) type [%s]\n",
968 ExternalPath, AcpiUtGetTypeName (Type)));
970 NewExternal->Flags = Flags;
971 NewExternal->Value = Value;
972 NewExternal->Path = ExternalPath;
973 NewExternal->Type = Type;
974 NewExternal->Length = (UINT16) strlen (ExternalPath);
975 NewExternal->InternalPath = InternalPath;
977 /* Link the new descriptor into the global list, alphabetically ordered */
979 NextExternal = AcpiGbl_ExternalList;
982 if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
986 PrevExternal->Next = NewExternal;
990 AcpiGbl_ExternalList = NewExternal;
993 NewExternal->Next = NextExternal;
994 return_ACPI_STATUS (AE_OK);
997 PrevExternal = NextExternal;
998 NextExternal = NextExternal->Next;
1003 PrevExternal->Next = NewExternal;
1007 AcpiGbl_ExternalList = NewExternal;
1010 return_ACPI_STATUS (AE_OK);
1014 /*******************************************************************************
1016 * FUNCTION: AcpiDmAddExternalsToNamespace
1022 * DESCRIPTION: Add all externals to the namespace. Allows externals to be
1025 ******************************************************************************/
1028 AcpiDmAddExternalsToNamespace (
1032 ACPI_NAMESPACE_NODE *Node;
1033 ACPI_OPERAND_OBJECT *ObjDesc;
1034 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
1039 /* Add the external name (object) into the namespace */
1041 Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
1042 ACPI_IMODE_LOAD_PASS1,
1043 ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
1046 if (ACPI_FAILURE (Status))
1048 ACPI_EXCEPTION ((AE_INFO, Status,
1049 "while adding external to namespace [%s]",
1053 else switch (External->Type)
1055 case ACPI_TYPE_METHOD:
1057 /* For methods, we need to save the argument count */
1059 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
1060 ObjDesc->Method.ParamCount = (UINT8) External->Value;
1061 Node->Object = ObjDesc;
1064 case ACPI_TYPE_REGION:
1066 /* Regions require a region sub-object */
1068 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
1069 ObjDesc->Region.Node = Node;
1070 Node->Object = ObjDesc;
1078 External = External->Next;
1083 /*******************************************************************************
1085 * FUNCTION: AcpiDmGetExternalMethodCount
1089 * RETURN: The number of control method externals in the external list
1091 * DESCRIPTION: Return the number of method externals that have been generated.
1092 * If any control method externals have been found, we must
1093 * re-parse the entire definition block with the new information
1094 * (number of arguments for the methods.) This is limitation of
1095 * AML, we don't know the number of arguments from the control
1096 * method invocation itself.
1098 ******************************************************************************/
1101 AcpiDmGetExternalMethodCount (
1104 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
1110 if (External->Type == ACPI_TYPE_METHOD)
1115 External = External->Next;
1122 /*******************************************************************************
1124 * FUNCTION: AcpiDmClearExternalList
1130 * DESCRIPTION: Free the entire External info list
1132 ******************************************************************************/
1135 AcpiDmClearExternalList (
1138 ACPI_EXTERNAL_LIST *NextExternal;
1141 while (AcpiGbl_ExternalList)
1143 NextExternal = AcpiGbl_ExternalList->Next;
1144 ACPI_FREE (AcpiGbl_ExternalList->Path);
1145 ACPI_FREE (AcpiGbl_ExternalList);
1146 AcpiGbl_ExternalList = NextExternal;
1151 /*******************************************************************************
1153 * FUNCTION: AcpiDmEmitExternals
1159 * DESCRIPTION: Emit an External() ASL statement for each of the externals in
1160 * the global external info list.
1162 ******************************************************************************/
1165 AcpiDmEmitExternals (
1168 ACPI_EXTERNAL_LIST *NextExternal;
1171 if (!AcpiGbl_ExternalList)
1177 * Determine the number of control methods in the external list, and
1178 * also how many of those externals were resolved via the namespace.
1180 NextExternal = AcpiGbl_ExternalList;
1181 while (NextExternal)
1183 if (NextExternal->Type == ACPI_TYPE_METHOD)
1185 AcpiGbl_NumExternalMethods++;
1186 if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
1188 AcpiGbl_ResolvedExternalMethods++;
1192 NextExternal = NextExternal->Next;
1195 /* Check if any control methods were unresolved */
1197 AcpiDmUnresolvedWarning (1);
1199 if (Gbl_ExternalRefFilename)
1202 " /*\n * External declarations were imported from\n"
1203 " * a reference file -- %s\n */\n\n",
1204 Gbl_ExternalRefFilename);
1208 * Walk and emit the list of externals found during the AML parsing
1210 while (AcpiGbl_ExternalList)
1212 if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
1214 AcpiOsPrintf (" External (%s%s)",
1215 AcpiGbl_ExternalList->Path,
1216 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
1218 /* Check for "unresolved" method reference */
1220 if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
1221 (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
1223 AcpiOsPrintf (" // Warning: Unknown method, "
1224 "guessing %u arguments",
1225 AcpiGbl_ExternalList->Value);
1228 /* Check for external from a external references file */
1230 else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
1232 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1234 AcpiOsPrintf (" // %u Arguments",
1235 AcpiGbl_ExternalList->Value);
1238 AcpiOsPrintf (" // From external reference file");
1241 /* This is the normal external case */
1245 /* For methods, add a comment with the number of arguments */
1247 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1249 AcpiOsPrintf (" // %u Arguments",
1250 AcpiGbl_ExternalList->Value);
1254 AcpiOsPrintf ("\n");
1257 /* Free this external info block and move on to next external */
1259 NextExternal = AcpiGbl_ExternalList->Next;
1260 if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
1262 ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
1265 ACPI_FREE (AcpiGbl_ExternalList->Path);
1266 ACPI_FREE (AcpiGbl_ExternalList);
1267 AcpiGbl_ExternalList = NextExternal;
1270 AcpiOsPrintf ("\n");
1274 /*******************************************************************************
1276 * FUNCTION: AcpiDmEmitExternal
1278 * PARAMETERS: Op External Parse Object
1282 * DESCRIPTION: Emit an External() ASL statement for the current External
1285 ******************************************************************************/
1288 AcpiDmEmitExternal (
1289 ACPI_PARSE_OBJECT *NameOp,
1290 ACPI_PARSE_OBJECT *TypeOp)
1292 AcpiOsPrintf ("External (");
1293 AcpiDmNamestring (NameOp->Common.Value.Name);
1294 AcpiOsPrintf ("%s)\n",
1295 AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));
1299 /*******************************************************************************
1301 * FUNCTION: AcpiDmUnresolvedWarning
1303 * PARAMETERS: Type - Where to output the warning.
1304 * 0 means write to stderr
1305 * 1 means write to AcpiOsPrintf
1309 * DESCRIPTION: Issue warning message if there are unresolved external control
1310 * methods within the disassembly.
1312 ******************************************************************************/
1315 Summary of the external control method problem:
1317 When the -e option is used with disassembly, the various SSDTs are simply
1318 loaded into a global namespace for the disassembler to use in order to
1319 resolve control method references (invocations).
1321 The disassembler tracks any such references, and will emit an External()
1322 statement for these types of methods, with the proper number of arguments .
1324 Without the SSDTs, the AML does not contain enough information to properly
1325 disassemble the control method invocation -- because the disassembler does
1326 not know how many arguments to parse.
1328 An example: Assume we have two control methods. ABCD has one argument, and
1329 EFGH has zero arguments. Further, we have two additional control methods
1330 that invoke ABCD and EFGH, named T1 and T2:
1340 ABCD (Add (2, 7, Local0))
1348 Here is the AML code that is generated for T1 and T2:
1352 0000034C: 14 10 54 31 5F 5F 00 ... "..T1__."
1355 187: ABCD (Add (2, 7, Local0))
1357 00000353: 41 42 43 44 ............ "ABCD"
1358 00000357: 72 0A 02 0A 07 60 ...... "r....`"
1364 0000035D: 14 10 54 32 5F 5F 00 ... "..T2__."
1369 00000364: 45 46 47 48 ............ "EFGH"
1371 193: Add (2, 7, Local0)
1373 00000368: 72 0A 02 0A 07 60 ...... "r....`"
1376 Note that the AML code for T1 and T2 is essentially identical. When
1377 disassembling this code, the methods ABCD and EFGH must be known to the
1378 disassembler, otherwise it does not know how to handle the method invocations.
1380 In other words, if ABCD and EFGH are actually external control methods
1381 appearing in an SSDT, the disassembler does not know what to do unless
1382 the owning SSDT has been loaded via the -e option.
1385 static char ExternalWarningPart1[600];
1386 static char ExternalWarningPart2[400];
1387 static char ExternalWarningPart3[400];
1388 static char ExternalWarningPart4[200];
1391 AcpiDmUnresolvedWarning (
1399 if (!AcpiGbl_NumExternalMethods)
1404 if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
1409 Format = Type ? Pad : NoPad;
1411 sprintf (ExternalWarningPart1,
1412 "%s iASL Warning: There %s %u external control method%s found during\n"
1413 "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1414 "%s ACPI tables may be required to properly disassemble the code. This\n"
1415 "%s resulting disassembler output file may not compile because the\n"
1416 "%s disassembler did not know how many arguments to assign to the\n"
1417 "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
1418 "%s runtime and may or may not be available via the host OS.\n",
1419 Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
1420 AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
1421 Format, AcpiGbl_ResolvedExternalMethods,
1422 (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
1423 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
1424 Format, Format, Format, Format, Format);
1426 sprintf (ExternalWarningPart2,
1427 "%s To specify the tables needed to resolve external control method\n"
1428 "%s references, the -e option can be used to specify the filenames.\n"
1429 "%s Example iASL invocations:\n"
1430 "%s iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
1431 "%s iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
1432 "%s iasl -e ssdt*.aml -d dsdt.aml\n",
1433 Format, Format, Format, Format, Format, Format);
1435 sprintf (ExternalWarningPart3,
1436 "%s In addition, the -fe option can be used to specify a file containing\n"
1437 "%s control method external declarations with the associated method\n"
1438 "%s argument counts. Each line of the file must be of the form:\n"
1439 "%s External (<method pathname>, MethodObj, <argument count>)\n"
1441 "%s iasl -fe refs.txt -d dsdt.aml\n",
1442 Format, Format, Format, Format, Format, Format);
1444 sprintf (ExternalWarningPart4,
1445 "%s The following methods were unresolved and many not compile properly\n"
1446 "%s because the disassembler had to guess at the number of arguments\n"
1447 "%s required for each:\n",
1448 Format, Format, Format);
1452 if (!AcpiGbl_ExternalFileList)
1454 /* The -e option was not specified */
1456 AcpiOsPrintf (" /*\n%s *\n%s *\n%s *\n%s */\n",
1457 ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
1458 ExternalWarningPart4);
1462 /* The -e option was specified, but there are still some unresolved externals */
1464 AcpiOsPrintf (" /*\n%s *\n%s *\n%s */\n",
1465 ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
1470 if (!AcpiGbl_ExternalFileList)
1472 /* The -e option was not specified */
1474 fprintf (stderr, "\n%s\n%s\n%s\n",
1475 ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
1479 /* The -e option was specified, but there are still some unresolved externals */
1481 fprintf (stderr, "\n%s\n%s\n",
1482 ExternalWarningPart1, ExternalWarningPart3);