xref: /freebsd/sys/contrib/dev/acpica/common/dmextern.c (revision 0d84335f991f528c6f038e79dd5cc0a7770532da)
1f556842eSJung-uk Kim /******************************************************************************
2f556842eSJung-uk Kim  *
3f556842eSJung-uk Kim  * Module Name: dmextern - Support for External() ASL statements
4f556842eSJung-uk Kim  *
5f556842eSJung-uk Kim  *****************************************************************************/
6f556842eSJung-uk Kim 
7*0d84335fSJung-uk Kim /******************************************************************************
8*0d84335fSJung-uk Kim  *
9*0d84335fSJung-uk Kim  * 1. Copyright Notice
10*0d84335fSJung-uk Kim  *
11*0d84335fSJung-uk Kim  * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12f556842eSJung-uk Kim  * All rights reserved.
13f556842eSJung-uk Kim  *
14*0d84335fSJung-uk Kim  * 2. License
15*0d84335fSJung-uk Kim  *
16*0d84335fSJung-uk Kim  * 2.1. This is your license from Intel Corp. under its intellectual property
17*0d84335fSJung-uk Kim  * rights. You may have additional license terms from the party that provided
18*0d84335fSJung-uk Kim  * you this software, covering your right to use that party's intellectual
19*0d84335fSJung-uk Kim  * property rights.
20*0d84335fSJung-uk Kim  *
21*0d84335fSJung-uk Kim  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22*0d84335fSJung-uk Kim  * copy of the source code appearing in this file ("Covered Code") an
23*0d84335fSJung-uk Kim  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24*0d84335fSJung-uk Kim  * base code distributed originally by Intel ("Original Intel Code") to copy,
25*0d84335fSJung-uk Kim  * make derivatives, distribute, use and display any portion of the Covered
26*0d84335fSJung-uk Kim  * Code in any form, with the right to sublicense such rights; and
27*0d84335fSJung-uk Kim  *
28*0d84335fSJung-uk Kim  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29*0d84335fSJung-uk Kim  * license (with the right to sublicense), under only those claims of Intel
30*0d84335fSJung-uk Kim  * patents that are infringed by the Original Intel Code, to make, use, sell,
31*0d84335fSJung-uk Kim  * offer to sell, and import the Covered Code and derivative works thereof
32*0d84335fSJung-uk Kim  * solely to the minimum extent necessary to exercise the above copyright
33*0d84335fSJung-uk Kim  * license, and in no event shall the patent license extend to any additions
34*0d84335fSJung-uk Kim  * to or modifications of the Original Intel Code. No other license or right
35*0d84335fSJung-uk Kim  * is granted directly or by implication, estoppel or otherwise;
36*0d84335fSJung-uk Kim  *
37*0d84335fSJung-uk Kim  * The above copyright and patent license is granted only if the following
38*0d84335fSJung-uk Kim  * conditions are met:
39*0d84335fSJung-uk Kim  *
40*0d84335fSJung-uk Kim  * 3. Conditions
41*0d84335fSJung-uk Kim  *
42*0d84335fSJung-uk Kim  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43*0d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
44*0d84335fSJung-uk Kim  * Code or modification with rights to further distribute source must include
45*0d84335fSJung-uk Kim  * the above Copyright Notice, the above License, this list of Conditions,
46*0d84335fSJung-uk Kim  * and the following Disclaimer and Export Compliance provision. In addition,
47*0d84335fSJung-uk Kim  * Licensee must cause all Covered Code to which Licensee contributes to
48*0d84335fSJung-uk Kim  * contain a file documenting the changes Licensee made to create that Covered
49*0d84335fSJung-uk Kim  * Code and the date of any change. Licensee must include in that file the
50*0d84335fSJung-uk Kim  * documentation of any changes made by any predecessor Licensee. Licensee
51*0d84335fSJung-uk Kim  * must include a prominent statement that the modification is derived,
52*0d84335fSJung-uk Kim  * directly or indirectly, from Original Intel Code.
53*0d84335fSJung-uk Kim  *
54*0d84335fSJung-uk Kim  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55*0d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
56*0d84335fSJung-uk Kim  * Code or modification without rights to further distribute source must
57*0d84335fSJung-uk Kim  * include the following Disclaimer and Export Compliance provision in the
58*0d84335fSJung-uk Kim  * documentation and/or other materials provided with distribution. In
59*0d84335fSJung-uk Kim  * addition, Licensee may not authorize further sublicense of source of any
60*0d84335fSJung-uk Kim  * portion of the Covered Code, and must include terms to the effect that the
61*0d84335fSJung-uk Kim  * license from Licensee to its licensee is limited to the intellectual
62*0d84335fSJung-uk Kim  * property embodied in the software Licensee provides to its licensee, and
63*0d84335fSJung-uk Kim  * not to intellectual property embodied in modifications its licensee may
64*0d84335fSJung-uk Kim  * make.
65*0d84335fSJung-uk Kim  *
66*0d84335fSJung-uk Kim  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67*0d84335fSJung-uk Kim  * substantial portion of the Covered Code or modification must reproduce the
68*0d84335fSJung-uk Kim  * above Copyright Notice, and the following Disclaimer and Export Compliance
69*0d84335fSJung-uk Kim  * provision in the documentation and/or other materials provided with the
70*0d84335fSJung-uk Kim  * distribution.
71*0d84335fSJung-uk Kim  *
72*0d84335fSJung-uk Kim  * 3.4. Intel retains all right, title, and interest in and to the Original
73*0d84335fSJung-uk Kim  * Intel Code.
74*0d84335fSJung-uk Kim  *
75*0d84335fSJung-uk Kim  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76*0d84335fSJung-uk Kim  * Intel shall be used in advertising or otherwise to promote the sale, use or
77*0d84335fSJung-uk Kim  * other dealings in products derived from or relating to the Covered Code
78*0d84335fSJung-uk Kim  * without prior written authorization from Intel.
79*0d84335fSJung-uk Kim  *
80*0d84335fSJung-uk Kim  * 4. Disclaimer and Export Compliance
81*0d84335fSJung-uk Kim  *
82*0d84335fSJung-uk Kim  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83*0d84335fSJung-uk Kim  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84*0d84335fSJung-uk Kim  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85*0d84335fSJung-uk Kim  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86*0d84335fSJung-uk Kim  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87*0d84335fSJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88*0d84335fSJung-uk Kim  * PARTICULAR PURPOSE.
89*0d84335fSJung-uk Kim  *
90*0d84335fSJung-uk Kim  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91*0d84335fSJung-uk Kim  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92*0d84335fSJung-uk Kim  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93*0d84335fSJung-uk Kim  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94*0d84335fSJung-uk Kim  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95*0d84335fSJung-uk Kim  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96*0d84335fSJung-uk Kim  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97*0d84335fSJung-uk Kim  * LIMITED REMEDY.
98*0d84335fSJung-uk Kim  *
99*0d84335fSJung-uk Kim  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100*0d84335fSJung-uk Kim  * software or system incorporating such software without first obtaining any
101*0d84335fSJung-uk Kim  * required license or other approval from the U. S. Department of Commerce or
102*0d84335fSJung-uk Kim  * any other agency or department of the United States Government. In the
103*0d84335fSJung-uk Kim  * event Licensee exports any such software from the United States or
104*0d84335fSJung-uk Kim  * re-exports any such software from a foreign destination, Licensee shall
105*0d84335fSJung-uk Kim  * ensure that the distribution and export/re-export of the software is in
106*0d84335fSJung-uk Kim  * compliance with all laws, regulations, orders, or other restrictions of the
107*0d84335fSJung-uk Kim  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108*0d84335fSJung-uk Kim  * any of its subsidiaries will export/re-export any technical data, process,
109*0d84335fSJung-uk Kim  * software, or service, directly or indirectly, to any country for which the
110*0d84335fSJung-uk Kim  * United States government or any agency thereof requires an export license,
111*0d84335fSJung-uk Kim  * other governmental approval, or letter of assurance, without first obtaining
112*0d84335fSJung-uk Kim  * such license, approval or letter.
113*0d84335fSJung-uk Kim  *
114*0d84335fSJung-uk Kim  *****************************************************************************
115*0d84335fSJung-uk Kim  *
116*0d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
117*0d84335fSJung-uk Kim  * following license:
118*0d84335fSJung-uk Kim  *
119d244b227SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
120d244b227SJung-uk Kim  * modification, are permitted provided that the following conditions
121d244b227SJung-uk Kim  * are met:
122d244b227SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
123d244b227SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
124d244b227SJung-uk Kim  *    without modification.
125d244b227SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126d244b227SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
127d244b227SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
128d244b227SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
129d244b227SJung-uk Kim  *    binary redistribution.
130d244b227SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
131d244b227SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
132d244b227SJung-uk Kim  *    from this software without specific prior written permission.
133f556842eSJung-uk Kim  *
134*0d84335fSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135*0d84335fSJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136*0d84335fSJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137*0d84335fSJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138*0d84335fSJung-uk Kim  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139*0d84335fSJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140*0d84335fSJung-uk Kim  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141*0d84335fSJung-uk Kim  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142*0d84335fSJung-uk Kim  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143*0d84335fSJung-uk Kim  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144*0d84335fSJung-uk Kim  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145*0d84335fSJung-uk Kim  *
146*0d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
147d244b227SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
148d244b227SJung-uk Kim  * Software Foundation.
149f556842eSJung-uk Kim  *
150*0d84335fSJung-uk Kim  *****************************************************************************/
151f556842eSJung-uk Kim 
152f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
153f556842eSJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
154f556842eSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
155f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
156f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h>
15779c6d946SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
1589c48c75eSJung-uk Kim #include <stdio.h>
15979c6d946SJung-uk Kim #include <errno.h>
160f556842eSJung-uk Kim 
161f556842eSJung-uk Kim 
162f556842eSJung-uk Kim /*
163f556842eSJung-uk Kim  * This module is used for application-level code (iASL disassembler) only.
164f556842eSJung-uk Kim  *
165f556842eSJung-uk Kim  * It contains the code to create and emit any necessary External() ASL
166f556842eSJung-uk Kim  * statements for the module being disassembled.
167f556842eSJung-uk Kim  */
168f556842eSJung-uk Kim #define _COMPONENT          ACPI_CA_DISASSEMBLER
169f556842eSJung-uk Kim         ACPI_MODULE_NAME    ("dmextern")
170f556842eSJung-uk Kim 
171f556842eSJung-uk Kim 
172f556842eSJung-uk Kim /*
173f556842eSJung-uk Kim  * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
174f556842eSJung-uk Kim  * ObjectTypeKeyword. Used to generate typed external declarations
175f556842eSJung-uk Kim  */
176f556842eSJung-uk Kim static const char           *AcpiGbl_DmTypeNames[] =
177f556842eSJung-uk Kim {
178313a0c13SJung-uk Kim     /* 00 */ ", UnknownObj",        /* Type ANY */
179f556842eSJung-uk Kim     /* 01 */ ", IntObj",
180f556842eSJung-uk Kim     /* 02 */ ", StrObj",
181f556842eSJung-uk Kim     /* 03 */ ", BuffObj",
182f556842eSJung-uk Kim     /* 04 */ ", PkgObj",
183f556842eSJung-uk Kim     /* 05 */ ", FieldUnitObj",
184f556842eSJung-uk Kim     /* 06 */ ", DeviceObj",
185f556842eSJung-uk Kim     /* 07 */ ", EventObj",
186f556842eSJung-uk Kim     /* 08 */ ", MethodObj",
187f556842eSJung-uk Kim     /* 09 */ ", MutexObj",
188f556842eSJung-uk Kim     /* 10 */ ", OpRegionObj",
189f556842eSJung-uk Kim     /* 11 */ ", PowerResObj",
190f556842eSJung-uk Kim     /* 12 */ ", ProcessorObj",
191f556842eSJung-uk Kim     /* 13 */ ", ThermalZoneObj",
192f556842eSJung-uk Kim     /* 14 */ ", BuffFieldObj",
193f556842eSJung-uk Kim     /* 15 */ ", DDBHandleObj",
194f556842eSJung-uk Kim     /* 16 */ "",                    /* Debug object */
195f556842eSJung-uk Kim     /* 17 */ ", FieldUnitObj",
196f556842eSJung-uk Kim     /* 18 */ ", FieldUnitObj",
197f556842eSJung-uk Kim     /* 19 */ ", FieldUnitObj"
198f556842eSJung-uk Kim };
199f556842eSJung-uk Kim 
20079c6d946SJung-uk Kim #define METHOD_SEPARATORS           " \t,()\n"
20179c6d946SJung-uk Kim 
202f556842eSJung-uk Kim 
203f556842eSJung-uk Kim /* Local prototypes */
204f556842eSJung-uk Kim 
205f556842eSJung-uk Kim static const char *
206f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
207f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type);
208f556842eSJung-uk Kim 
209f556842eSJung-uk Kim static char *
210f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
211f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
212f556842eSJung-uk Kim     char                    *Path);
213f556842eSJung-uk Kim 
21479c6d946SJung-uk Kim static void
215313a0c13SJung-uk Kim AcpiDmAddPathToExternalList (
21679c6d946SJung-uk Kim     char                    *Path,
21779c6d946SJung-uk Kim     UINT8                   Type,
218313a0c13SJung-uk Kim     UINT32                  Value,
219313a0c13SJung-uk Kim     UINT16                  Flags);
220313a0c13SJung-uk Kim 
221313a0c13SJung-uk Kim static ACPI_STATUS
222313a0c13SJung-uk Kim AcpiDmCreateNewExternal (
223313a0c13SJung-uk Kim     char                    *ExternalPath,
224313a0c13SJung-uk Kim     char                    *InternalPath,
225313a0c13SJung-uk Kim     UINT8                   Type,
226313a0c13SJung-uk Kim     UINT32                  Value,
227313a0c13SJung-uk Kim     UINT16                  Flags);
22879c6d946SJung-uk Kim 
229f556842eSJung-uk Kim 
230f556842eSJung-uk Kim /*******************************************************************************
231f556842eSJung-uk Kim  *
232f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetObjectTypeName
233f556842eSJung-uk Kim  *
234f556842eSJung-uk Kim  * PARAMETERS:  Type                - An ACPI_OBJECT_TYPE
235f556842eSJung-uk Kim  *
236f556842eSJung-uk Kim  * RETURN:      Pointer to a string
237f556842eSJung-uk Kim  *
238f556842eSJung-uk Kim  * DESCRIPTION: Map an object type to the ASL object type string.
239f556842eSJung-uk Kim  *
240f556842eSJung-uk Kim  ******************************************************************************/
241f556842eSJung-uk Kim 
242f556842eSJung-uk Kim static const char *
243f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
244f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type)
245f556842eSJung-uk Kim {
246f556842eSJung-uk Kim 
247f556842eSJung-uk Kim     if (Type == ACPI_TYPE_LOCAL_SCOPE)
248f556842eSJung-uk Kim     {
249f556842eSJung-uk Kim         Type = ACPI_TYPE_DEVICE;
250f556842eSJung-uk Kim     }
251f556842eSJung-uk Kim     else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
252f556842eSJung-uk Kim     {
253f556842eSJung-uk Kim         return ("");
254f556842eSJung-uk Kim     }
255f556842eSJung-uk Kim 
256f556842eSJung-uk Kim     return (AcpiGbl_DmTypeNames[Type]);
257f556842eSJung-uk Kim }
258f556842eSJung-uk Kim 
259f556842eSJung-uk Kim 
260f556842eSJung-uk Kim /*******************************************************************************
261f556842eSJung-uk Kim  *
262f556842eSJung-uk Kim  * FUNCTION:    AcpiDmNormalizeParentPrefix
263f556842eSJung-uk Kim  *
264f556842eSJung-uk Kim  * PARAMETERS:  Op                  - Parse op
265f556842eSJung-uk Kim  *              Path                - Path with parent prefix
266f556842eSJung-uk Kim  *
267f556842eSJung-uk Kim  * RETURN:      The full pathname to the object (from the namespace root)
268f556842eSJung-uk Kim  *
269f556842eSJung-uk Kim  * DESCRIPTION: Returns the full pathname of a path with parent prefix
270f556842eSJung-uk Kim  *              The caller must free the fullpath returned.
271f556842eSJung-uk Kim  *
272f556842eSJung-uk Kim  ******************************************************************************/
273f556842eSJung-uk Kim 
274f556842eSJung-uk Kim static char *
275f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
276f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
277f556842eSJung-uk Kim     char                    *Path)
278f556842eSJung-uk Kim {
279f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
280f556842eSJung-uk Kim     char                    *Fullpath;
281f556842eSJung-uk Kim     char                    *ParentPath;
282f556842eSJung-uk Kim     ACPI_SIZE               Length;
283ed17e06eSJung-uk Kim     UINT32                  Index = 0;
284f556842eSJung-uk Kim 
285f556842eSJung-uk Kim 
286ed17e06eSJung-uk Kim     if (!Op)
287ed17e06eSJung-uk Kim     {
288ed17e06eSJung-uk Kim         return (NULL);
289ed17e06eSJung-uk Kim     }
290f556842eSJung-uk Kim 
291ed17e06eSJung-uk Kim     /* Search upwards in the parse tree until we reach the next namespace node */
292ed17e06eSJung-uk Kim 
293ed17e06eSJung-uk Kim     Op = Op->Common.Parent;
294f556842eSJung-uk Kim     while (Op)
295f556842eSJung-uk Kim     {
296f556842eSJung-uk Kim         if (Op->Common.Node)
297f556842eSJung-uk Kim         {
298f556842eSJung-uk Kim             break;
299f556842eSJung-uk Kim         }
300f556842eSJung-uk Kim 
301f556842eSJung-uk Kim         Op = Op->Common.Parent;
302f556842eSJung-uk Kim     }
303f556842eSJung-uk Kim 
304f556842eSJung-uk Kim     if (!Op)
305f556842eSJung-uk Kim     {
306f556842eSJung-uk Kim         return (NULL);
307f556842eSJung-uk Kim     }
308f556842eSJung-uk Kim 
309f556842eSJung-uk Kim     /*
310f556842eSJung-uk Kim      * Find the actual parent node for the reference:
311f556842eSJung-uk Kim      * Remove all carat prefixes from the input path.
312f556842eSJung-uk Kim      * There may be multiple parent prefixes (For example, ^^^M000)
313f556842eSJung-uk Kim      */
314f556842eSJung-uk Kim     Node = Op->Common.Node;
315f556842eSJung-uk Kim     while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
316f556842eSJung-uk Kim     {
317a88e22b7SJung-uk Kim         Node = Node->Parent;
318f556842eSJung-uk Kim         Path++;
319f556842eSJung-uk Kim     }
320f556842eSJung-uk Kim 
321f556842eSJung-uk Kim     if (!Node)
322f556842eSJung-uk Kim     {
323f556842eSJung-uk Kim         return (NULL);
324f556842eSJung-uk Kim     }
325f556842eSJung-uk Kim 
326f556842eSJung-uk Kim     /* Get the full pathname for the parent node */
327f556842eSJung-uk Kim 
328f556842eSJung-uk Kim     ParentPath = AcpiNsGetExternalPathname (Node);
329f556842eSJung-uk Kim     if (!ParentPath)
330f556842eSJung-uk Kim     {
331f556842eSJung-uk Kim         return (NULL);
332f556842eSJung-uk Kim     }
333f556842eSJung-uk Kim 
3345ef50723SJung-uk Kim     Length = (strlen (ParentPath) + strlen (Path) + 1);
3358c8be05fSJung-uk Kim     if (ParentPath[1])
3368c8be05fSJung-uk Kim     {
3378c8be05fSJung-uk Kim         /*
3388c8be05fSJung-uk Kim          * If ParentPath is not just a simple '\', increment the length
3398c8be05fSJung-uk Kim          * for the required dot separator (ParentPath.Path)
3408c8be05fSJung-uk Kim          */
3418c8be05fSJung-uk Kim         Length++;
342ed17e06eSJung-uk Kim 
343ed17e06eSJung-uk Kim         /* For External() statements, we do not want a leading '\' */
344ed17e06eSJung-uk Kim 
345ed17e06eSJung-uk Kim         if (*ParentPath == AML_ROOT_PREFIX)
346ed17e06eSJung-uk Kim         {
347ed17e06eSJung-uk Kim             Index = 1;
348ed17e06eSJung-uk Kim         }
3498c8be05fSJung-uk Kim     }
3508c8be05fSJung-uk Kim 
351f556842eSJung-uk Kim     Fullpath = ACPI_ALLOCATE_ZEROED (Length);
352f556842eSJung-uk Kim     if (!Fullpath)
353f556842eSJung-uk Kim     {
354f556842eSJung-uk Kim         goto Cleanup;
355f556842eSJung-uk Kim     }
356f556842eSJung-uk Kim 
357f556842eSJung-uk Kim     /*
358f556842eSJung-uk Kim      * Concatenate parent fullpath and path. For example,
359f556842eSJung-uk Kim      * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
360f556842eSJung-uk Kim      *
361f556842eSJung-uk Kim      * Copy the parent path
362f556842eSJung-uk Kim      */
3635ef50723SJung-uk Kim     strcpy (Fullpath, &ParentPath[Index]);
364f556842eSJung-uk Kim 
365f38b0f21SJung-uk Kim     /*
366f38b0f21SJung-uk Kim      * Add dot separator
367f38b0f21SJung-uk Kim      * (don't need dot if parent fullpath is a single backslash)
368f38b0f21SJung-uk Kim      */
369f556842eSJung-uk Kim     if (ParentPath[1])
370f556842eSJung-uk Kim     {
3715ef50723SJung-uk Kim         strcat (Fullpath, ".");
372f556842eSJung-uk Kim     }
373f556842eSJung-uk Kim 
374f556842eSJung-uk Kim     /* Copy child path (carat parent prefix(es) were skipped above) */
375f556842eSJung-uk Kim 
3765ef50723SJung-uk Kim     strcat (Fullpath, Path);
377f556842eSJung-uk Kim 
378f556842eSJung-uk Kim Cleanup:
379f556842eSJung-uk Kim     ACPI_FREE (ParentPath);
380f556842eSJung-uk Kim     return (Fullpath);
381f556842eSJung-uk Kim }
382f556842eSJung-uk Kim 
383f556842eSJung-uk Kim 
384f556842eSJung-uk Kim /*******************************************************************************
385f556842eSJung-uk Kim  *
386709fac06SJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalFileList
387709fac06SJung-uk Kim  *
388709fac06SJung-uk Kim  * PARAMETERS:  PathList            - Single path or list separated by comma
389709fac06SJung-uk Kim  *
390709fac06SJung-uk Kim  * RETURN:      None
391709fac06SJung-uk Kim  *
392709fac06SJung-uk Kim  * DESCRIPTION: Add external files to global list
393709fac06SJung-uk Kim  *
394709fac06SJung-uk Kim  ******************************************************************************/
395709fac06SJung-uk Kim 
396709fac06SJung-uk Kim ACPI_STATUS
397709fac06SJung-uk Kim AcpiDmAddToExternalFileList (
398313a0c13SJung-uk Kim     char                    *Pathname)
399709fac06SJung-uk Kim {
400709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *ExternalFile;
401313a0c13SJung-uk Kim     char                    *LocalPathname;
402709fac06SJung-uk Kim 
403709fac06SJung-uk Kim 
404313a0c13SJung-uk Kim     if (!Pathname)
405709fac06SJung-uk Kim     {
406709fac06SJung-uk Kim         return (AE_OK);
407709fac06SJung-uk Kim     }
408709fac06SJung-uk Kim 
409313a0c13SJung-uk Kim     LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
410313a0c13SJung-uk Kim     if (!LocalPathname)
411709fac06SJung-uk Kim     {
412709fac06SJung-uk Kim         return (AE_NO_MEMORY);
413709fac06SJung-uk Kim     }
414709fac06SJung-uk Kim 
415709fac06SJung-uk Kim     ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
416709fac06SJung-uk Kim     if (!ExternalFile)
417709fac06SJung-uk Kim     {
418313a0c13SJung-uk Kim         ACPI_FREE (LocalPathname);
419709fac06SJung-uk Kim         return (AE_NO_MEMORY);
420709fac06SJung-uk Kim     }
421709fac06SJung-uk Kim 
422313a0c13SJung-uk Kim     /* Take a copy of the file pathname */
423313a0c13SJung-uk Kim 
424313a0c13SJung-uk Kim     strcpy (LocalPathname, Pathname);
425313a0c13SJung-uk Kim     ExternalFile->Path = LocalPathname;
426709fac06SJung-uk Kim 
427709fac06SJung-uk Kim     if (AcpiGbl_ExternalFileList)
428709fac06SJung-uk Kim     {
429709fac06SJung-uk Kim         ExternalFile->Next = AcpiGbl_ExternalFileList;
430709fac06SJung-uk Kim     }
431709fac06SJung-uk Kim 
432709fac06SJung-uk Kim     AcpiGbl_ExternalFileList = ExternalFile;
433709fac06SJung-uk Kim     return (AE_OK);
434709fac06SJung-uk Kim }
435709fac06SJung-uk Kim 
436709fac06SJung-uk Kim 
437709fac06SJung-uk Kim /*******************************************************************************
438709fac06SJung-uk Kim  *
439709fac06SJung-uk Kim  * FUNCTION:    AcpiDmClearExternalFileList
440709fac06SJung-uk Kim  *
441709fac06SJung-uk Kim  * PARAMETERS:  None
442709fac06SJung-uk Kim  *
443709fac06SJung-uk Kim  * RETURN:      None
444709fac06SJung-uk Kim  *
445709fac06SJung-uk Kim  * DESCRIPTION: Clear the external file list
446709fac06SJung-uk Kim  *
447709fac06SJung-uk Kim  ******************************************************************************/
448709fac06SJung-uk Kim 
449709fac06SJung-uk Kim void
450709fac06SJung-uk Kim AcpiDmClearExternalFileList (
451709fac06SJung-uk Kim     void)
452709fac06SJung-uk Kim {
453709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *NextExternal;
454709fac06SJung-uk Kim 
455709fac06SJung-uk Kim 
456709fac06SJung-uk Kim     while (AcpiGbl_ExternalFileList)
457709fac06SJung-uk Kim     {
458709fac06SJung-uk Kim         NextExternal = AcpiGbl_ExternalFileList->Next;
459709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList->Path);
460709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList);
461709fac06SJung-uk Kim         AcpiGbl_ExternalFileList = NextExternal;
462709fac06SJung-uk Kim     }
463709fac06SJung-uk Kim }
464709fac06SJung-uk Kim 
465709fac06SJung-uk Kim 
466709fac06SJung-uk Kim /*******************************************************************************
467709fac06SJung-uk Kim  *
46879c6d946SJung-uk Kim  * FUNCTION:    AcpiDmGetExternalsFromFile
46979c6d946SJung-uk Kim  *
47079c6d946SJung-uk Kim  * PARAMETERS:  None
47179c6d946SJung-uk Kim  *
47279c6d946SJung-uk Kim  * RETURN:      None
47379c6d946SJung-uk Kim  *
47479c6d946SJung-uk Kim  * DESCRIPTION: Process the optional external reference file.
47579c6d946SJung-uk Kim  *
47679c6d946SJung-uk Kim  * Each line in the file should be of the form:
47779c6d946SJung-uk Kim  *      External (<Method namepath>, MethodObj, <ArgCount>)
47879c6d946SJung-uk Kim  *
47979c6d946SJung-uk Kim  * Example:
48079c6d946SJung-uk Kim  *      External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
48179c6d946SJung-uk Kim  *
48279c6d946SJung-uk Kim  ******************************************************************************/
48379c6d946SJung-uk Kim 
48479c6d946SJung-uk Kim void
48579c6d946SJung-uk Kim AcpiDmGetExternalsFromFile (
48679c6d946SJung-uk Kim     void)
48779c6d946SJung-uk Kim {
48879c6d946SJung-uk Kim     FILE                    *ExternalRefFile;
48979c6d946SJung-uk Kim     char                    *Token;
49079c6d946SJung-uk Kim     char                    *MethodName;
49179c6d946SJung-uk Kim     UINT32                  ArgCount;
49279c6d946SJung-uk Kim     UINT32                  ImportCount = 0;
49379c6d946SJung-uk Kim 
49479c6d946SJung-uk Kim 
49579c6d946SJung-uk Kim     if (!Gbl_ExternalRefFilename)
49679c6d946SJung-uk Kim     {
49779c6d946SJung-uk Kim         return;
49879c6d946SJung-uk Kim     }
49979c6d946SJung-uk Kim 
50079c6d946SJung-uk Kim     /* Open the file */
50179c6d946SJung-uk Kim 
50279c6d946SJung-uk Kim     ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
50379c6d946SJung-uk Kim     if (!ExternalRefFile)
50479c6d946SJung-uk Kim     {
50579c6d946SJung-uk Kim         fprintf (stderr, "Could not open external reference file \"%s\"\n",
50679c6d946SJung-uk Kim             Gbl_ExternalRefFilename);
507313a0c13SJung-uk Kim         AslAbort ();
50879c6d946SJung-uk Kim         return;
50979c6d946SJung-uk Kim     }
51079c6d946SJung-uk Kim 
51179c6d946SJung-uk Kim     /* Each line defines a method */
51279c6d946SJung-uk Kim 
51379c6d946SJung-uk Kim     while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile))
51479c6d946SJung-uk Kim     {
51579c6d946SJung-uk Kim         Token = strtok (StringBuffer, METHOD_SEPARATORS);   /* "External" */
516313a0c13SJung-uk Kim         if (!Token)
517313a0c13SJung-uk Kim         {
518313a0c13SJung-uk Kim             continue;
519313a0c13SJung-uk Kim         }
520f8146b88SJung-uk Kim 
521313a0c13SJung-uk Kim         if (strcmp (Token, "External"))
522313a0c13SJung-uk Kim         {
523313a0c13SJung-uk Kim             continue;
524313a0c13SJung-uk Kim         }
52579c6d946SJung-uk Kim 
52679c6d946SJung-uk Kim         MethodName = strtok (NULL, METHOD_SEPARATORS);      /* Method namepath */
527313a0c13SJung-uk Kim         if (!MethodName)
528313a0c13SJung-uk Kim         {
529313a0c13SJung-uk Kim             continue;
530313a0c13SJung-uk Kim         }
53179c6d946SJung-uk Kim 
53279c6d946SJung-uk Kim         Token = strtok (NULL, METHOD_SEPARATORS);           /* "MethodObj" */
533313a0c13SJung-uk Kim         if (!Token)
534313a0c13SJung-uk Kim         {
535313a0c13SJung-uk Kim             continue;
536313a0c13SJung-uk Kim         }
537313a0c13SJung-uk Kim 
538313a0c13SJung-uk Kim         if (strcmp (Token, "MethodObj"))
539313a0c13SJung-uk Kim         {
540313a0c13SJung-uk Kim             continue;
541313a0c13SJung-uk Kim         }
54279c6d946SJung-uk Kim 
54379c6d946SJung-uk Kim         Token = strtok (NULL, METHOD_SEPARATORS);           /* Arg count */
544313a0c13SJung-uk Kim         if (!Token)
545313a0c13SJung-uk Kim         {
546313a0c13SJung-uk Kim             continue;
547313a0c13SJung-uk Kim         }
54879c6d946SJung-uk Kim 
54979c6d946SJung-uk Kim         /* Convert arg count string to an integer */
55079c6d946SJung-uk Kim 
55179c6d946SJung-uk Kim         errno = 0;
55279c6d946SJung-uk Kim         ArgCount = strtoul (Token, NULL, 0);
55379c6d946SJung-uk Kim         if (errno)
55479c6d946SJung-uk Kim         {
55579c6d946SJung-uk Kim             fprintf (stderr, "Invalid argument count (%s)\n", Token);
55679c6d946SJung-uk Kim             continue;
55779c6d946SJung-uk Kim         }
558f8146b88SJung-uk Kim 
55979c6d946SJung-uk Kim         if (ArgCount > 7)
56079c6d946SJung-uk Kim         {
56179c6d946SJung-uk Kim             fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
56279c6d946SJung-uk Kim             continue;
56379c6d946SJung-uk Kim         }
56479c6d946SJung-uk Kim 
56579c6d946SJung-uk Kim         /* Add this external to the global list */
56679c6d946SJung-uk Kim 
56779c6d946SJung-uk Kim         AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
56879c6d946SJung-uk Kim             Gbl_ExternalRefFilename, ArgCount, MethodName);
56979c6d946SJung-uk Kim 
570313a0c13SJung-uk Kim         AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
571313a0c13SJung-uk Kim             ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
57279c6d946SJung-uk Kim         ImportCount++;
57379c6d946SJung-uk Kim     }
57479c6d946SJung-uk Kim 
57579c6d946SJung-uk Kim     if (!ImportCount)
57679c6d946SJung-uk Kim     {
577f8146b88SJung-uk Kim         fprintf (stderr,
578f8146b88SJung-uk Kim             "Did not find any external methods in reference file \"%s\"\n",
57979c6d946SJung-uk Kim             Gbl_ExternalRefFilename);
58079c6d946SJung-uk Kim     }
58179c6d946SJung-uk Kim     else
58279c6d946SJung-uk Kim     {
58379c6d946SJung-uk Kim         /* Add the external(s) to the namespace */
58479c6d946SJung-uk Kim 
58579c6d946SJung-uk Kim         AcpiDmAddExternalsToNamespace ();
58679c6d946SJung-uk Kim 
58779c6d946SJung-uk Kim         AcpiOsPrintf ("%s: Imported %u external method definitions\n",
58879c6d946SJung-uk Kim             Gbl_ExternalRefFilename, ImportCount);
58979c6d946SJung-uk Kim     }
59079c6d946SJung-uk Kim 
59179c6d946SJung-uk Kim     fclose (ExternalRefFile);
59279c6d946SJung-uk Kim }
59379c6d946SJung-uk Kim 
59479c6d946SJung-uk Kim 
59579c6d946SJung-uk Kim /*******************************************************************************
59679c6d946SJung-uk Kim  *
597313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmAddOpToExternalList
59879c6d946SJung-uk Kim  *
599313a0c13SJung-uk Kim  * PARAMETERS:  Op                  - Current parser Op
600313a0c13SJung-uk Kim  *              Path                - Internal (AML) path to the object
60179c6d946SJung-uk Kim  *              Type                - ACPI object type to be added
60279c6d946SJung-uk Kim  *              Value               - Arg count if adding a Method object
603313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
60479c6d946SJung-uk Kim  *
60579c6d946SJung-uk Kim  * RETURN:      None
60679c6d946SJung-uk Kim  *
60779c6d946SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
60879c6d946SJung-uk Kim  *              will in turn be later emitted as an External() declaration
60979c6d946SJung-uk Kim  *              in the disassembled output.
61079c6d946SJung-uk Kim  *
611313a0c13SJung-uk Kim  *              This function handles the most common case where the referenced
612313a0c13SJung-uk Kim  *              name is simply not found in the constructed namespace.
613313a0c13SJung-uk Kim  *
61479c6d946SJung-uk Kim  ******************************************************************************/
61579c6d946SJung-uk Kim 
616313a0c13SJung-uk Kim void
617313a0c13SJung-uk Kim AcpiDmAddOpToExternalList (
618313a0c13SJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
61979c6d946SJung-uk Kim     char                    *Path,
62079c6d946SJung-uk Kim     UINT8                   Type,
621313a0c13SJung-uk Kim     UINT32                  Value,
622313a0c13SJung-uk Kim     UINT16                  Flags)
62379c6d946SJung-uk Kim {
62479c6d946SJung-uk Kim     char                    *ExternalPath;
625313a0c13SJung-uk Kim     char                    *InternalPath = Path;
626313a0c13SJung-uk Kim     char                    *Temp;
62779c6d946SJung-uk Kim     ACPI_STATUS             Status;
628313a0c13SJung-uk Kim 
629313a0c13SJung-uk Kim 
630313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
63179c6d946SJung-uk Kim 
63279c6d946SJung-uk Kim 
63379c6d946SJung-uk Kim     if (!Path)
63479c6d946SJung-uk Kim     {
635313a0c13SJung-uk Kim         return_VOID;
63679c6d946SJung-uk Kim     }
63779c6d946SJung-uk Kim 
638313a0c13SJung-uk Kim     /* Remove a root backslash if present */
63979c6d946SJung-uk Kim 
640313a0c13SJung-uk Kim     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
64179c6d946SJung-uk Kim     {
642313a0c13SJung-uk Kim         Path++;
64379c6d946SJung-uk Kim     }
644313a0c13SJung-uk Kim 
645313a0c13SJung-uk Kim     /* Externalize the pathname */
646313a0c13SJung-uk Kim 
647313a0c13SJung-uk Kim     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
648313a0c13SJung-uk Kim         NULL, &ExternalPath);
649313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
650313a0c13SJung-uk Kim     {
651313a0c13SJung-uk Kim         return_VOID;
65279c6d946SJung-uk Kim     }
65379c6d946SJung-uk Kim 
65479c6d946SJung-uk Kim     /*
655313a0c13SJung-uk Kim      * Get the full pathname from the root if "Path" has one or more
656313a0c13SJung-uk Kim      * parent prefixes (^). Note: path will not contain a leading '\'.
657313a0c13SJung-uk Kim      */
658313a0c13SJung-uk Kim     if (*Path == (UINT8) AML_PARENT_PREFIX)
659313a0c13SJung-uk Kim     {
660313a0c13SJung-uk Kim         Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
661313a0c13SJung-uk Kim 
662313a0c13SJung-uk Kim         /* Set new external path */
663313a0c13SJung-uk Kim 
664313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
665313a0c13SJung-uk Kim         ExternalPath = Temp;
666313a0c13SJung-uk Kim         if (!Temp)
667313a0c13SJung-uk Kim         {
668313a0c13SJung-uk Kim             return_VOID;
669313a0c13SJung-uk Kim         }
670313a0c13SJung-uk Kim 
671313a0c13SJung-uk Kim         /* Create the new internal pathname */
672313a0c13SJung-uk Kim 
673313a0c13SJung-uk Kim         Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
674313a0c13SJung-uk Kim         Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
675313a0c13SJung-uk Kim         if (ACPI_FAILURE (Status))
676313a0c13SJung-uk Kim         {
677313a0c13SJung-uk Kim             ACPI_FREE (ExternalPath);
678313a0c13SJung-uk Kim             return_VOID;
679313a0c13SJung-uk Kim         }
680313a0c13SJung-uk Kim     }
681313a0c13SJung-uk Kim 
682313a0c13SJung-uk Kim     /* Create the new External() declaration node */
683313a0c13SJung-uk Kim 
684313a0c13SJung-uk Kim     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
685313a0c13SJung-uk Kim         Type, Value, Flags);
686313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
687313a0c13SJung-uk Kim     {
688313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
689313a0c13SJung-uk Kim         if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
690313a0c13SJung-uk Kim         {
691313a0c13SJung-uk Kim             ACPI_FREE (InternalPath);
692313a0c13SJung-uk Kim         }
693313a0c13SJung-uk Kim     }
694313a0c13SJung-uk Kim 
695313a0c13SJung-uk Kim     return_VOID;
696313a0c13SJung-uk Kim }
697313a0c13SJung-uk Kim 
698313a0c13SJung-uk Kim 
699313a0c13SJung-uk Kim /*******************************************************************************
700313a0c13SJung-uk Kim  *
701313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmAddNodeToExternalList
702313a0c13SJung-uk Kim  *
703313a0c13SJung-uk Kim  * PARAMETERS:  Node                - Namespace node for object to be added
704313a0c13SJung-uk Kim  *              Type                - ACPI object type to be added
705313a0c13SJung-uk Kim  *              Value               - Arg count if adding a Method object
706313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
707313a0c13SJung-uk Kim  *
708313a0c13SJung-uk Kim  * RETURN:      None
709313a0c13SJung-uk Kim  *
710313a0c13SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
711313a0c13SJung-uk Kim  *              will in turn be later emitted as an External() declaration
712313a0c13SJung-uk Kim  *              in the disassembled output.
713313a0c13SJung-uk Kim  *
714313a0c13SJung-uk Kim  *              This function handles the case where the referenced name has
715313a0c13SJung-uk Kim  *              been found in the namespace, but the name originated in a
716313a0c13SJung-uk Kim  *              table other than the one that is being disassembled (such
717313a0c13SJung-uk Kim  *              as a table that is added via the iASL -e option).
718313a0c13SJung-uk Kim  *
719313a0c13SJung-uk Kim  ******************************************************************************/
720313a0c13SJung-uk Kim 
721313a0c13SJung-uk Kim void
722313a0c13SJung-uk Kim AcpiDmAddNodeToExternalList (
723313a0c13SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node,
724313a0c13SJung-uk Kim     UINT8                   Type,
725313a0c13SJung-uk Kim     UINT32                  Value,
726313a0c13SJung-uk Kim     UINT16                  Flags)
727313a0c13SJung-uk Kim {
728313a0c13SJung-uk Kim     char                    *ExternalPath;
729313a0c13SJung-uk Kim     char                    *InternalPath;
730313a0c13SJung-uk Kim     char                    *Temp;
731313a0c13SJung-uk Kim     ACPI_STATUS             Status;
732313a0c13SJung-uk Kim 
733313a0c13SJung-uk Kim 
734313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
735313a0c13SJung-uk Kim 
736313a0c13SJung-uk Kim 
737313a0c13SJung-uk Kim     if (!Node)
738313a0c13SJung-uk Kim     {
739313a0c13SJung-uk Kim         return_VOID;
740313a0c13SJung-uk Kim     }
741313a0c13SJung-uk Kim 
742313a0c13SJung-uk Kim     /* Get the full external and internal pathnames to the node */
743313a0c13SJung-uk Kim 
744313a0c13SJung-uk Kim     ExternalPath = AcpiNsGetExternalPathname (Node);
745313a0c13SJung-uk Kim     if (!ExternalPath)
746313a0c13SJung-uk Kim     {
747313a0c13SJung-uk Kim         return_VOID;
748313a0c13SJung-uk Kim     }
749313a0c13SJung-uk Kim 
750313a0c13SJung-uk Kim     Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
751313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
752313a0c13SJung-uk Kim     {
753313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
754313a0c13SJung-uk Kim         return_VOID;
755313a0c13SJung-uk Kim     }
756313a0c13SJung-uk Kim 
757313a0c13SJung-uk Kim     /* Remove the root backslash */
758313a0c13SJung-uk Kim 
759313a0c13SJung-uk Kim     if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1]))
760313a0c13SJung-uk Kim     {
7615ef50723SJung-uk Kim         Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1);
762313a0c13SJung-uk Kim         if (!Temp)
763313a0c13SJung-uk Kim         {
764313a0c13SJung-uk Kim             return_VOID;
765313a0c13SJung-uk Kim         }
766313a0c13SJung-uk Kim 
7675ef50723SJung-uk Kim         strcpy (Temp, &ExternalPath[1]);
768313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
769313a0c13SJung-uk Kim         ExternalPath = Temp;
770313a0c13SJung-uk Kim     }
771313a0c13SJung-uk Kim 
772313a0c13SJung-uk Kim     /* Create the new External() declaration node */
773313a0c13SJung-uk Kim 
774313a0c13SJung-uk Kim     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
775313a0c13SJung-uk Kim         Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
776313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
777313a0c13SJung-uk Kim     {
778313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
779313a0c13SJung-uk Kim         ACPI_FREE (InternalPath);
780313a0c13SJung-uk Kim     }
781313a0c13SJung-uk Kim 
782313a0c13SJung-uk Kim     return_VOID;
783313a0c13SJung-uk Kim }
784313a0c13SJung-uk Kim 
785313a0c13SJung-uk Kim 
786313a0c13SJung-uk Kim /*******************************************************************************
787313a0c13SJung-uk Kim  *
788313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmAddPathToExternalList
789313a0c13SJung-uk Kim  *
790313a0c13SJung-uk Kim  * PARAMETERS:  Path                - External name of the object to be added
791313a0c13SJung-uk Kim  *              Type                - ACPI object type to be added
792313a0c13SJung-uk Kim  *              Value               - Arg count if adding a Method object
793313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
794313a0c13SJung-uk Kim  *
795313a0c13SJung-uk Kim  * RETURN:      None
796313a0c13SJung-uk Kim  *
797313a0c13SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
798313a0c13SJung-uk Kim  *              will in turn be later emitted as an External() declaration
799313a0c13SJung-uk Kim  *              in the disassembled output.
800313a0c13SJung-uk Kim  *
801313a0c13SJung-uk Kim  *              This function currently is used to add externals via a
802313a0c13SJung-uk Kim  *              reference file (via the -fe iASL option).
803313a0c13SJung-uk Kim  *
804313a0c13SJung-uk Kim  ******************************************************************************/
805313a0c13SJung-uk Kim 
806313a0c13SJung-uk Kim static void
807313a0c13SJung-uk Kim AcpiDmAddPathToExternalList (
808313a0c13SJung-uk Kim     char                    *Path,
809313a0c13SJung-uk Kim     UINT8                   Type,
810313a0c13SJung-uk Kim     UINT32                  Value,
811313a0c13SJung-uk Kim     UINT16                  Flags)
812313a0c13SJung-uk Kim {
813313a0c13SJung-uk Kim     char                    *InternalPath;
814313a0c13SJung-uk Kim     char                    *ExternalPath;
815313a0c13SJung-uk Kim     ACPI_STATUS             Status;
816313a0c13SJung-uk Kim 
817313a0c13SJung-uk Kim 
818313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
819313a0c13SJung-uk Kim 
820313a0c13SJung-uk Kim 
821313a0c13SJung-uk Kim     if (!Path)
822313a0c13SJung-uk Kim     {
823313a0c13SJung-uk Kim         return_VOID;
824313a0c13SJung-uk Kim     }
825313a0c13SJung-uk Kim 
826313a0c13SJung-uk Kim     /* Remove a root backslash if present */
827313a0c13SJung-uk Kim 
828313a0c13SJung-uk Kim     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
829313a0c13SJung-uk Kim     {
830313a0c13SJung-uk Kim         Path++;
831313a0c13SJung-uk Kim     }
832313a0c13SJung-uk Kim 
833313a0c13SJung-uk Kim     /* Create the internal and external pathnames */
834313a0c13SJung-uk Kim 
835313a0c13SJung-uk Kim     Status = AcpiNsInternalizeName (Path, &InternalPath);
836313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
837313a0c13SJung-uk Kim     {
838313a0c13SJung-uk Kim         return_VOID;
839313a0c13SJung-uk Kim     }
840313a0c13SJung-uk Kim 
841313a0c13SJung-uk Kim     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
842313a0c13SJung-uk Kim         NULL, &ExternalPath);
843313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
844313a0c13SJung-uk Kim     {
845313a0c13SJung-uk Kim         ACPI_FREE (InternalPath);
846313a0c13SJung-uk Kim         return_VOID;
847313a0c13SJung-uk Kim     }
848313a0c13SJung-uk Kim 
849313a0c13SJung-uk Kim     /* Create the new External() declaration node */
850313a0c13SJung-uk Kim 
851313a0c13SJung-uk Kim     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
852313a0c13SJung-uk Kim         Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
853313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
854313a0c13SJung-uk Kim     {
855313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
856313a0c13SJung-uk Kim         ACPI_FREE (InternalPath);
857313a0c13SJung-uk Kim     }
858313a0c13SJung-uk Kim 
859313a0c13SJung-uk Kim     return_VOID;
860313a0c13SJung-uk Kim }
861313a0c13SJung-uk Kim 
862313a0c13SJung-uk Kim 
863313a0c13SJung-uk Kim /*******************************************************************************
864313a0c13SJung-uk Kim  *
865313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmCreateNewExternal
866313a0c13SJung-uk Kim  *
867313a0c13SJung-uk Kim  * PARAMETERS:  ExternalPath        - External path to the object
868313a0c13SJung-uk Kim  *              InternalPath        - Internal (AML) path to the object
869313a0c13SJung-uk Kim  *              Type                - ACPI object type to be added
870313a0c13SJung-uk Kim  *              Value               - Arg count if adding a Method object
871313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
872313a0c13SJung-uk Kim  *
873313a0c13SJung-uk Kim  * RETURN:      Status
874313a0c13SJung-uk Kim  *
875313a0c13SJung-uk Kim  * DESCRIPTION: Common low-level function to insert a new name into the global
876313a0c13SJung-uk Kim  *              list of Externals which will in turn be later emitted as
877313a0c13SJung-uk Kim  *              External() declarations in the disassembled output.
878313a0c13SJung-uk Kim  *
879313a0c13SJung-uk Kim  *              Note: The external name should not include a root prefix
880313a0c13SJung-uk Kim  *              (backslash). We do not want External() statements to contain
881313a0c13SJung-uk Kim  *              a leading '\', as this prevents duplicate external statements
882313a0c13SJung-uk Kim  *              of the form:
88379c6d946SJung-uk Kim  *
88479c6d946SJung-uk Kim  *                  External (\ABCD)
88579c6d946SJung-uk Kim  *                  External (ABCD)
88679c6d946SJung-uk Kim  *
88779c6d946SJung-uk Kim  *              This would cause a compile time error when the disassembled
88879c6d946SJung-uk Kim  *              output file is recompiled.
889313a0c13SJung-uk Kim  *
890313a0c13SJung-uk Kim  *              There are two cases that are handled here. For both, we emit
891313a0c13SJung-uk Kim  *              an External() statement:
892313a0c13SJung-uk Kim  *              1) The name was simply not found in the namespace.
893313a0c13SJung-uk Kim  *              2) The name was found, but it originated in a table other than
894313a0c13SJung-uk Kim  *              the table that is being disassembled.
895313a0c13SJung-uk Kim  *
896313a0c13SJung-uk Kim  ******************************************************************************/
897313a0c13SJung-uk Kim 
898313a0c13SJung-uk Kim static ACPI_STATUS
899313a0c13SJung-uk Kim AcpiDmCreateNewExternal (
900313a0c13SJung-uk Kim     char                    *ExternalPath,
901313a0c13SJung-uk Kim     char                    *InternalPath,
902313a0c13SJung-uk Kim     UINT8                   Type,
903313a0c13SJung-uk Kim     UINT32                  Value,
904313a0c13SJung-uk Kim     UINT16                  Flags)
90579c6d946SJung-uk Kim {
906313a0c13SJung-uk Kim     ACPI_EXTERNAL_LIST      *NewExternal;
907313a0c13SJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
908313a0c13SJung-uk Kim     ACPI_EXTERNAL_LIST      *PrevExternal = NULL;
909313a0c13SJung-uk Kim 
910313a0c13SJung-uk Kim 
911313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmCreateNewExternal);
912313a0c13SJung-uk Kim 
91379c6d946SJung-uk Kim 
91479c6d946SJung-uk Kim     /* Check all existing externals to ensure no duplicates */
91579c6d946SJung-uk Kim 
91679c6d946SJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
91779c6d946SJung-uk Kim     while (NextExternal)
91879c6d946SJung-uk Kim     {
919f8146b88SJung-uk Kim         /* Check for duplicates */
920f8146b88SJung-uk Kim 
9215ef50723SJung-uk Kim         if (!strcmp (ExternalPath, NextExternal->Path))
92279c6d946SJung-uk Kim         {
923f8146b88SJung-uk Kim             /*
924f8146b88SJung-uk Kim              * If this external came from an External() opcode, we are
925f8146b88SJung-uk Kim              * finished with this one. (No need to check any further).
926f8146b88SJung-uk Kim              */
927f8146b88SJung-uk Kim             if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
92879c6d946SJung-uk Kim             {
929f8146b88SJung-uk Kim                 return_ACPI_STATUS (AE_ALREADY_EXISTS);
93079c6d946SJung-uk Kim             }
93179c6d946SJung-uk Kim 
93279c6d946SJung-uk Kim             /* Allow upgrade of type from ANY */
93379c6d946SJung-uk Kim 
934f8146b88SJung-uk Kim             else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
935f8146b88SJung-uk Kim                 (Type != ACPI_TYPE_ANY))
93679c6d946SJung-uk Kim             {
93779c6d946SJung-uk Kim                 NextExternal->Type = Type;
938f8146b88SJung-uk Kim             }
939f8146b88SJung-uk Kim 
940f8146b88SJung-uk Kim             /* Update the argument count as necessary */
941f8146b88SJung-uk Kim 
942f8146b88SJung-uk Kim             if (Value < NextExternal->Value)
943f8146b88SJung-uk Kim             {
94479c6d946SJung-uk Kim                 NextExternal->Value = Value;
94579c6d946SJung-uk Kim             }
94679c6d946SJung-uk Kim 
947f8146b88SJung-uk Kim             /* Update flags. */
948f8146b88SJung-uk Kim 
949f8146b88SJung-uk Kim             NextExternal->Flags |= Flags;
950f8146b88SJung-uk Kim             NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
951f8146b88SJung-uk Kim 
952313a0c13SJung-uk Kim             return_ACPI_STATUS (AE_ALREADY_EXISTS);
95379c6d946SJung-uk Kim         }
95479c6d946SJung-uk Kim 
95579c6d946SJung-uk Kim         NextExternal = NextExternal->Next;
95679c6d946SJung-uk Kim     }
95779c6d946SJung-uk Kim 
95879c6d946SJung-uk Kim     /* Allocate and init a new External() descriptor */
95979c6d946SJung-uk Kim 
96079c6d946SJung-uk Kim     NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
96179c6d946SJung-uk Kim     if (!NewExternal)
96279c6d946SJung-uk Kim     {
963313a0c13SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
96479c6d946SJung-uk Kim     }
96579c6d946SJung-uk Kim 
966313a0c13SJung-uk Kim     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
967313a0c13SJung-uk Kim         "Adding external reference node (%s) type [%s]\n",
968313a0c13SJung-uk Kim         ExternalPath, AcpiUtGetTypeName (Type)));
96979c6d946SJung-uk Kim 
970313a0c13SJung-uk Kim     NewExternal->Flags = Flags;
971313a0c13SJung-uk Kim     NewExternal->Value = Value;
97279c6d946SJung-uk Kim     NewExternal->Path = ExternalPath;
97379c6d946SJung-uk Kim     NewExternal->Type = Type;
9745ef50723SJung-uk Kim     NewExternal->Length = (UINT16) strlen (ExternalPath);
97579c6d946SJung-uk Kim     NewExternal->InternalPath = InternalPath;
97679c6d946SJung-uk Kim 
97779c6d946SJung-uk Kim     /* Link the new descriptor into the global list, alphabetically ordered */
97879c6d946SJung-uk Kim 
97979c6d946SJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
98079c6d946SJung-uk Kim     while (NextExternal)
98179c6d946SJung-uk Kim     {
98279c6d946SJung-uk Kim         if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
98379c6d946SJung-uk Kim         {
98479c6d946SJung-uk Kim             if (PrevExternal)
98579c6d946SJung-uk Kim             {
98679c6d946SJung-uk Kim                 PrevExternal->Next = NewExternal;
98779c6d946SJung-uk Kim             }
98879c6d946SJung-uk Kim             else
98979c6d946SJung-uk Kim             {
99079c6d946SJung-uk Kim                 AcpiGbl_ExternalList = NewExternal;
99179c6d946SJung-uk Kim             }
99279c6d946SJung-uk Kim 
99379c6d946SJung-uk Kim             NewExternal->Next = NextExternal;
994313a0c13SJung-uk Kim             return_ACPI_STATUS (AE_OK);
99579c6d946SJung-uk Kim         }
99679c6d946SJung-uk Kim 
99779c6d946SJung-uk Kim         PrevExternal = NextExternal;
99879c6d946SJung-uk Kim         NextExternal = NextExternal->Next;
99979c6d946SJung-uk Kim     }
100079c6d946SJung-uk Kim 
100179c6d946SJung-uk Kim     if (PrevExternal)
100279c6d946SJung-uk Kim     {
100379c6d946SJung-uk Kim         PrevExternal->Next = NewExternal;
100479c6d946SJung-uk Kim     }
100579c6d946SJung-uk Kim     else
100679c6d946SJung-uk Kim     {
100779c6d946SJung-uk Kim         AcpiGbl_ExternalList = NewExternal;
100879c6d946SJung-uk Kim     }
1009313a0c13SJung-uk Kim 
1010313a0c13SJung-uk Kim     return_ACPI_STATUS (AE_OK);
101179c6d946SJung-uk Kim }
101279c6d946SJung-uk Kim 
101379c6d946SJung-uk Kim 
101479c6d946SJung-uk Kim /*******************************************************************************
101579c6d946SJung-uk Kim  *
1016f556842eSJung-uk Kim  * FUNCTION:    AcpiDmAddExternalsToNamespace
1017f556842eSJung-uk Kim  *
1018f556842eSJung-uk Kim  * PARAMETERS:  None
1019f556842eSJung-uk Kim  *
1020f556842eSJung-uk Kim  * RETURN:      None
1021f556842eSJung-uk Kim  *
1022f556842eSJung-uk Kim  * DESCRIPTION: Add all externals to the namespace. Allows externals to be
1023f556842eSJung-uk Kim  *              "resolved".
1024f556842eSJung-uk Kim  *
1025f556842eSJung-uk Kim  ******************************************************************************/
1026f556842eSJung-uk Kim 
1027f556842eSJung-uk Kim void
1028f556842eSJung-uk Kim AcpiDmAddExternalsToNamespace (
1029f556842eSJung-uk Kim     void)
1030f556842eSJung-uk Kim {
1031f556842eSJung-uk Kim     ACPI_STATUS             Status;
1032f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
1033a7a3b383SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
1034f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
1035f556842eSJung-uk Kim 
1036f556842eSJung-uk Kim 
1037f556842eSJung-uk Kim     while (External)
1038f556842eSJung-uk Kim     {
1039f556842eSJung-uk Kim         /* Add the external name (object) into the namespace */
1040f556842eSJung-uk Kim 
1041f556842eSJung-uk Kim         Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
1042f556842eSJung-uk Kim             ACPI_IMODE_LOAD_PASS1,
104379c6d946SJung-uk Kim             ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
1044f556842eSJung-uk Kim             NULL, &Node);
1045f556842eSJung-uk Kim 
1046f556842eSJung-uk Kim         if (ACPI_FAILURE (Status))
1047f556842eSJung-uk Kim         {
1048f556842eSJung-uk Kim             ACPI_EXCEPTION ((AE_INFO, Status,
1049f556842eSJung-uk Kim                 "while adding external to namespace [%s]",
1050f556842eSJung-uk Kim                 External->Path));
1051f556842eSJung-uk Kim         }
1052a7a3b383SJung-uk Kim 
1053a7a3b383SJung-uk Kim         else switch (External->Type)
1054f556842eSJung-uk Kim         {
1055a7a3b383SJung-uk Kim         case ACPI_TYPE_METHOD:
1056a7a3b383SJung-uk Kim 
1057f556842eSJung-uk Kim             /* For methods, we need to save the argument count */
1058f556842eSJung-uk Kim 
1059a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
1060a7a3b383SJung-uk Kim             ObjDesc->Method.ParamCount = (UINT8) External->Value;
1061a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
1062a7a3b383SJung-uk Kim             break;
1063a7a3b383SJung-uk Kim 
1064a7a3b383SJung-uk Kim         case ACPI_TYPE_REGION:
1065a7a3b383SJung-uk Kim 
1066a7a3b383SJung-uk Kim             /* Regions require a region sub-object */
1067a7a3b383SJung-uk Kim 
1068a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
1069a7a3b383SJung-uk Kim             ObjDesc->Region.Node = Node;
1070a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
1071a7a3b383SJung-uk Kim             break;
1072a7a3b383SJung-uk Kim 
1073a7a3b383SJung-uk Kim         default:
1074a9d8d09cSJung-uk Kim 
1075a7a3b383SJung-uk Kim             break;
1076f556842eSJung-uk Kim         }
1077f556842eSJung-uk Kim 
1078f556842eSJung-uk Kim         External = External->Next;
1079f556842eSJung-uk Kim     }
1080f556842eSJung-uk Kim }
1081f556842eSJung-uk Kim 
1082f556842eSJung-uk Kim 
1083f556842eSJung-uk Kim /*******************************************************************************
1084f556842eSJung-uk Kim  *
1085f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetExternalMethodCount
1086f556842eSJung-uk Kim  *
1087f556842eSJung-uk Kim  * PARAMETERS:  None
1088f556842eSJung-uk Kim  *
1089f556842eSJung-uk Kim  * RETURN:      The number of control method externals in the external list
1090f556842eSJung-uk Kim  *
1091f556842eSJung-uk Kim  * DESCRIPTION: Return the number of method externals that have been generated.
1092f556842eSJung-uk Kim  *              If any control method externals have been found, we must
1093f556842eSJung-uk Kim  *              re-parse the entire definition block with the new information
1094f556842eSJung-uk Kim  *              (number of arguments for the methods.) This is limitation of
1095f556842eSJung-uk Kim  *              AML, we don't know the number of arguments from the control
1096f556842eSJung-uk Kim  *              method invocation itself.
1097f556842eSJung-uk Kim  *
1098f556842eSJung-uk Kim  ******************************************************************************/
1099f556842eSJung-uk Kim 
1100f556842eSJung-uk Kim UINT32
1101f556842eSJung-uk Kim AcpiDmGetExternalMethodCount (
1102f556842eSJung-uk Kim     void)
1103f556842eSJung-uk Kim {
1104f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
1105f556842eSJung-uk Kim     UINT32                  Count = 0;
1106f556842eSJung-uk Kim 
1107f556842eSJung-uk Kim 
1108f556842eSJung-uk Kim     while (External)
1109f556842eSJung-uk Kim     {
1110f556842eSJung-uk Kim         if (External->Type == ACPI_TYPE_METHOD)
1111f556842eSJung-uk Kim         {
1112f556842eSJung-uk Kim             Count++;
1113f556842eSJung-uk Kim         }
1114f556842eSJung-uk Kim 
1115f556842eSJung-uk Kim         External = External->Next;
1116f556842eSJung-uk Kim     }
1117f556842eSJung-uk Kim 
1118f556842eSJung-uk Kim     return (Count);
1119f556842eSJung-uk Kim }
1120f556842eSJung-uk Kim 
1121f556842eSJung-uk Kim 
1122f556842eSJung-uk Kim /*******************************************************************************
1123f556842eSJung-uk Kim  *
1124f556842eSJung-uk Kim  * FUNCTION:    AcpiDmClearExternalList
1125f556842eSJung-uk Kim  *
1126f556842eSJung-uk Kim  * PARAMETERS:  None
1127f556842eSJung-uk Kim  *
1128f556842eSJung-uk Kim  * RETURN:      None
1129f556842eSJung-uk Kim  *
1130f556842eSJung-uk Kim  * DESCRIPTION: Free the entire External info list
1131f556842eSJung-uk Kim  *
1132f556842eSJung-uk Kim  ******************************************************************************/
1133f556842eSJung-uk Kim 
1134f556842eSJung-uk Kim void
1135f556842eSJung-uk Kim AcpiDmClearExternalList (
1136f556842eSJung-uk Kim     void)
1137f556842eSJung-uk Kim {
1138f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
1139f556842eSJung-uk Kim 
1140f556842eSJung-uk Kim 
1141f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
1142f556842eSJung-uk Kim     {
1143f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
1144f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
1145f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
1146f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
1147f556842eSJung-uk Kim     }
1148f556842eSJung-uk Kim }
1149f556842eSJung-uk Kim 
1150f556842eSJung-uk Kim 
1151f556842eSJung-uk Kim /*******************************************************************************
1152f556842eSJung-uk Kim  *
1153f556842eSJung-uk Kim  * FUNCTION:    AcpiDmEmitExternals
1154f556842eSJung-uk Kim  *
1155f556842eSJung-uk Kim  * PARAMETERS:  None
1156f556842eSJung-uk Kim  *
1157f556842eSJung-uk Kim  * RETURN:      None
1158f556842eSJung-uk Kim  *
1159f556842eSJung-uk Kim  * DESCRIPTION: Emit an External() ASL statement for each of the externals in
1160f556842eSJung-uk Kim  *              the global external info list.
1161f556842eSJung-uk Kim  *
1162f556842eSJung-uk Kim  ******************************************************************************/
1163f556842eSJung-uk Kim 
1164f556842eSJung-uk Kim void
1165f556842eSJung-uk Kim AcpiDmEmitExternals (
1166f556842eSJung-uk Kim     void)
1167f556842eSJung-uk Kim {
1168f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
1169f556842eSJung-uk Kim 
1170f556842eSJung-uk Kim 
1171f556842eSJung-uk Kim     if (!AcpiGbl_ExternalList)
1172f556842eSJung-uk Kim     {
1173f556842eSJung-uk Kim         return;
1174f556842eSJung-uk Kim     }
1175f556842eSJung-uk Kim 
1176f556842eSJung-uk Kim     /*
11779c48c75eSJung-uk Kim      * Determine the number of control methods in the external list, and
11789c48c75eSJung-uk Kim      * also how many of those externals were resolved via the namespace.
11799c48c75eSJung-uk Kim      */
11809c48c75eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
11819c48c75eSJung-uk Kim     while (NextExternal)
11829c48c75eSJung-uk Kim     {
11839c48c75eSJung-uk Kim         if (NextExternal->Type == ACPI_TYPE_METHOD)
11849c48c75eSJung-uk Kim         {
11859c48c75eSJung-uk Kim             AcpiGbl_NumExternalMethods++;
1186313a0c13SJung-uk Kim             if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
11879c48c75eSJung-uk Kim             {
11889c48c75eSJung-uk Kim                 AcpiGbl_ResolvedExternalMethods++;
11899c48c75eSJung-uk Kim             }
11909c48c75eSJung-uk Kim         }
11919c48c75eSJung-uk Kim 
11929c48c75eSJung-uk Kim         NextExternal = NextExternal->Next;
11939c48c75eSJung-uk Kim     }
11949c48c75eSJung-uk Kim 
11959c48c75eSJung-uk Kim     /* Check if any control methods were unresolved */
11969c48c75eSJung-uk Kim 
11979c48c75eSJung-uk Kim     AcpiDmUnresolvedWarning (1);
11989c48c75eSJung-uk Kim 
119979c6d946SJung-uk Kim     if (Gbl_ExternalRefFilename)
120079c6d946SJung-uk Kim     {
120179c6d946SJung-uk Kim         AcpiOsPrintf (
1202f8146b88SJung-uk Kim             "    /*\n     * External declarations were imported from\n"
1203f8146b88SJung-uk Kim             "     * a reference file -- %s\n     */\n\n",
120479c6d946SJung-uk Kim             Gbl_ExternalRefFilename);
120579c6d946SJung-uk Kim     }
120679c6d946SJung-uk Kim 
12079c48c75eSJung-uk Kim     /*
1208f8146b88SJung-uk Kim      * Walk and emit the list of externals found during the AML parsing
1209f556842eSJung-uk Kim      */
1210f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
1211f556842eSJung-uk Kim     {
1212313a0c13SJung-uk Kim         if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
1213bf6fac21SJung-uk Kim         {
1214f8146b88SJung-uk Kim             AcpiOsPrintf ("    External (%s%s)",
1215f556842eSJung-uk Kim                 AcpiGbl_ExternalList->Path,
1216f556842eSJung-uk Kim                 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
1217f556842eSJung-uk Kim 
1218f8146b88SJung-uk Kim             /* Check for "unresolved" method reference */
1219f8146b88SJung-uk Kim 
1220f8146b88SJung-uk Kim             if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
1221f8146b88SJung-uk Kim                 (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
1222f8146b88SJung-uk Kim             {
1223f8146b88SJung-uk Kim                 AcpiOsPrintf ("    // Warning: Unknown method, "
1224f8146b88SJung-uk Kim                     "guessing %u arguments",
1225f8146b88SJung-uk Kim                     AcpiGbl_ExternalList->Value);
1226f8146b88SJung-uk Kim             }
1227f8146b88SJung-uk Kim 
1228f8146b88SJung-uk Kim             /* Check for external from a external references file */
1229f8146b88SJung-uk Kim 
1230f8146b88SJung-uk Kim             else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
1231f8146b88SJung-uk Kim             {
1232f8146b88SJung-uk Kim                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1233f8146b88SJung-uk Kim                 {
1234f8146b88SJung-uk Kim                     AcpiOsPrintf ("    // %u Arguments",
1235f8146b88SJung-uk Kim                         AcpiGbl_ExternalList->Value);
1236f8146b88SJung-uk Kim                 }
1237f8146b88SJung-uk Kim 
1238f8146b88SJung-uk Kim                 AcpiOsPrintf ("    // From external reference file");
1239f8146b88SJung-uk Kim             }
1240f8146b88SJung-uk Kim 
1241f8146b88SJung-uk Kim             /* This is the normal external case */
1242f8146b88SJung-uk Kim 
1243f8146b88SJung-uk Kim             else
1244f8146b88SJung-uk Kim             {
1245bf6fac21SJung-uk Kim                 /* For methods, add a comment with the number of arguments */
1246bf6fac21SJung-uk Kim 
1247f556842eSJung-uk Kim                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1248f556842eSJung-uk Kim                 {
1249f8146b88SJung-uk Kim                     AcpiOsPrintf ("    // %u Arguments",
1250f556842eSJung-uk Kim                         AcpiGbl_ExternalList->Value);
1251f556842eSJung-uk Kim                 }
1252f556842eSJung-uk Kim             }
1253f8146b88SJung-uk Kim 
1254f8146b88SJung-uk Kim             AcpiOsPrintf ("\n");
1255bf6fac21SJung-uk Kim         }
1256f556842eSJung-uk Kim 
1257f556842eSJung-uk Kim         /* Free this external info block and move on to next external */
1258f556842eSJung-uk Kim 
1259f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
1260313a0c13SJung-uk Kim         if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
1261f556842eSJung-uk Kim         {
1262f556842eSJung-uk Kim             ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
1263f556842eSJung-uk Kim         }
1264f556842eSJung-uk Kim 
1265f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
1266f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
1267f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
1268f556842eSJung-uk Kim     }
1269f556842eSJung-uk Kim 
1270f556842eSJung-uk Kim     AcpiOsPrintf ("\n");
1271f556842eSJung-uk Kim }
12729c48c75eSJung-uk Kim 
12739c48c75eSJung-uk Kim 
12749c48c75eSJung-uk Kim /*******************************************************************************
12759c48c75eSJung-uk Kim  *
1276*0d84335fSJung-uk Kim  * FUNCTION:    AcpiDmEmitExternal
1277*0d84335fSJung-uk Kim  *
1278*0d84335fSJung-uk Kim  * PARAMETERS:  Op                  External Parse Object
1279*0d84335fSJung-uk Kim  *
1280*0d84335fSJung-uk Kim  * RETURN:      None
1281*0d84335fSJung-uk Kim  *
1282*0d84335fSJung-uk Kim  * DESCRIPTION: Emit an External() ASL statement for the current External
1283*0d84335fSJung-uk Kim  *              parse object
1284*0d84335fSJung-uk Kim  *
1285*0d84335fSJung-uk Kim  ******************************************************************************/
1286*0d84335fSJung-uk Kim 
1287*0d84335fSJung-uk Kim void
1288*0d84335fSJung-uk Kim AcpiDmEmitExternal (
1289*0d84335fSJung-uk Kim     ACPI_PARSE_OBJECT       *NameOp,
1290*0d84335fSJung-uk Kim     ACPI_PARSE_OBJECT       *TypeOp)
1291*0d84335fSJung-uk Kim {
1292*0d84335fSJung-uk Kim     AcpiOsPrintf ("External (");
1293*0d84335fSJung-uk Kim     AcpiDmNamestring (NameOp->Common.Value.Name);
1294*0d84335fSJung-uk Kim     AcpiOsPrintf ("%s)\n",
1295*0d84335fSJung-uk Kim         AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));
1296*0d84335fSJung-uk Kim }
1297*0d84335fSJung-uk Kim 
1298*0d84335fSJung-uk Kim 
1299*0d84335fSJung-uk Kim /*******************************************************************************
1300*0d84335fSJung-uk Kim  *
13019c48c75eSJung-uk Kim  * FUNCTION:    AcpiDmUnresolvedWarning
13029c48c75eSJung-uk Kim  *
13039c48c75eSJung-uk Kim  * PARAMETERS:  Type                - Where to output the warning.
13049c48c75eSJung-uk Kim  *                                    0 means write to stderr
13059c48c75eSJung-uk Kim  *                                    1 means write to AcpiOsPrintf
13069c48c75eSJung-uk Kim  *
13079c48c75eSJung-uk Kim  * RETURN:      None
13089c48c75eSJung-uk Kim  *
13099c48c75eSJung-uk Kim  * DESCRIPTION: Issue warning message if there are unresolved external control
13109c48c75eSJung-uk Kim  *              methods within the disassembly.
13119c48c75eSJung-uk Kim  *
13129c48c75eSJung-uk Kim  ******************************************************************************/
13139c48c75eSJung-uk Kim 
13149c48c75eSJung-uk Kim #if 0
13159c48c75eSJung-uk Kim Summary of the external control method problem:
13169c48c75eSJung-uk Kim 
13179c48c75eSJung-uk Kim When the -e option is used with disassembly, the various SSDTs are simply
13189c48c75eSJung-uk Kim loaded into a global namespace for the disassembler to use in order to
13199c48c75eSJung-uk Kim resolve control method references (invocations).
13209c48c75eSJung-uk Kim 
13219c48c75eSJung-uk Kim The disassembler tracks any such references, and will emit an External()
13229c48c75eSJung-uk Kim statement for these types of methods, with the proper number of arguments .
13239c48c75eSJung-uk Kim 
13249c48c75eSJung-uk Kim Without the SSDTs, the AML does not contain enough information to properly
13259c48c75eSJung-uk Kim disassemble the control method invocation -- because the disassembler does
13269c48c75eSJung-uk Kim not know how many arguments to parse.
13279c48c75eSJung-uk Kim 
13289c48c75eSJung-uk Kim An example: Assume we have two control methods. ABCD has one argument, and
13299c48c75eSJung-uk Kim EFGH has zero arguments. Further, we have two additional control methods
13309c48c75eSJung-uk Kim that invoke ABCD and EFGH, named T1 and T2:
13319c48c75eSJung-uk Kim 
13329c48c75eSJung-uk Kim     Method (ABCD, 1)
13339c48c75eSJung-uk Kim     {
13349c48c75eSJung-uk Kim     }
13359c48c75eSJung-uk Kim     Method (EFGH, 0)
13369c48c75eSJung-uk Kim     {
13379c48c75eSJung-uk Kim     }
13389c48c75eSJung-uk Kim     Method (T1)
13399c48c75eSJung-uk Kim     {
13409c48c75eSJung-uk Kim         ABCD (Add (2, 7, Local0))
13419c48c75eSJung-uk Kim     }
13429c48c75eSJung-uk Kim     Method (T2)
13439c48c75eSJung-uk Kim     {
13449c48c75eSJung-uk Kim         EFGH ()
13459c48c75eSJung-uk Kim         Add (2, 7, Local0)
13469c48c75eSJung-uk Kim     }
13479c48c75eSJung-uk Kim 
13489c48c75eSJung-uk Kim Here is the AML code that is generated for T1 and T2:
13499c48c75eSJung-uk Kim 
13509c48c75eSJung-uk Kim      185:      Method (T1)
13519c48c75eSJung-uk Kim 
13529c48c75eSJung-uk Kim 0000034C:  14 10 54 31 5F 5F 00 ...    "..T1__."
13539c48c75eSJung-uk Kim 
13549c48c75eSJung-uk Kim      186:      {
13559c48c75eSJung-uk Kim      187:          ABCD (Add (2, 7, Local0))
13569c48c75eSJung-uk Kim 
13579c48c75eSJung-uk Kim 00000353:  41 42 43 44 ............    "ABCD"
13589c48c75eSJung-uk Kim 00000357:  72 0A 02 0A 07 60 ......    "r....`"
13599c48c75eSJung-uk Kim 
13609c48c75eSJung-uk Kim      188:      }
13619c48c75eSJung-uk Kim 
13629c48c75eSJung-uk Kim      190:      Method (T2)
13639c48c75eSJung-uk Kim 
13649c48c75eSJung-uk Kim 0000035D:  14 10 54 32 5F 5F 00 ...    "..T2__."
13659c48c75eSJung-uk Kim 
13669c48c75eSJung-uk Kim      191:      {
13679c48c75eSJung-uk Kim      192:          EFGH ()
13689c48c75eSJung-uk Kim 
13699c48c75eSJung-uk Kim 00000364:  45 46 47 48 ............    "EFGH"
13709c48c75eSJung-uk Kim 
13719c48c75eSJung-uk Kim      193:          Add (2, 7, Local0)
13729c48c75eSJung-uk Kim 
13739c48c75eSJung-uk Kim 00000368:  72 0A 02 0A 07 60 ......    "r....`"
13749c48c75eSJung-uk Kim      194:      }
13759c48c75eSJung-uk Kim 
13769c48c75eSJung-uk Kim Note that the AML code for T1 and T2 is essentially identical. When
13779c48c75eSJung-uk Kim disassembling this code, the methods ABCD and EFGH must be known to the
13789c48c75eSJung-uk Kim disassembler, otherwise it does not know how to handle the method invocations.
13799c48c75eSJung-uk Kim 
13809c48c75eSJung-uk Kim In other words, if ABCD and EFGH are actually external control methods
13819c48c75eSJung-uk Kim appearing in an SSDT, the disassembler does not know what to do unless
13829c48c75eSJung-uk Kim the owning SSDT has been loaded via the -e option.
13839c48c75eSJung-uk Kim #endif
13849c48c75eSJung-uk Kim 
1385f8146b88SJung-uk Kim static char             ExternalWarningPart1[600];
1386f8146b88SJung-uk Kim static char             ExternalWarningPart2[400];
1387f8146b88SJung-uk Kim static char             ExternalWarningPart3[400];
1388f8146b88SJung-uk Kim static char             ExternalWarningPart4[200];
1389f8146b88SJung-uk Kim 
13909c48c75eSJung-uk Kim void
13919c48c75eSJung-uk Kim AcpiDmUnresolvedWarning (
13929c48c75eSJung-uk Kim     UINT8                   Type)
13939c48c75eSJung-uk Kim {
1394f8146b88SJung-uk Kim     char                    *Format;
1395f8146b88SJung-uk Kim     char                    Pad[] = "     *";
1396f8146b88SJung-uk Kim     char                    NoPad[] = "";
1397f8146b88SJung-uk Kim 
13989c48c75eSJung-uk Kim 
13999c48c75eSJung-uk Kim     if (!AcpiGbl_NumExternalMethods)
14009c48c75eSJung-uk Kim     {
14019c48c75eSJung-uk Kim         return;
14029c48c75eSJung-uk Kim     }
14039c48c75eSJung-uk Kim 
1404f8146b88SJung-uk Kim     if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
1405f8146b88SJung-uk Kim     {
1406f8146b88SJung-uk Kim         return;
1407f8146b88SJung-uk Kim     }
1408f8146b88SJung-uk Kim 
1409f8146b88SJung-uk Kim     Format = Type ? Pad : NoPad;
1410f8146b88SJung-uk Kim 
1411f8146b88SJung-uk Kim     sprintf (ExternalWarningPart1,
1412f8146b88SJung-uk Kim         "%s iASL Warning: There %s %u external control method%s found during\n"
1413f8146b88SJung-uk Kim         "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1414f8146b88SJung-uk Kim         "%s ACPI tables may be required to properly disassemble the code. This\n"
1415f8146b88SJung-uk Kim         "%s resulting disassembler output file may not compile because the\n"
1416f8146b88SJung-uk Kim         "%s disassembler did not know how many arguments to assign to the\n"
1417f8146b88SJung-uk Kim         "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
1418f8146b88SJung-uk Kim         "%s runtime and may or may not be available via the host OS.\n",
1419f8146b88SJung-uk Kim         Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
1420f8146b88SJung-uk Kim         AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
1421f8146b88SJung-uk Kim         Format, AcpiGbl_ResolvedExternalMethods,
1422f8146b88SJung-uk Kim         (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
1423f8146b88SJung-uk Kim         (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
1424f8146b88SJung-uk Kim         Format, Format, Format, Format, Format);
1425f8146b88SJung-uk Kim 
1426f8146b88SJung-uk Kim     sprintf (ExternalWarningPart2,
1427f8146b88SJung-uk Kim         "%s To specify the tables needed to resolve external control method\n"
1428f8146b88SJung-uk Kim         "%s references, the -e option can be used to specify the filenames.\n"
1429f8146b88SJung-uk Kim         "%s Example iASL invocations:\n"
1430f8146b88SJung-uk Kim         "%s     iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
1431f8146b88SJung-uk Kim         "%s     iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
1432f8146b88SJung-uk Kim         "%s     iasl -e ssdt*.aml -d dsdt.aml\n",
1433f8146b88SJung-uk Kim         Format, Format, Format, Format, Format, Format);
1434f8146b88SJung-uk Kim 
1435f8146b88SJung-uk Kim     sprintf (ExternalWarningPart3,
1436f8146b88SJung-uk Kim         "%s In addition, the -fe option can be used to specify a file containing\n"
1437f8146b88SJung-uk Kim         "%s control method external declarations with the associated method\n"
1438f8146b88SJung-uk Kim         "%s argument counts. Each line of the file must be of the form:\n"
1439f8146b88SJung-uk Kim         "%s     External (<method pathname>, MethodObj, <argument count>)\n"
1440f8146b88SJung-uk Kim         "%s Invocation:\n"
1441f8146b88SJung-uk Kim         "%s     iasl -fe refs.txt -d dsdt.aml\n",
1442f8146b88SJung-uk Kim         Format, Format, Format, Format, Format, Format);
1443f8146b88SJung-uk Kim 
1444f8146b88SJung-uk Kim     sprintf (ExternalWarningPart4,
1445f8146b88SJung-uk Kim         "%s The following methods were unresolved and many not compile properly\n"
1446f8146b88SJung-uk Kim         "%s because the disassembler had to guess at the number of arguments\n"
1447f8146b88SJung-uk Kim         "%s required for each:\n",
1448f8146b88SJung-uk Kim         Format, Format, Format);
1449f8146b88SJung-uk Kim 
14509c48c75eSJung-uk Kim     if (Type)
14519c48c75eSJung-uk Kim     {
14529c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
14539c48c75eSJung-uk Kim         {
14549c48c75eSJung-uk Kim             /* The -e option was not specified */
14559c48c75eSJung-uk Kim 
1456f8146b88SJung-uk Kim            AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     *\n%s     */\n",
1457f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
1458f8146b88SJung-uk Kim                ExternalWarningPart4);
14599c48c75eSJung-uk Kim         }
1460f8146b88SJung-uk Kim         else
14619c48c75eSJung-uk Kim         {
14629c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
14639c48c75eSJung-uk Kim 
1464f8146b88SJung-uk Kim             AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     */\n",
1465f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
14669c48c75eSJung-uk Kim         }
14679c48c75eSJung-uk Kim     }
14689c48c75eSJung-uk Kim     else
14699c48c75eSJung-uk Kim     {
14709c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
14719c48c75eSJung-uk Kim         {
14729c48c75eSJung-uk Kim             /* The -e option was not specified */
14739c48c75eSJung-uk Kim 
1474f8146b88SJung-uk Kim             fprintf (stderr, "\n%s\n%s\n%s\n",
1475f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
14769c48c75eSJung-uk Kim         }
1477f8146b88SJung-uk Kim         else
14789c48c75eSJung-uk Kim         {
14799c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
14809c48c75eSJung-uk Kim 
1481f8146b88SJung-uk Kim             fprintf (stderr, "\n%s\n%s\n",
1482f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart3);
14839c48c75eSJung-uk Kim         }
14849c48c75eSJung-uk Kim     }
14859c48c75eSJung-uk Kim }
1486