xref: /illumos-gate/usr/src/cmd/acpi/common/dmextern.c (revision 35786f68)
1bc36eafdSMike Gerdts /******************************************************************************
2bc36eafdSMike Gerdts  *
3bc36eafdSMike Gerdts  * Module Name: dmextern - Support for External() ASL statements
4bc36eafdSMike Gerdts  *
5bc36eafdSMike Gerdts  *****************************************************************************/
6bc36eafdSMike Gerdts 
7*35786f68SRobert Mustacchi /******************************************************************************
8*35786f68SRobert Mustacchi  *
9*35786f68SRobert Mustacchi  * 1. Copyright Notice
10*35786f68SRobert Mustacchi  *
11*35786f68SRobert Mustacchi  * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
12bc36eafdSMike Gerdts  * All rights reserved.
13bc36eafdSMike Gerdts  *
14*35786f68SRobert Mustacchi  * 2. License
15*35786f68SRobert Mustacchi  *
16*35786f68SRobert Mustacchi  * 2.1. This is your license from Intel Corp. under its intellectual property
17*35786f68SRobert Mustacchi  * rights. You may have additional license terms from the party that provided
18*35786f68SRobert Mustacchi  * you this software, covering your right to use that party's intellectual
19*35786f68SRobert Mustacchi  * property rights.
20*35786f68SRobert Mustacchi  *
21*35786f68SRobert Mustacchi  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22*35786f68SRobert Mustacchi  * copy of the source code appearing in this file ("Covered Code") an
23*35786f68SRobert Mustacchi  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24*35786f68SRobert Mustacchi  * base code distributed originally by Intel ("Original Intel Code") to copy,
25*35786f68SRobert Mustacchi  * make derivatives, distribute, use and display any portion of the Covered
26*35786f68SRobert Mustacchi  * Code in any form, with the right to sublicense such rights; and
27*35786f68SRobert Mustacchi  *
28*35786f68SRobert Mustacchi  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29*35786f68SRobert Mustacchi  * license (with the right to sublicense), under only those claims of Intel
30*35786f68SRobert Mustacchi  * patents that are infringed by the Original Intel Code, to make, use, sell,
31*35786f68SRobert Mustacchi  * offer to sell, and import the Covered Code and derivative works thereof
32*35786f68SRobert Mustacchi  * solely to the minimum extent necessary to exercise the above copyright
33*35786f68SRobert Mustacchi  * license, and in no event shall the patent license extend to any additions
34*35786f68SRobert Mustacchi  * to or modifications of the Original Intel Code. No other license or right
35*35786f68SRobert Mustacchi  * is granted directly or by implication, estoppel or otherwise;
36*35786f68SRobert Mustacchi  *
37*35786f68SRobert Mustacchi  * The above copyright and patent license is granted only if the following
38*35786f68SRobert Mustacchi  * conditions are met:
39*35786f68SRobert Mustacchi  *
40*35786f68SRobert Mustacchi  * 3. Conditions
41*35786f68SRobert Mustacchi  *
42*35786f68SRobert Mustacchi  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43*35786f68SRobert Mustacchi  * Redistribution of source code of any substantial portion of the Covered
44*35786f68SRobert Mustacchi  * Code or modification with rights to further distribute source must include
45*35786f68SRobert Mustacchi  * the above Copyright Notice, the above License, this list of Conditions,
46*35786f68SRobert Mustacchi  * and the following Disclaimer and Export Compliance provision. In addition,
47*35786f68SRobert Mustacchi  * Licensee must cause all Covered Code to which Licensee contributes to
48*35786f68SRobert Mustacchi  * contain a file documenting the changes Licensee made to create that Covered
49*35786f68SRobert Mustacchi  * Code and the date of any change. Licensee must include in that file the
50*35786f68SRobert Mustacchi  * documentation of any changes made by any predecessor Licensee. Licensee
51*35786f68SRobert Mustacchi  * must include a prominent statement that the modification is derived,
52*35786f68SRobert Mustacchi  * directly or indirectly, from Original Intel Code.
53*35786f68SRobert Mustacchi  *
54*35786f68SRobert Mustacchi  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55*35786f68SRobert Mustacchi  * Redistribution of source code of any substantial portion of the Covered
56*35786f68SRobert Mustacchi  * Code or modification without rights to further distribute source must
57*35786f68SRobert Mustacchi  * include the following Disclaimer and Export Compliance provision in the
58*35786f68SRobert Mustacchi  * documentation and/or other materials provided with distribution. In
59*35786f68SRobert Mustacchi  * addition, Licensee may not authorize further sublicense of source of any
60*35786f68SRobert Mustacchi  * portion of the Covered Code, and must include terms to the effect that the
61*35786f68SRobert Mustacchi  * license from Licensee to its licensee is limited to the intellectual
62*35786f68SRobert Mustacchi  * property embodied in the software Licensee provides to its licensee, and
63*35786f68SRobert Mustacchi  * not to intellectual property embodied in modifications its licensee may
64*35786f68SRobert Mustacchi  * make.
65*35786f68SRobert Mustacchi  *
66*35786f68SRobert Mustacchi  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67*35786f68SRobert Mustacchi  * substantial portion of the Covered Code or modification must reproduce the
68*35786f68SRobert Mustacchi  * above Copyright Notice, and the following Disclaimer and Export Compliance
69*35786f68SRobert Mustacchi  * provision in the documentation and/or other materials provided with the
70*35786f68SRobert Mustacchi  * distribution.
71*35786f68SRobert Mustacchi  *
72*35786f68SRobert Mustacchi  * 3.4. Intel retains all right, title, and interest in and to the Original
73*35786f68SRobert Mustacchi  * Intel Code.
74*35786f68SRobert Mustacchi  *
75*35786f68SRobert Mustacchi  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76*35786f68SRobert Mustacchi  * Intel shall be used in advertising or otherwise to promote the sale, use or
77*35786f68SRobert Mustacchi  * other dealings in products derived from or relating to the Covered Code
78*35786f68SRobert Mustacchi  * without prior written authorization from Intel.
79*35786f68SRobert Mustacchi  *
80*35786f68SRobert Mustacchi  * 4. Disclaimer and Export Compliance
81*35786f68SRobert Mustacchi  *
82*35786f68SRobert Mustacchi  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83*35786f68SRobert Mustacchi  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84*35786f68SRobert Mustacchi  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85*35786f68SRobert Mustacchi  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86*35786f68SRobert Mustacchi  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87*35786f68SRobert Mustacchi  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88*35786f68SRobert Mustacchi  * PARTICULAR PURPOSE.
89*35786f68SRobert Mustacchi  *
90*35786f68SRobert Mustacchi  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91*35786f68SRobert Mustacchi  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92*35786f68SRobert Mustacchi  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93*35786f68SRobert Mustacchi  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94*35786f68SRobert Mustacchi  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95*35786f68SRobert Mustacchi  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96*35786f68SRobert Mustacchi  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97*35786f68SRobert Mustacchi  * LIMITED REMEDY.
98*35786f68SRobert Mustacchi  *
99*35786f68SRobert Mustacchi  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100*35786f68SRobert Mustacchi  * software or system incorporating such software without first obtaining any
101*35786f68SRobert Mustacchi  * required license or other approval from the U. S. Department of Commerce or
102*35786f68SRobert Mustacchi  * any other agency or department of the United States Government. In the
103*35786f68SRobert Mustacchi  * event Licensee exports any such software from the United States or
104*35786f68SRobert Mustacchi  * re-exports any such software from a foreign destination, Licensee shall
105*35786f68SRobert Mustacchi  * ensure that the distribution and export/re-export of the software is in
106*35786f68SRobert Mustacchi  * compliance with all laws, regulations, orders, or other restrictions of the
107*35786f68SRobert Mustacchi  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108*35786f68SRobert Mustacchi  * any of its subsidiaries will export/re-export any technical data, process,
109*35786f68SRobert Mustacchi  * software, or service, directly or indirectly, to any country for which the
110*35786f68SRobert Mustacchi  * United States government or any agency thereof requires an export license,
111*35786f68SRobert Mustacchi  * other governmental approval, or letter of assurance, without first obtaining
112*35786f68SRobert Mustacchi  * such license, approval or letter.
113*35786f68SRobert Mustacchi  *
114*35786f68SRobert Mustacchi  *****************************************************************************
115*35786f68SRobert Mustacchi  *
116*35786f68SRobert Mustacchi  * Alternatively, you may choose to be licensed under the terms of the
117*35786f68SRobert Mustacchi  * following license:
118*35786f68SRobert Mustacchi  *
119bc36eafdSMike Gerdts  * Redistribution and use in source and binary forms, with or without
120bc36eafdSMike Gerdts  * modification, are permitted provided that the following conditions
121bc36eafdSMike Gerdts  * are met:
122bc36eafdSMike Gerdts  * 1. Redistributions of source code must retain the above copyright
123bc36eafdSMike Gerdts  *    notice, this list of conditions, and the following disclaimer,
124bc36eafdSMike Gerdts  *    without modification.
125bc36eafdSMike Gerdts  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126bc36eafdSMike Gerdts  *    substantially similar to the "NO WARRANTY" disclaimer below
127bc36eafdSMike Gerdts  *    ("Disclaimer") and any redistribution must be conditioned upon
128bc36eafdSMike Gerdts  *    including a substantially similar Disclaimer requirement for further
129bc36eafdSMike Gerdts  *    binary redistribution.
130bc36eafdSMike Gerdts  * 3. Neither the names of the above-listed copyright holders nor the names
131bc36eafdSMike Gerdts  *    of any contributors may be used to endorse or promote products derived
132bc36eafdSMike Gerdts  *    from this software without specific prior written permission.
133bc36eafdSMike Gerdts  *
134bc36eafdSMike Gerdts  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135bc36eafdSMike Gerdts  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136*35786f68SRobert Mustacchi  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137bc36eafdSMike Gerdts  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138*35786f68SRobert Mustacchi  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139*35786f68SRobert Mustacchi  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140*35786f68SRobert Mustacchi  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141*35786f68SRobert Mustacchi  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142*35786f68SRobert Mustacchi  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143*35786f68SRobert Mustacchi  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144*35786f68SRobert Mustacchi  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145*35786f68SRobert Mustacchi  *
146*35786f68SRobert Mustacchi  * Alternatively, you may choose to be licensed under the terms of the
147*35786f68SRobert Mustacchi  * GNU General Public License ("GPL") version 2 as published by the Free
148*35786f68SRobert Mustacchi  * Software Foundation.
149*35786f68SRobert Mustacchi  *
150*35786f68SRobert Mustacchi  *****************************************************************************/
151bc36eafdSMike Gerdts 
152bc36eafdSMike Gerdts #include "acpi.h"
153bc36eafdSMike Gerdts #include "accommon.h"
154bc36eafdSMike Gerdts #include "amlcode.h"
155bc36eafdSMike Gerdts #include "acnamesp.h"
156bc36eafdSMike Gerdts #include "acdisasm.h"
157bc36eafdSMike Gerdts #include "aslcompiler.h"
158bc36eafdSMike Gerdts #include <stdio.h>
159bc36eafdSMike Gerdts #include <errno.h>
160bc36eafdSMike Gerdts 
161bc36eafdSMike Gerdts 
162bc36eafdSMike Gerdts /*
163bc36eafdSMike Gerdts  * This module is used for application-level code (iASL disassembler) only.
164bc36eafdSMike Gerdts  *
165bc36eafdSMike Gerdts  * It contains the code to create and emit any necessary External() ASL
166bc36eafdSMike Gerdts  * statements for the module being disassembled.
167bc36eafdSMike Gerdts  */
168bc36eafdSMike Gerdts #define _COMPONENT          ACPI_CA_DISASSEMBLER
169bc36eafdSMike Gerdts         ACPI_MODULE_NAME    ("dmextern")
170bc36eafdSMike Gerdts 
171bc36eafdSMike Gerdts 
172bc36eafdSMike Gerdts /*
173bc36eafdSMike Gerdts  * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
174bc36eafdSMike Gerdts  * ObjectTypeKeyword. Used to generate typed external declarations
175bc36eafdSMike Gerdts  */
176bc36eafdSMike Gerdts static const char           *AcpiGbl_DmTypeNames[] =
177bc36eafdSMike Gerdts {
178bc36eafdSMike Gerdts     /* 00 */ ", UnknownObj",        /* Type ANY */
179bc36eafdSMike Gerdts     /* 01 */ ", IntObj",
180bc36eafdSMike Gerdts     /* 02 */ ", StrObj",
181bc36eafdSMike Gerdts     /* 03 */ ", BuffObj",
182bc36eafdSMike Gerdts     /* 04 */ ", PkgObj",
183bc36eafdSMike Gerdts     /* 05 */ ", FieldUnitObj",
184bc36eafdSMike Gerdts     /* 06 */ ", DeviceObj",
185bc36eafdSMike Gerdts     /* 07 */ ", EventObj",
186bc36eafdSMike Gerdts     /* 08 */ ", MethodObj",
187bc36eafdSMike Gerdts     /* 09 */ ", MutexObj",
188bc36eafdSMike Gerdts     /* 10 */ ", OpRegionObj",
189bc36eafdSMike Gerdts     /* 11 */ ", PowerResObj",
190bc36eafdSMike Gerdts     /* 12 */ ", ProcessorObj",
191bc36eafdSMike Gerdts     /* 13 */ ", ThermalZoneObj",
192bc36eafdSMike Gerdts     /* 14 */ ", BuffFieldObj",
193bc36eafdSMike Gerdts     /* 15 */ ", DDBHandleObj",
194bc36eafdSMike Gerdts     /* 16 */ "",                    /* Debug object */
195bc36eafdSMike Gerdts     /* 17 */ ", FieldUnitObj",
196bc36eafdSMike Gerdts     /* 18 */ ", FieldUnitObj",
197bc36eafdSMike Gerdts     /* 19 */ ", FieldUnitObj"
198bc36eafdSMike Gerdts };
199bc36eafdSMike Gerdts 
200bc36eafdSMike Gerdts #define METHOD_SEPARATORS           " \t,()\n"
201bc36eafdSMike Gerdts 
202*35786f68SRobert Mustacchi static const char          *ExternalConflictMessage =
203*35786f68SRobert Mustacchi     "    // Conflicts with a later declaration";
204*35786f68SRobert Mustacchi 
205bc36eafdSMike Gerdts 
206bc36eafdSMike Gerdts /* Local prototypes */
207bc36eafdSMike Gerdts 
208bc36eafdSMike Gerdts static const char *
209bc36eafdSMike Gerdts AcpiDmGetObjectTypeName (
210bc36eafdSMike Gerdts     ACPI_OBJECT_TYPE        Type);
211bc36eafdSMike Gerdts 
212bc36eafdSMike Gerdts static char *
213bc36eafdSMike Gerdts AcpiDmNormalizeParentPrefix (
214bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *Op,
215bc36eafdSMike Gerdts     char                    *Path);
216bc36eafdSMike Gerdts 
217*35786f68SRobert Mustacchi static ACPI_STATUS
218*35786f68SRobert Mustacchi AcpiDmGetExternalAndInternalPath (
219*35786f68SRobert Mustacchi     ACPI_NAMESPACE_NODE     *Node,
220*35786f68SRobert Mustacchi     char                    **ExternalPath,
221*35786f68SRobert Mustacchi     char                    **InternalPath);
222*35786f68SRobert Mustacchi 
223*35786f68SRobert Mustacchi static ACPI_STATUS
224*35786f68SRobert Mustacchi AcpiDmRemoveRootPrefix (
225*35786f68SRobert Mustacchi     char                    **Path);
226*35786f68SRobert Mustacchi 
227bc36eafdSMike Gerdts static void
228bc36eafdSMike Gerdts AcpiDmAddPathToExternalList (
229bc36eafdSMike Gerdts     char                    *Path,
230bc36eafdSMike Gerdts     UINT8                   Type,
231bc36eafdSMike Gerdts     UINT32                  Value,
232bc36eafdSMike Gerdts     UINT16                  Flags);
233bc36eafdSMike Gerdts 
234bc36eafdSMike Gerdts static ACPI_STATUS
235bc36eafdSMike Gerdts AcpiDmCreateNewExternal (
236bc36eafdSMike Gerdts     char                    *ExternalPath,
237bc36eafdSMike Gerdts     char                    *InternalPath,
238bc36eafdSMike Gerdts     UINT8                   Type,
239bc36eafdSMike Gerdts     UINT32                  Value,
240bc36eafdSMike Gerdts     UINT16                  Flags);
241bc36eafdSMike Gerdts 
242*35786f68SRobert Mustacchi static void
243*35786f68SRobert Mustacchi AcpiDmCheckForExternalConflict (
244*35786f68SRobert Mustacchi     char                    *Path);
245*35786f68SRobert Mustacchi 
246*35786f68SRobert Mustacchi static ACPI_STATUS
247*35786f68SRobert Mustacchi AcpiDmResolveExternal (
248*35786f68SRobert Mustacchi     char                    *Path,
249*35786f68SRobert Mustacchi     UINT8                   Type,
250*35786f68SRobert Mustacchi     ACPI_NAMESPACE_NODE     **Node);
251*35786f68SRobert Mustacchi 
252*35786f68SRobert Mustacchi 
253*35786f68SRobert Mustacchi static void
254*35786f68SRobert Mustacchi AcpiDmConflictingDeclaration (
255*35786f68SRobert Mustacchi     char                    *Path);
256*35786f68SRobert Mustacchi 
257bc36eafdSMike Gerdts 
258bc36eafdSMike Gerdts /*******************************************************************************
259bc36eafdSMike Gerdts  *
260bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmGetObjectTypeName
261bc36eafdSMike Gerdts  *
262bc36eafdSMike Gerdts  * PARAMETERS:  Type                - An ACPI_OBJECT_TYPE
263bc36eafdSMike Gerdts  *
264bc36eafdSMike Gerdts  * RETURN:      Pointer to a string
265bc36eafdSMike Gerdts  *
266bc36eafdSMike Gerdts  * DESCRIPTION: Map an object type to the ASL object type string.
267bc36eafdSMike Gerdts  *
268bc36eafdSMike Gerdts  ******************************************************************************/
269bc36eafdSMike Gerdts 
270bc36eafdSMike Gerdts static const char *
AcpiDmGetObjectTypeName(ACPI_OBJECT_TYPE Type)271bc36eafdSMike Gerdts AcpiDmGetObjectTypeName (
272bc36eafdSMike Gerdts     ACPI_OBJECT_TYPE        Type)
273bc36eafdSMike Gerdts {
274bc36eafdSMike Gerdts 
275bc36eafdSMike Gerdts     if (Type == ACPI_TYPE_LOCAL_SCOPE)
276bc36eafdSMike Gerdts     {
277bc36eafdSMike Gerdts         Type = ACPI_TYPE_DEVICE;
278bc36eafdSMike Gerdts     }
279bc36eafdSMike Gerdts     else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
280bc36eafdSMike Gerdts     {
281bc36eafdSMike Gerdts         return ("");
282bc36eafdSMike Gerdts     }
283bc36eafdSMike Gerdts 
284bc36eafdSMike Gerdts     return (AcpiGbl_DmTypeNames[Type]);
285bc36eafdSMike Gerdts }
286bc36eafdSMike Gerdts 
287bc36eafdSMike Gerdts 
288bc36eafdSMike Gerdts /*******************************************************************************
289bc36eafdSMike Gerdts  *
290bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmNormalizeParentPrefix
291bc36eafdSMike Gerdts  *
292bc36eafdSMike Gerdts  * PARAMETERS:  Op                  - Parse op
293bc36eafdSMike Gerdts  *              Path                - Path with parent prefix
294bc36eafdSMike Gerdts  *
295bc36eafdSMike Gerdts  * RETURN:      The full pathname to the object (from the namespace root)
296bc36eafdSMike Gerdts  *
297bc36eafdSMike Gerdts  * DESCRIPTION: Returns the full pathname of a path with parent prefix
298bc36eafdSMike Gerdts  *              The caller must free the fullpath returned.
299bc36eafdSMike Gerdts  *
300bc36eafdSMike Gerdts  ******************************************************************************/
301bc36eafdSMike Gerdts 
302bc36eafdSMike Gerdts static char *
AcpiDmNormalizeParentPrefix(ACPI_PARSE_OBJECT * Op,char * Path)303bc36eafdSMike Gerdts AcpiDmNormalizeParentPrefix (
304bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *Op,
305bc36eafdSMike Gerdts     char                    *Path)
306bc36eafdSMike Gerdts {
307bc36eafdSMike Gerdts     ACPI_NAMESPACE_NODE     *Node;
308bc36eafdSMike Gerdts     char                    *Fullpath;
309bc36eafdSMike Gerdts     char                    *ParentPath;
310bc36eafdSMike Gerdts     ACPI_SIZE               Length;
311bc36eafdSMike Gerdts     UINT32                  Index = 0;
312bc36eafdSMike Gerdts 
313bc36eafdSMike Gerdts 
314bc36eafdSMike Gerdts     if (!Op)
315bc36eafdSMike Gerdts     {
316bc36eafdSMike Gerdts         return (NULL);
317bc36eafdSMike Gerdts     }
318bc36eafdSMike Gerdts 
319bc36eafdSMike Gerdts     /* Search upwards in the parse tree until we reach the next namespace node */
320bc36eafdSMike Gerdts 
321bc36eafdSMike Gerdts     Op = Op->Common.Parent;
322bc36eafdSMike Gerdts     while (Op)
323bc36eafdSMike Gerdts     {
324bc36eafdSMike Gerdts         if (Op->Common.Node)
325bc36eafdSMike Gerdts         {
326bc36eafdSMike Gerdts             break;
327bc36eafdSMike Gerdts         }
328bc36eafdSMike Gerdts 
329bc36eafdSMike Gerdts         Op = Op->Common.Parent;
330bc36eafdSMike Gerdts     }
331bc36eafdSMike Gerdts 
332bc36eafdSMike Gerdts     if (!Op)
333bc36eafdSMike Gerdts     {
334bc36eafdSMike Gerdts         return (NULL);
335bc36eafdSMike Gerdts     }
336bc36eafdSMike Gerdts 
337bc36eafdSMike Gerdts     /*
338bc36eafdSMike Gerdts      * Find the actual parent node for the reference:
339bc36eafdSMike Gerdts      * Remove all carat prefixes from the input path.
340bc36eafdSMike Gerdts      * There may be multiple parent prefixes (For example, ^^^M000)
341bc36eafdSMike Gerdts      */
342bc36eafdSMike Gerdts     Node = Op->Common.Node;
343bc36eafdSMike Gerdts     while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
344bc36eafdSMike Gerdts     {
345bc36eafdSMike Gerdts         Node = Node->Parent;
346bc36eafdSMike Gerdts         Path++;
347bc36eafdSMike Gerdts     }
348bc36eafdSMike Gerdts 
349bc36eafdSMike Gerdts     if (!Node)
350bc36eafdSMike Gerdts     {
351bc36eafdSMike Gerdts         return (NULL);
352bc36eafdSMike Gerdts     }
353bc36eafdSMike Gerdts 
354bc36eafdSMike Gerdts     /* Get the full pathname for the parent node */
355bc36eafdSMike Gerdts 
356bc36eafdSMike Gerdts     ParentPath = AcpiNsGetExternalPathname (Node);
357bc36eafdSMike Gerdts     if (!ParentPath)
358bc36eafdSMike Gerdts     {
359bc36eafdSMike Gerdts         return (NULL);
360bc36eafdSMike Gerdts     }
361bc36eafdSMike Gerdts 
362bc36eafdSMike Gerdts     Length = (strlen (ParentPath) + strlen (Path) + 1);
363bc36eafdSMike Gerdts     if (ParentPath[1])
364bc36eafdSMike Gerdts     {
365bc36eafdSMike Gerdts         /*
366bc36eafdSMike Gerdts          * If ParentPath is not just a simple '\', increment the length
367bc36eafdSMike Gerdts          * for the required dot separator (ParentPath.Path)
368bc36eafdSMike Gerdts          */
369bc36eafdSMike Gerdts         Length++;
370bc36eafdSMike Gerdts 
371bc36eafdSMike Gerdts         /* For External() statements, we do not want a leading '\' */
372bc36eafdSMike Gerdts 
373bc36eafdSMike Gerdts         if (*ParentPath == AML_ROOT_PREFIX)
374bc36eafdSMike Gerdts         {
375bc36eafdSMike Gerdts             Index = 1;
376bc36eafdSMike Gerdts         }
377bc36eafdSMike Gerdts     }
378bc36eafdSMike Gerdts 
379bc36eafdSMike Gerdts     Fullpath = ACPI_ALLOCATE_ZEROED (Length);
380bc36eafdSMike Gerdts     if (!Fullpath)
381bc36eafdSMike Gerdts     {
382bc36eafdSMike Gerdts         goto Cleanup;
383bc36eafdSMike Gerdts     }
384bc36eafdSMike Gerdts 
385bc36eafdSMike Gerdts     /*
386bc36eafdSMike Gerdts      * Concatenate parent fullpath and path. For example,
387bc36eafdSMike Gerdts      * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
388bc36eafdSMike Gerdts      *
389bc36eafdSMike Gerdts      * Copy the parent path
390bc36eafdSMike Gerdts      */
391bc36eafdSMike Gerdts     strcpy (Fullpath, &ParentPath[Index]);
392bc36eafdSMike Gerdts 
393bc36eafdSMike Gerdts     /*
394bc36eafdSMike Gerdts      * Add dot separator
395bc36eafdSMike Gerdts      * (don't need dot if parent fullpath is a single backslash)
396bc36eafdSMike Gerdts      */
397bc36eafdSMike Gerdts     if (ParentPath[1])
398bc36eafdSMike Gerdts     {
399bc36eafdSMike Gerdts         strcat (Fullpath, ".");
400bc36eafdSMike Gerdts     }
401bc36eafdSMike Gerdts 
402bc36eafdSMike Gerdts     /* Copy child path (carat parent prefix(es) were skipped above) */
403bc36eafdSMike Gerdts 
404bc36eafdSMike Gerdts     strcat (Fullpath, Path);
405bc36eafdSMike Gerdts 
406bc36eafdSMike Gerdts Cleanup:
407bc36eafdSMike Gerdts     ACPI_FREE (ParentPath);
408bc36eafdSMike Gerdts     return (Fullpath);
409bc36eafdSMike Gerdts }
410bc36eafdSMike Gerdts 
411bc36eafdSMike Gerdts 
412bc36eafdSMike Gerdts /*******************************************************************************
413bc36eafdSMike Gerdts  *
414bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmAddToExternalFileList
415bc36eafdSMike Gerdts  *
416bc36eafdSMike Gerdts  * PARAMETERS:  PathList            - Single path or list separated by comma
417bc36eafdSMike Gerdts  *
418bc36eafdSMike Gerdts  * RETURN:      None
419bc36eafdSMike Gerdts  *
420bc36eafdSMike Gerdts  * DESCRIPTION: Add external files to global list
421bc36eafdSMike Gerdts  *
422bc36eafdSMike Gerdts  ******************************************************************************/
423bc36eafdSMike Gerdts 
424bc36eafdSMike Gerdts ACPI_STATUS
AcpiDmAddToExternalFileList(char * Pathname)425bc36eafdSMike Gerdts AcpiDmAddToExternalFileList (
426bc36eafdSMike Gerdts     char                    *Pathname)
427bc36eafdSMike Gerdts {
428bc36eafdSMike Gerdts     ACPI_EXTERNAL_FILE      *ExternalFile;
429bc36eafdSMike Gerdts     char                    *LocalPathname;
430bc36eafdSMike Gerdts 
431bc36eafdSMike Gerdts 
432bc36eafdSMike Gerdts     if (!Pathname)
433bc36eafdSMike Gerdts     {
434bc36eafdSMike Gerdts         return (AE_OK);
435bc36eafdSMike Gerdts     }
436bc36eafdSMike Gerdts 
437bc36eafdSMike Gerdts     LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
438bc36eafdSMike Gerdts     if (!LocalPathname)
439bc36eafdSMike Gerdts     {
440bc36eafdSMike Gerdts         return (AE_NO_MEMORY);
441bc36eafdSMike Gerdts     }
442bc36eafdSMike Gerdts 
443bc36eafdSMike Gerdts     ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
444bc36eafdSMike Gerdts     if (!ExternalFile)
445bc36eafdSMike Gerdts     {
446bc36eafdSMike Gerdts         ACPI_FREE (LocalPathname);
447bc36eafdSMike Gerdts         return (AE_NO_MEMORY);
448bc36eafdSMike Gerdts     }
449bc36eafdSMike Gerdts 
450bc36eafdSMike Gerdts     /* Take a copy of the file pathname */
451bc36eafdSMike Gerdts 
452bc36eafdSMike Gerdts     strcpy (LocalPathname, Pathname);
453bc36eafdSMike Gerdts     ExternalFile->Path = LocalPathname;
454bc36eafdSMike Gerdts 
455bc36eafdSMike Gerdts     if (AcpiGbl_ExternalFileList)
456bc36eafdSMike Gerdts     {
457bc36eafdSMike Gerdts         ExternalFile->Next = AcpiGbl_ExternalFileList;
458bc36eafdSMike Gerdts     }
459bc36eafdSMike Gerdts 
460bc36eafdSMike Gerdts     AcpiGbl_ExternalFileList = ExternalFile;
461bc36eafdSMike Gerdts     return (AE_OK);
462bc36eafdSMike Gerdts }
463bc36eafdSMike Gerdts 
464bc36eafdSMike Gerdts 
465bc36eafdSMike Gerdts /*******************************************************************************
466bc36eafdSMike Gerdts  *
467bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmClearExternalFileList
468bc36eafdSMike Gerdts  *
469bc36eafdSMike Gerdts  * PARAMETERS:  None
470bc36eafdSMike Gerdts  *
471bc36eafdSMike Gerdts  * RETURN:      None
472bc36eafdSMike Gerdts  *
473bc36eafdSMike Gerdts  * DESCRIPTION: Clear the external file list
474bc36eafdSMike Gerdts  *
475bc36eafdSMike Gerdts  ******************************************************************************/
476bc36eafdSMike Gerdts 
477bc36eafdSMike Gerdts void
AcpiDmClearExternalFileList(void)478bc36eafdSMike Gerdts AcpiDmClearExternalFileList (
479bc36eafdSMike Gerdts     void)
480bc36eafdSMike Gerdts {
481bc36eafdSMike Gerdts     ACPI_EXTERNAL_FILE      *NextExternal;
482bc36eafdSMike Gerdts 
483bc36eafdSMike Gerdts 
484bc36eafdSMike Gerdts     while (AcpiGbl_ExternalFileList)
485bc36eafdSMike Gerdts     {
486bc36eafdSMike Gerdts         NextExternal = AcpiGbl_ExternalFileList->Next;
487bc36eafdSMike Gerdts         ACPI_FREE (AcpiGbl_ExternalFileList->Path);
488bc36eafdSMike Gerdts         ACPI_FREE (AcpiGbl_ExternalFileList);
489bc36eafdSMike Gerdts         AcpiGbl_ExternalFileList = NextExternal;
490bc36eafdSMike Gerdts     }
491bc36eafdSMike Gerdts }
492bc36eafdSMike Gerdts 
493bc36eafdSMike Gerdts 
494bc36eafdSMike Gerdts /*******************************************************************************
495bc36eafdSMike Gerdts  *
496bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmGetExternalsFromFile
497bc36eafdSMike Gerdts  *
498bc36eafdSMike Gerdts  * PARAMETERS:  None
499bc36eafdSMike Gerdts  *
500bc36eafdSMike Gerdts  * RETURN:      None
501bc36eafdSMike Gerdts  *
502bc36eafdSMike Gerdts  * DESCRIPTION: Process the optional external reference file.
503bc36eafdSMike Gerdts  *
504bc36eafdSMike Gerdts  * Each line in the file should be of the form:
505bc36eafdSMike Gerdts  *      External (<Method namepath>, MethodObj, <ArgCount>)
506bc36eafdSMike Gerdts  *
507bc36eafdSMike Gerdts  * Example:
508bc36eafdSMike Gerdts  *      External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
509bc36eafdSMike Gerdts  *
510bc36eafdSMike Gerdts  ******************************************************************************/
511bc36eafdSMike Gerdts 
512bc36eafdSMike Gerdts void
AcpiDmGetExternalsFromFile(void)513bc36eafdSMike Gerdts AcpiDmGetExternalsFromFile (
514bc36eafdSMike Gerdts     void)
515bc36eafdSMike Gerdts {
516bc36eafdSMike Gerdts     FILE                    *ExternalRefFile;
517bc36eafdSMike Gerdts     char                    *Token;
518bc36eafdSMike Gerdts     char                    *MethodName;
519bc36eafdSMike Gerdts     UINT32                  ArgCount;
520bc36eafdSMike Gerdts     UINT32                  ImportCount = 0;
521bc36eafdSMike Gerdts 
522bc36eafdSMike Gerdts 
523bc36eafdSMike Gerdts     if (!Gbl_ExternalRefFilename)
524bc36eafdSMike Gerdts     {
525bc36eafdSMike Gerdts         return;
526bc36eafdSMike Gerdts     }
527bc36eafdSMike Gerdts 
528bc36eafdSMike Gerdts     /* Open the file */
529bc36eafdSMike Gerdts 
530bc36eafdSMike Gerdts     ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
531bc36eafdSMike Gerdts     if (!ExternalRefFile)
532bc36eafdSMike Gerdts     {
533bc36eafdSMike Gerdts         fprintf (stderr, "Could not open external reference file \"%s\"\n",
534bc36eafdSMike Gerdts             Gbl_ExternalRefFilename);
535bc36eafdSMike Gerdts         AslAbort ();
536bc36eafdSMike Gerdts         return;
537bc36eafdSMike Gerdts     }
538bc36eafdSMike Gerdts 
539bc36eafdSMike Gerdts     /* Each line defines a method */
540bc36eafdSMike Gerdts 
541*35786f68SRobert Mustacchi     while (fgets (StringBuffer, ASL_STRING_BUFFER_SIZE, ExternalRefFile))
542bc36eafdSMike Gerdts     {
543bc36eafdSMike Gerdts         Token = strtok (StringBuffer, METHOD_SEPARATORS);   /* "External" */
544bc36eafdSMike Gerdts         if (!Token)
545bc36eafdSMike Gerdts         {
546bc36eafdSMike Gerdts             continue;
547bc36eafdSMike Gerdts         }
548bc36eafdSMike Gerdts 
549bc36eafdSMike Gerdts         if (strcmp (Token, "External"))
550bc36eafdSMike Gerdts         {
551bc36eafdSMike Gerdts             continue;
552bc36eafdSMike Gerdts         }
553bc36eafdSMike Gerdts 
554bc36eafdSMike Gerdts         MethodName = strtok (NULL, METHOD_SEPARATORS);      /* Method namepath */
555bc36eafdSMike Gerdts         if (!MethodName)
556bc36eafdSMike Gerdts         {
557bc36eafdSMike Gerdts             continue;
558bc36eafdSMike Gerdts         }
559bc36eafdSMike Gerdts 
560bc36eafdSMike Gerdts         Token = strtok (NULL, METHOD_SEPARATORS);           /* "MethodObj" */
561bc36eafdSMike Gerdts         if (!Token)
562bc36eafdSMike Gerdts         {
563bc36eafdSMike Gerdts             continue;
564bc36eafdSMike Gerdts         }
565bc36eafdSMike Gerdts 
566bc36eafdSMike Gerdts         if (strcmp (Token, "MethodObj"))
567bc36eafdSMike Gerdts         {
568bc36eafdSMike Gerdts             continue;
569bc36eafdSMike Gerdts         }
570bc36eafdSMike Gerdts 
571bc36eafdSMike Gerdts         Token = strtok (NULL, METHOD_SEPARATORS);           /* Arg count */
572bc36eafdSMike Gerdts         if (!Token)
573bc36eafdSMike Gerdts         {
574bc36eafdSMike Gerdts             continue;
575bc36eafdSMike Gerdts         }
576bc36eafdSMike Gerdts 
577bc36eafdSMike Gerdts         /* Convert arg count string to an integer */
578bc36eafdSMike Gerdts 
579bc36eafdSMike Gerdts         errno = 0;
580bc36eafdSMike Gerdts         ArgCount = strtoul (Token, NULL, 0);
581bc36eafdSMike Gerdts         if (errno)
582bc36eafdSMike Gerdts         {
583bc36eafdSMike Gerdts             fprintf (stderr, "Invalid argument count (%s)\n", Token);
584bc36eafdSMike Gerdts             continue;
585bc36eafdSMike Gerdts         }
586bc36eafdSMike Gerdts 
587bc36eafdSMike Gerdts         if (ArgCount > 7)
588bc36eafdSMike Gerdts         {
589bc36eafdSMike Gerdts             fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
590bc36eafdSMike Gerdts             continue;
591bc36eafdSMike Gerdts         }
592bc36eafdSMike Gerdts 
593bc36eafdSMike Gerdts         /* Add this external to the global list */
594bc36eafdSMike Gerdts 
595bc36eafdSMike Gerdts         AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
596bc36eafdSMike Gerdts             Gbl_ExternalRefFilename, ArgCount, MethodName);
597bc36eafdSMike Gerdts 
598bc36eafdSMike Gerdts         AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
599bc36eafdSMike Gerdts             ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
600bc36eafdSMike Gerdts         ImportCount++;
601bc36eafdSMike Gerdts     }
602bc36eafdSMike Gerdts 
603bc36eafdSMike Gerdts     if (!ImportCount)
604bc36eafdSMike Gerdts     {
605bc36eafdSMike Gerdts         fprintf (stderr,
606bc36eafdSMike Gerdts             "Did not find any external methods in reference file \"%s\"\n",
607bc36eafdSMike Gerdts             Gbl_ExternalRefFilename);
608bc36eafdSMike Gerdts     }
609bc36eafdSMike Gerdts     else
610bc36eafdSMike Gerdts     {
611bc36eafdSMike Gerdts         /* Add the external(s) to the namespace */
612bc36eafdSMike Gerdts 
613*35786f68SRobert Mustacchi         AcpiDmAddExternalListToNamespace ();
614bc36eafdSMike Gerdts 
615bc36eafdSMike Gerdts         AcpiOsPrintf ("%s: Imported %u external method definitions\n",
616bc36eafdSMike Gerdts             Gbl_ExternalRefFilename, ImportCount);
617bc36eafdSMike Gerdts     }
618bc36eafdSMike Gerdts 
619bc36eafdSMike Gerdts     fclose (ExternalRefFile);
620bc36eafdSMike Gerdts }
621bc36eafdSMike Gerdts 
622bc36eafdSMike Gerdts 
623bc36eafdSMike Gerdts /*******************************************************************************
624bc36eafdSMike Gerdts  *
625bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmAddOpToExternalList
626bc36eafdSMike Gerdts  *
627bc36eafdSMike Gerdts  * PARAMETERS:  Op                  - Current parser Op
628bc36eafdSMike Gerdts  *              Path                - Internal (AML) path to the object
629bc36eafdSMike Gerdts  *              Type                - ACPI object type to be added
630bc36eafdSMike Gerdts  *              Value               - Arg count if adding a Method object
631bc36eafdSMike Gerdts  *              Flags               - To be passed to the external object
632bc36eafdSMike Gerdts  *
633bc36eafdSMike Gerdts  * RETURN:      None
634bc36eafdSMike Gerdts  *
635bc36eafdSMike Gerdts  * DESCRIPTION: Insert a new name into the global list of Externals which
636bc36eafdSMike Gerdts  *              will in turn be later emitted as an External() declaration
637bc36eafdSMike Gerdts  *              in the disassembled output.
638bc36eafdSMike Gerdts  *
639bc36eafdSMike Gerdts  *              This function handles the most common case where the referenced
640bc36eafdSMike Gerdts  *              name is simply not found in the constructed namespace.
641bc36eafdSMike Gerdts  *
642bc36eafdSMike Gerdts  ******************************************************************************/
643bc36eafdSMike Gerdts 
644bc36eafdSMike Gerdts void
AcpiDmAddOpToExternalList(ACPI_PARSE_OBJECT * Op,char * Path,UINT8 Type,UINT32 Value,UINT16 Flags)645bc36eafdSMike Gerdts AcpiDmAddOpToExternalList (
646bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *Op,
647bc36eafdSMike Gerdts     char                    *Path,
648bc36eafdSMike Gerdts     UINT8                   Type,
649bc36eafdSMike Gerdts     UINT32                  Value,
650bc36eafdSMike Gerdts     UINT16                  Flags)
651bc36eafdSMike Gerdts {
652bc36eafdSMike Gerdts     char                    *ExternalPath;
653bc36eafdSMike Gerdts     char                    *InternalPath = Path;
654bc36eafdSMike Gerdts     char                    *Temp;
655bc36eafdSMike Gerdts     ACPI_STATUS             Status;
656bc36eafdSMike Gerdts 
657bc36eafdSMike Gerdts 
658bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
659bc36eafdSMike Gerdts 
660bc36eafdSMike Gerdts 
661bc36eafdSMike Gerdts     if (!Path)
662bc36eafdSMike Gerdts     {
663bc36eafdSMike Gerdts         return_VOID;
664bc36eafdSMike Gerdts     }
665bc36eafdSMike Gerdts 
666bc36eafdSMike Gerdts     /* Remove a root backslash if present */
667bc36eafdSMike Gerdts 
668bc36eafdSMike Gerdts     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
669bc36eafdSMike Gerdts     {
670bc36eafdSMike Gerdts         Path++;
671bc36eafdSMike Gerdts     }
672bc36eafdSMike Gerdts 
673bc36eafdSMike Gerdts     /* Externalize the pathname */
674bc36eafdSMike Gerdts 
675bc36eafdSMike Gerdts     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
676bc36eafdSMike Gerdts         NULL, &ExternalPath);
677bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
678bc36eafdSMike Gerdts     {
679bc36eafdSMike Gerdts         return_VOID;
680bc36eafdSMike Gerdts     }
681bc36eafdSMike Gerdts 
682bc36eafdSMike Gerdts     /*
683bc36eafdSMike Gerdts      * Get the full pathname from the root if "Path" has one or more
684bc36eafdSMike Gerdts      * parent prefixes (^). Note: path will not contain a leading '\'.
685bc36eafdSMike Gerdts      */
686bc36eafdSMike Gerdts     if (*Path == (UINT8) AML_PARENT_PREFIX)
687bc36eafdSMike Gerdts     {
688bc36eafdSMike Gerdts         Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
689bc36eafdSMike Gerdts 
690bc36eafdSMike Gerdts         /* Set new external path */
691bc36eafdSMike Gerdts 
692bc36eafdSMike Gerdts         ACPI_FREE (ExternalPath);
693bc36eafdSMike Gerdts         ExternalPath = Temp;
694bc36eafdSMike Gerdts         if (!Temp)
695bc36eafdSMike Gerdts         {
696bc36eafdSMike Gerdts             return_VOID;
697bc36eafdSMike Gerdts         }
698bc36eafdSMike Gerdts 
699bc36eafdSMike Gerdts         /* Create the new internal pathname */
700bc36eafdSMike Gerdts 
701bc36eafdSMike Gerdts         Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
702bc36eafdSMike Gerdts         Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
703bc36eafdSMike Gerdts         if (ACPI_FAILURE (Status))
704bc36eafdSMike Gerdts         {
705bc36eafdSMike Gerdts             ACPI_FREE (ExternalPath);
706bc36eafdSMike Gerdts             return_VOID;
707bc36eafdSMike Gerdts         }
708bc36eafdSMike Gerdts     }
709bc36eafdSMike Gerdts 
710bc36eafdSMike Gerdts     /* Create the new External() declaration node */
711bc36eafdSMike Gerdts 
712bc36eafdSMike Gerdts     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
713bc36eafdSMike Gerdts         Type, Value, Flags);
714bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
715bc36eafdSMike Gerdts     {
716bc36eafdSMike Gerdts         ACPI_FREE (ExternalPath);
717bc36eafdSMike Gerdts         if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
718bc36eafdSMike Gerdts         {
719bc36eafdSMike Gerdts             ACPI_FREE (InternalPath);
720bc36eafdSMike Gerdts         }
721bc36eafdSMike Gerdts     }
722bc36eafdSMike Gerdts 
723bc36eafdSMike Gerdts     return_VOID;
724bc36eafdSMike Gerdts }
725bc36eafdSMike Gerdts 
726bc36eafdSMike Gerdts 
727*35786f68SRobert Mustacchi /*******************************************************************************
728*35786f68SRobert Mustacchi  *
729*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmGetExternalAndInternalPath
730*35786f68SRobert Mustacchi  *
731*35786f68SRobert Mustacchi  * PARAMETERS:  Node                - Namespace node for object to be added
732*35786f68SRobert Mustacchi  *              ExternalPath        - Will contain the external path of the node
733*35786f68SRobert Mustacchi  *              InternalPath        - Will contain the internal path of the node
734*35786f68SRobert Mustacchi  *
735*35786f68SRobert Mustacchi  * RETURN:      None
736*35786f68SRobert Mustacchi  *
737*35786f68SRobert Mustacchi  * DESCRIPTION: Get the External and Internal path from the given node.
738*35786f68SRobert Mustacchi  *
739*35786f68SRobert Mustacchi  ******************************************************************************/
740*35786f68SRobert Mustacchi 
741*35786f68SRobert Mustacchi static ACPI_STATUS
AcpiDmGetExternalAndInternalPath(ACPI_NAMESPACE_NODE * Node,char ** ExternalPath,char ** InternalPath)742*35786f68SRobert Mustacchi AcpiDmGetExternalAndInternalPath (
743*35786f68SRobert Mustacchi     ACPI_NAMESPACE_NODE     *Node,
744*35786f68SRobert Mustacchi     char                    **ExternalPath,
745*35786f68SRobert Mustacchi     char                    **InternalPath)
746*35786f68SRobert Mustacchi {
747*35786f68SRobert Mustacchi     ACPI_STATUS             Status;
748*35786f68SRobert Mustacchi 
749*35786f68SRobert Mustacchi 
750*35786f68SRobert Mustacchi     if (!Node)
751*35786f68SRobert Mustacchi     {
752*35786f68SRobert Mustacchi         return (AE_BAD_PARAMETER);
753*35786f68SRobert Mustacchi     }
754*35786f68SRobert Mustacchi 
755*35786f68SRobert Mustacchi     /* Get the full external and internal pathnames to the node */
756*35786f68SRobert Mustacchi 
757*35786f68SRobert Mustacchi     *ExternalPath = AcpiNsGetExternalPathname (Node);
758*35786f68SRobert Mustacchi     if (!*ExternalPath)
759*35786f68SRobert Mustacchi     {
760*35786f68SRobert Mustacchi         return (AE_BAD_PATHNAME);
761*35786f68SRobert Mustacchi     }
762*35786f68SRobert Mustacchi 
763*35786f68SRobert Mustacchi     Status = AcpiNsInternalizeName (*ExternalPath, InternalPath);
764*35786f68SRobert Mustacchi     if (ACPI_FAILURE (Status))
765*35786f68SRobert Mustacchi     {
766*35786f68SRobert Mustacchi         ACPI_FREE (*ExternalPath);
767*35786f68SRobert Mustacchi         return (Status);
768*35786f68SRobert Mustacchi     }
769*35786f68SRobert Mustacchi 
770*35786f68SRobert Mustacchi     return (AE_OK);
771*35786f68SRobert Mustacchi }
772*35786f68SRobert Mustacchi 
773*35786f68SRobert Mustacchi 
774*35786f68SRobert Mustacchi /*******************************************************************************
775*35786f68SRobert Mustacchi  *
776*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmRemoveRootPrefix
777*35786f68SRobert Mustacchi  *
778*35786f68SRobert Mustacchi  * PARAMETERS:  Path                - Remove Root prefix from this Path
779*35786f68SRobert Mustacchi  *
780*35786f68SRobert Mustacchi  * RETURN:      None
781*35786f68SRobert Mustacchi  *
782*35786f68SRobert Mustacchi  * DESCRIPTION: Remove the root prefix character '\' from Path.
783*35786f68SRobert Mustacchi  *
784*35786f68SRobert Mustacchi  ******************************************************************************/
785*35786f68SRobert Mustacchi 
786*35786f68SRobert Mustacchi static ACPI_STATUS
AcpiDmRemoveRootPrefix(char ** Path)787*35786f68SRobert Mustacchi AcpiDmRemoveRootPrefix (
788*35786f68SRobert Mustacchi     char                    **Path)
789*35786f68SRobert Mustacchi {
790*35786f68SRobert Mustacchi     char                    *InputPath = *Path;
791*35786f68SRobert Mustacchi 
792*35786f68SRobert Mustacchi 
793*35786f68SRobert Mustacchi     if ((*InputPath == AML_ROOT_PREFIX) && (InputPath[1]))
794*35786f68SRobert Mustacchi     {
795*35786f68SRobert Mustacchi         if (!memmove(InputPath, InputPath+1, strlen(InputPath)))
796*35786f68SRobert Mustacchi         {
797*35786f68SRobert Mustacchi             return (AE_ERROR);
798*35786f68SRobert Mustacchi         }
799*35786f68SRobert Mustacchi 
800*35786f68SRobert Mustacchi         *Path = InputPath;
801*35786f68SRobert Mustacchi     }
802*35786f68SRobert Mustacchi 
803*35786f68SRobert Mustacchi     return (AE_OK);
804*35786f68SRobert Mustacchi }
805*35786f68SRobert Mustacchi 
806*35786f68SRobert Mustacchi 
807bc36eafdSMike Gerdts /*******************************************************************************
808bc36eafdSMike Gerdts  *
809bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmAddNodeToExternalList
810bc36eafdSMike Gerdts  *
811bc36eafdSMike Gerdts  * PARAMETERS:  Node                - Namespace node for object to be added
812bc36eafdSMike Gerdts  *              Type                - ACPI object type to be added
813bc36eafdSMike Gerdts  *              Value               - Arg count if adding a Method object
814bc36eafdSMike Gerdts  *              Flags               - To be passed to the external object
815bc36eafdSMike Gerdts  *
816bc36eafdSMike Gerdts  * RETURN:      None
817bc36eafdSMike Gerdts  *
818bc36eafdSMike Gerdts  * DESCRIPTION: Insert a new name into the global list of Externals which
819bc36eafdSMike Gerdts  *              will in turn be later emitted as an External() declaration
820bc36eafdSMike Gerdts  *              in the disassembled output.
821bc36eafdSMike Gerdts  *
822bc36eafdSMike Gerdts  *              This function handles the case where the referenced name has
823bc36eafdSMike Gerdts  *              been found in the namespace, but the name originated in a
824bc36eafdSMike Gerdts  *              table other than the one that is being disassembled (such
825bc36eafdSMike Gerdts  *              as a table that is added via the iASL -e option).
826bc36eafdSMike Gerdts  *
827bc36eafdSMike Gerdts  ******************************************************************************/
828bc36eafdSMike Gerdts 
829bc36eafdSMike Gerdts void
AcpiDmAddNodeToExternalList(ACPI_NAMESPACE_NODE * Node,UINT8 Type,UINT32 Value,UINT16 Flags)830bc36eafdSMike Gerdts AcpiDmAddNodeToExternalList (
831bc36eafdSMike Gerdts     ACPI_NAMESPACE_NODE     *Node,
832bc36eafdSMike Gerdts     UINT8                   Type,
833bc36eafdSMike Gerdts     UINT32                  Value,
834bc36eafdSMike Gerdts     UINT16                  Flags)
835bc36eafdSMike Gerdts {
836bc36eafdSMike Gerdts     char                    *ExternalPath;
837bc36eafdSMike Gerdts     char                    *InternalPath;
838bc36eafdSMike Gerdts     ACPI_STATUS             Status;
839bc36eafdSMike Gerdts 
840bc36eafdSMike Gerdts 
841bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
842bc36eafdSMike Gerdts 
843bc36eafdSMike Gerdts     /* Get the full external and internal pathnames to the node */
844bc36eafdSMike Gerdts 
845*35786f68SRobert Mustacchi     Status = AcpiDmGetExternalAndInternalPath (Node, &ExternalPath, &InternalPath);
846bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
847bc36eafdSMike Gerdts     {
848bc36eafdSMike Gerdts         return_VOID;
849bc36eafdSMike Gerdts     }
850bc36eafdSMike Gerdts 
851bc36eafdSMike Gerdts     /* Remove the root backslash */
852bc36eafdSMike Gerdts 
853*35786f68SRobert Mustacchi     Status = AcpiDmRemoveRootPrefix (&ExternalPath);
854*35786f68SRobert Mustacchi     if (ACPI_FAILURE (Status))
855bc36eafdSMike Gerdts     {
856bc36eafdSMike Gerdts         ACPI_FREE (ExternalPath);
857*35786f68SRobert Mustacchi         ACPI_FREE (InternalPath);
858*35786f68SRobert Mustacchi         return_VOID;
859bc36eafdSMike Gerdts     }
860bc36eafdSMike Gerdts 
861bc36eafdSMike Gerdts     /* Create the new External() declaration node */
862bc36eafdSMike Gerdts 
863bc36eafdSMike Gerdts     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
864bc36eafdSMike Gerdts         Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
865bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
866bc36eafdSMike Gerdts     {
867bc36eafdSMike Gerdts         ACPI_FREE (ExternalPath);
868bc36eafdSMike Gerdts         ACPI_FREE (InternalPath);
869bc36eafdSMike Gerdts     }
870bc36eafdSMike Gerdts 
871bc36eafdSMike Gerdts     return_VOID;
872bc36eafdSMike Gerdts }
873bc36eafdSMike Gerdts 
874bc36eafdSMike Gerdts 
875bc36eafdSMike Gerdts /*******************************************************************************
876bc36eafdSMike Gerdts  *
877bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmAddPathToExternalList
878bc36eafdSMike Gerdts  *
879bc36eafdSMike Gerdts  * PARAMETERS:  Path                - External name of the object to be added
880bc36eafdSMike Gerdts  *              Type                - ACPI object type to be added
881bc36eafdSMike Gerdts  *              Value               - Arg count if adding a Method object
882bc36eafdSMike Gerdts  *              Flags               - To be passed to the external object
883bc36eafdSMike Gerdts  *
884bc36eafdSMike Gerdts  * RETURN:      None
885bc36eafdSMike Gerdts  *
886bc36eafdSMike Gerdts  * DESCRIPTION: Insert a new name into the global list of Externals which
887bc36eafdSMike Gerdts  *              will in turn be later emitted as an External() declaration
888bc36eafdSMike Gerdts  *              in the disassembled output.
889bc36eafdSMike Gerdts  *
890bc36eafdSMike Gerdts  *              This function currently is used to add externals via a
891bc36eafdSMike Gerdts  *              reference file (via the -fe iASL option).
892bc36eafdSMike Gerdts  *
893bc36eafdSMike Gerdts  ******************************************************************************/
894bc36eafdSMike Gerdts 
895bc36eafdSMike Gerdts static void
AcpiDmAddPathToExternalList(char * Path,UINT8 Type,UINT32 Value,UINT16 Flags)896bc36eafdSMike Gerdts AcpiDmAddPathToExternalList (
897bc36eafdSMike Gerdts     char                    *Path,
898bc36eafdSMike Gerdts     UINT8                   Type,
899bc36eafdSMike Gerdts     UINT32                  Value,
900bc36eafdSMike Gerdts     UINT16                  Flags)
901bc36eafdSMike Gerdts {
902bc36eafdSMike Gerdts     char                    *InternalPath;
903bc36eafdSMike Gerdts     char                    *ExternalPath;
904bc36eafdSMike Gerdts     ACPI_STATUS             Status;
905bc36eafdSMike Gerdts 
906bc36eafdSMike Gerdts 
907bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
908bc36eafdSMike Gerdts 
909bc36eafdSMike Gerdts 
910bc36eafdSMike Gerdts     if (!Path)
911bc36eafdSMike Gerdts     {
912bc36eafdSMike Gerdts         return_VOID;
913bc36eafdSMike Gerdts     }
914bc36eafdSMike Gerdts 
915bc36eafdSMike Gerdts     /* Remove a root backslash if present */
916bc36eafdSMike Gerdts 
917bc36eafdSMike Gerdts     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
918bc36eafdSMike Gerdts     {
919bc36eafdSMike Gerdts         Path++;
920bc36eafdSMike Gerdts     }
921bc36eafdSMike Gerdts 
922bc36eafdSMike Gerdts     /* Create the internal and external pathnames */
923bc36eafdSMike Gerdts 
924bc36eafdSMike Gerdts     Status = AcpiNsInternalizeName (Path, &InternalPath);
925bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
926bc36eafdSMike Gerdts     {
927bc36eafdSMike Gerdts         return_VOID;
928bc36eafdSMike Gerdts     }
929bc36eafdSMike Gerdts 
930bc36eafdSMike Gerdts     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
931bc36eafdSMike Gerdts         NULL, &ExternalPath);
932bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
933bc36eafdSMike Gerdts     {
934bc36eafdSMike Gerdts         ACPI_FREE (InternalPath);
935bc36eafdSMike Gerdts         return_VOID;
936bc36eafdSMike Gerdts     }
937bc36eafdSMike Gerdts 
938bc36eafdSMike Gerdts     /* Create the new External() declaration node */
939bc36eafdSMike Gerdts 
940bc36eafdSMike Gerdts     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
941bc36eafdSMike Gerdts         Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
942bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
943bc36eafdSMike Gerdts     {
944bc36eafdSMike Gerdts         ACPI_FREE (ExternalPath);
945bc36eafdSMike Gerdts         ACPI_FREE (InternalPath);
946bc36eafdSMike Gerdts     }
947bc36eafdSMike Gerdts 
948bc36eafdSMike Gerdts     return_VOID;
949bc36eafdSMike Gerdts }
950bc36eafdSMike Gerdts 
951bc36eafdSMike Gerdts 
952bc36eafdSMike Gerdts /*******************************************************************************
953bc36eafdSMike Gerdts  *
954bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmCreateNewExternal
955bc36eafdSMike Gerdts  *
956bc36eafdSMike Gerdts  * PARAMETERS:  ExternalPath        - External path to the object
957bc36eafdSMike Gerdts  *              InternalPath        - Internal (AML) path to the object
958bc36eafdSMike Gerdts  *              Type                - ACPI object type to be added
959bc36eafdSMike Gerdts  *              Value               - Arg count if adding a Method object
960bc36eafdSMike Gerdts  *              Flags               - To be passed to the external object
961bc36eafdSMike Gerdts  *
962bc36eafdSMike Gerdts  * RETURN:      Status
963bc36eafdSMike Gerdts  *
964bc36eafdSMike Gerdts  * DESCRIPTION: Common low-level function to insert a new name into the global
965bc36eafdSMike Gerdts  *              list of Externals which will in turn be later emitted as
966bc36eafdSMike Gerdts  *              External() declarations in the disassembled output.
967bc36eafdSMike Gerdts  *
968bc36eafdSMike Gerdts  *              Note: The external name should not include a root prefix
969bc36eafdSMike Gerdts  *              (backslash). We do not want External() statements to contain
970bc36eafdSMike Gerdts  *              a leading '\', as this prevents duplicate external statements
971bc36eafdSMike Gerdts  *              of the form:
972bc36eafdSMike Gerdts  *
973bc36eafdSMike Gerdts  *                  External (\ABCD)
974bc36eafdSMike Gerdts  *                  External (ABCD)
975bc36eafdSMike Gerdts  *
976bc36eafdSMike Gerdts  *              This would cause a compile time error when the disassembled
977bc36eafdSMike Gerdts  *              output file is recompiled.
978bc36eafdSMike Gerdts  *
979bc36eafdSMike Gerdts  *              There are two cases that are handled here. For both, we emit
980bc36eafdSMike Gerdts  *              an External() statement:
981bc36eafdSMike Gerdts  *              1) The name was simply not found in the namespace.
982bc36eafdSMike Gerdts  *              2) The name was found, but it originated in a table other than
983bc36eafdSMike Gerdts  *              the table that is being disassembled.
984bc36eafdSMike Gerdts  *
985bc36eafdSMike Gerdts  ******************************************************************************/
986bc36eafdSMike Gerdts 
987bc36eafdSMike Gerdts static ACPI_STATUS
AcpiDmCreateNewExternal(char * ExternalPath,char * InternalPath,UINT8 Type,UINT32 Value,UINT16 Flags)988bc36eafdSMike Gerdts AcpiDmCreateNewExternal (
989bc36eafdSMike Gerdts     char                    *ExternalPath,
990bc36eafdSMike Gerdts     char                    *InternalPath,
991bc36eafdSMike Gerdts     UINT8                   Type,
992bc36eafdSMike Gerdts     UINT32                  Value,
993bc36eafdSMike Gerdts     UINT16                  Flags)
994bc36eafdSMike Gerdts {
995bc36eafdSMike Gerdts     ACPI_EXTERNAL_LIST      *NewExternal;
996bc36eafdSMike Gerdts     ACPI_EXTERNAL_LIST      *NextExternal;
997bc36eafdSMike Gerdts     ACPI_EXTERNAL_LIST      *PrevExternal = NULL;
998bc36eafdSMike Gerdts 
999bc36eafdSMike Gerdts 
1000bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (DmCreateNewExternal);
1001bc36eafdSMike Gerdts 
1002bc36eafdSMike Gerdts 
1003bc36eafdSMike Gerdts     /* Check all existing externals to ensure no duplicates */
1004bc36eafdSMike Gerdts 
1005bc36eafdSMike Gerdts     NextExternal = AcpiGbl_ExternalList;
1006bc36eafdSMike Gerdts     while (NextExternal)
1007bc36eafdSMike Gerdts     {
1008bc36eafdSMike Gerdts         /* Check for duplicates */
1009bc36eafdSMike Gerdts 
1010bc36eafdSMike Gerdts         if (!strcmp (ExternalPath, NextExternal->Path))
1011bc36eafdSMike Gerdts         {
1012bc36eafdSMike Gerdts             /*
1013bc36eafdSMike Gerdts              * If this external came from an External() opcode, we are
1014bc36eafdSMike Gerdts              * finished with this one. (No need to check any further).
1015bc36eafdSMike Gerdts              */
1016bc36eafdSMike Gerdts             if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
1017bc36eafdSMike Gerdts             {
1018bc36eafdSMike Gerdts                 return_ACPI_STATUS (AE_ALREADY_EXISTS);
1019bc36eafdSMike Gerdts             }
1020bc36eafdSMike Gerdts 
1021bc36eafdSMike Gerdts             /* Allow upgrade of type from ANY */
1022bc36eafdSMike Gerdts 
1023bc36eafdSMike Gerdts             else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
1024bc36eafdSMike Gerdts                 (Type != ACPI_TYPE_ANY))
1025bc36eafdSMike Gerdts             {
1026bc36eafdSMike Gerdts                 NextExternal->Type = Type;
1027bc36eafdSMike Gerdts             }
1028bc36eafdSMike Gerdts 
1029bc36eafdSMike Gerdts             /* Update the argument count as necessary */
1030bc36eafdSMike Gerdts 
1031bc36eafdSMike Gerdts             if (Value < NextExternal->Value)
1032bc36eafdSMike Gerdts             {
1033bc36eafdSMike Gerdts                 NextExternal->Value = Value;
1034bc36eafdSMike Gerdts             }
1035bc36eafdSMike Gerdts 
1036bc36eafdSMike Gerdts             /* Update flags. */
1037bc36eafdSMike Gerdts 
1038bc36eafdSMike Gerdts             NextExternal->Flags |= Flags;
1039bc36eafdSMike Gerdts             NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
1040bc36eafdSMike Gerdts 
1041bc36eafdSMike Gerdts             return_ACPI_STATUS (AE_ALREADY_EXISTS);
1042bc36eafdSMike Gerdts         }
1043bc36eafdSMike Gerdts 
1044bc36eafdSMike Gerdts         NextExternal = NextExternal->Next;
1045bc36eafdSMike Gerdts     }
1046bc36eafdSMike Gerdts 
1047bc36eafdSMike Gerdts     /* Allocate and init a new External() descriptor */
1048bc36eafdSMike Gerdts 
1049bc36eafdSMike Gerdts     NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
1050bc36eafdSMike Gerdts     if (!NewExternal)
1051bc36eafdSMike Gerdts     {
1052bc36eafdSMike Gerdts         return_ACPI_STATUS (AE_NO_MEMORY);
1053bc36eafdSMike Gerdts     }
1054bc36eafdSMike Gerdts 
1055bc36eafdSMike Gerdts     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
1056bc36eafdSMike Gerdts         "Adding external reference node (%s) type [%s]\n",
1057bc36eafdSMike Gerdts         ExternalPath, AcpiUtGetTypeName (Type)));
1058bc36eafdSMike Gerdts 
1059bc36eafdSMike Gerdts     NewExternal->Flags = Flags;
1060bc36eafdSMike Gerdts     NewExternal->Value = Value;
1061bc36eafdSMike Gerdts     NewExternal->Path = ExternalPath;
1062bc36eafdSMike Gerdts     NewExternal->Type = Type;
1063bc36eafdSMike Gerdts     NewExternal->Length = (UINT16) strlen (ExternalPath);
1064bc36eafdSMike Gerdts     NewExternal->InternalPath = InternalPath;
1065bc36eafdSMike Gerdts 
1066bc36eafdSMike Gerdts     /* Link the new descriptor into the global list, alphabetically ordered */
1067bc36eafdSMike Gerdts 
1068bc36eafdSMike Gerdts     NextExternal = AcpiGbl_ExternalList;
1069bc36eafdSMike Gerdts     while (NextExternal)
1070bc36eafdSMike Gerdts     {
1071bc36eafdSMike Gerdts         if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
1072bc36eafdSMike Gerdts         {
1073bc36eafdSMike Gerdts             if (PrevExternal)
1074bc36eafdSMike Gerdts             {
1075bc36eafdSMike Gerdts                 PrevExternal->Next = NewExternal;
1076bc36eafdSMike Gerdts             }
1077bc36eafdSMike Gerdts             else
1078bc36eafdSMike Gerdts             {
1079bc36eafdSMike Gerdts                 AcpiGbl_ExternalList = NewExternal;
1080bc36eafdSMike Gerdts             }
1081bc36eafdSMike Gerdts 
1082bc36eafdSMike Gerdts             NewExternal->Next = NextExternal;
1083bc36eafdSMike Gerdts             return_ACPI_STATUS (AE_OK);
1084bc36eafdSMike Gerdts         }
1085bc36eafdSMike Gerdts 
1086bc36eafdSMike Gerdts         PrevExternal = NextExternal;
1087bc36eafdSMike Gerdts         NextExternal = NextExternal->Next;
1088bc36eafdSMike Gerdts     }
1089bc36eafdSMike Gerdts 
1090bc36eafdSMike Gerdts     if (PrevExternal)
1091bc36eafdSMike Gerdts     {
1092bc36eafdSMike Gerdts         PrevExternal->Next = NewExternal;
1093bc36eafdSMike Gerdts     }
1094bc36eafdSMike Gerdts     else
1095bc36eafdSMike Gerdts     {
1096bc36eafdSMike Gerdts         AcpiGbl_ExternalList = NewExternal;
1097bc36eafdSMike Gerdts     }
1098bc36eafdSMike Gerdts 
1099bc36eafdSMike Gerdts     return_ACPI_STATUS (AE_OK);
1100bc36eafdSMike Gerdts }
1101bc36eafdSMike Gerdts 
1102bc36eafdSMike Gerdts 
1103bc36eafdSMike Gerdts /*******************************************************************************
1104bc36eafdSMike Gerdts  *
1105*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmResolveExternal
1106bc36eafdSMike Gerdts  *
1107*35786f68SRobert Mustacchi  * PARAMETERS:  Path               - Path of the external
1108*35786f68SRobert Mustacchi  *              Type               - Type of the external
1109*35786f68SRobert Mustacchi  *              Node               - Input node for AcpiNsLookup
1110*35786f68SRobert Mustacchi  *
1111*35786f68SRobert Mustacchi  * RETURN:      Status
1112*35786f68SRobert Mustacchi  *
1113*35786f68SRobert Mustacchi  * DESCRIPTION: Resolve the external within the namespace by AcpiNsLookup.
1114*35786f68SRobert Mustacchi  *              If the returned node is an external and has the same type
1115*35786f68SRobert Mustacchi  *              we assume that it was either an existing external or a
1116*35786f68SRobert Mustacchi  *
1117*35786f68SRobert Mustacchi  ******************************************************************************/
1118*35786f68SRobert Mustacchi 
1119*35786f68SRobert Mustacchi static ACPI_STATUS
AcpiDmResolveExternal(char * Path,UINT8 Type,ACPI_NAMESPACE_NODE ** Node)1120*35786f68SRobert Mustacchi AcpiDmResolveExternal (
1121*35786f68SRobert Mustacchi     char                    *Path,
1122*35786f68SRobert Mustacchi     UINT8                   Type,
1123*35786f68SRobert Mustacchi     ACPI_NAMESPACE_NODE     **Node)
1124*35786f68SRobert Mustacchi {
1125*35786f68SRobert Mustacchi     ACPI_STATUS             Status;
1126*35786f68SRobert Mustacchi 
1127*35786f68SRobert Mustacchi 
1128*35786f68SRobert Mustacchi     Status = AcpiNsLookup (NULL, Path, Type,
1129*35786f68SRobert Mustacchi         ACPI_IMODE_LOAD_PASS1,
1130*35786f68SRobert Mustacchi         ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
1131*35786f68SRobert Mustacchi         NULL, Node);
1132*35786f68SRobert Mustacchi 
1133*35786f68SRobert Mustacchi     if (!Node)
1134*35786f68SRobert Mustacchi     {
1135*35786f68SRobert Mustacchi         ACPI_EXCEPTION ((AE_INFO, Status,
1136*35786f68SRobert Mustacchi             "while adding external to namespace [%s]", Path));
1137*35786f68SRobert Mustacchi     }
1138*35786f68SRobert Mustacchi 
1139*35786f68SRobert Mustacchi     /* Note the asl code "external(a) external(a)" is acceptable ASL */
1140*35786f68SRobert Mustacchi 
1141*35786f68SRobert Mustacchi     else if ((*Node)->Type == Type &&
1142*35786f68SRobert Mustacchi         (*Node)->Flags & ANOBJ_IS_EXTERNAL)
1143*35786f68SRobert Mustacchi     {
1144*35786f68SRobert Mustacchi         return (AE_OK);
1145*35786f68SRobert Mustacchi     }
1146*35786f68SRobert Mustacchi     else
1147*35786f68SRobert Mustacchi     {
1148*35786f68SRobert Mustacchi         ACPI_EXCEPTION ((AE_INFO, AE_ERROR,
1149*35786f68SRobert Mustacchi             "[%s] has conflicting declarations", Path));
1150*35786f68SRobert Mustacchi     }
1151*35786f68SRobert Mustacchi 
1152*35786f68SRobert Mustacchi     return (AE_ERROR);
1153*35786f68SRobert Mustacchi }
1154*35786f68SRobert Mustacchi 
1155*35786f68SRobert Mustacchi 
1156*35786f68SRobert Mustacchi /*******************************************************************************
1157*35786f68SRobert Mustacchi  *
1158*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmCreateSubobjectForExternal
1159*35786f68SRobert Mustacchi  *
1160*35786f68SRobert Mustacchi  * PARAMETERS:  Type                  - Type of the external
1161*35786f68SRobert Mustacchi  *              Node                  - Namespace node from AcpiNsLookup
1162*35786f68SRobert Mustacchi  *              ParamCount            - Value to be used for Method
1163bc36eafdSMike Gerdts  *
1164bc36eafdSMike Gerdts  * RETURN:      None
1165bc36eafdSMike Gerdts  *
1166*35786f68SRobert Mustacchi  * DESCRIPTION: Add one external to the namespace. Allows external to be
1167bc36eafdSMike Gerdts  *              "resolved".
1168bc36eafdSMike Gerdts  *
1169bc36eafdSMike Gerdts  ******************************************************************************/
1170bc36eafdSMike Gerdts 
1171bc36eafdSMike Gerdts void
AcpiDmCreateSubobjectForExternal(UINT8 Type,ACPI_NAMESPACE_NODE ** Node,UINT32 ParamCount)1172*35786f68SRobert Mustacchi AcpiDmCreateSubobjectForExternal (
1173*35786f68SRobert Mustacchi     UINT8                   Type,
1174*35786f68SRobert Mustacchi     ACPI_NAMESPACE_NODE     **Node,
1175*35786f68SRobert Mustacchi     UINT32                  ParamCount)
1176bc36eafdSMike Gerdts {
1177bc36eafdSMike Gerdts     ACPI_OPERAND_OBJECT     *ObjDesc;
1178bc36eafdSMike Gerdts 
1179bc36eafdSMike Gerdts 
1180*35786f68SRobert Mustacchi     switch (Type)
1181bc36eafdSMike Gerdts     {
1182*35786f68SRobert Mustacchi     case ACPI_TYPE_METHOD:
1183bc36eafdSMike Gerdts 
1184*35786f68SRobert Mustacchi         /* For methods, we need to save the argument count */
1185bc36eafdSMike Gerdts 
1186*35786f68SRobert Mustacchi         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
1187*35786f68SRobert Mustacchi         ObjDesc->Method.ParamCount = (UINT8) ParamCount;
1188*35786f68SRobert Mustacchi         (*Node)->Object = ObjDesc;
1189*35786f68SRobert Mustacchi         break;
1190bc36eafdSMike Gerdts 
1191*35786f68SRobert Mustacchi     case ACPI_TYPE_REGION:
1192bc36eafdSMike Gerdts 
1193*35786f68SRobert Mustacchi         /* Regions require a region sub-object */
1194bc36eafdSMike Gerdts 
1195*35786f68SRobert Mustacchi         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
1196*35786f68SRobert Mustacchi         ObjDesc->Region.Node = *Node;
1197*35786f68SRobert Mustacchi         (*Node)->Object = ObjDesc;
1198*35786f68SRobert Mustacchi         break;
1199bc36eafdSMike Gerdts 
1200*35786f68SRobert Mustacchi     default:
1201bc36eafdSMike Gerdts 
1202*35786f68SRobert Mustacchi         break;
1203*35786f68SRobert Mustacchi     }
1204*35786f68SRobert Mustacchi }
1205bc36eafdSMike Gerdts 
1206bc36eafdSMike Gerdts 
1207*35786f68SRobert Mustacchi /*******************************************************************************
1208*35786f68SRobert Mustacchi  *
1209*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmAddOneExternalToNamespace
1210*35786f68SRobert Mustacchi  *
1211*35786f68SRobert Mustacchi  * PARAMETERS:  Path                   - External parse object
1212*35786f68SRobert Mustacchi  *              Type                   - Type of parse object
1213*35786f68SRobert Mustacchi  *              ParamCount             - External method parameter count
1214*35786f68SRobert Mustacchi  *
1215*35786f68SRobert Mustacchi  * RETURN:      None
1216*35786f68SRobert Mustacchi  *
1217*35786f68SRobert Mustacchi  * DESCRIPTION: Add one external to the namespace by resolvign the external
1218*35786f68SRobert Mustacchi  *              (by performing a namespace lookup) and annotating the resulting
1219*35786f68SRobert Mustacchi  *              namespace node with the approperiate information if the type
1220*35786f68SRobert Mustacchi  *              is ACPI_TYPE_REGION or ACPI_TYPE_METHOD.
1221*35786f68SRobert Mustacchi  *
1222*35786f68SRobert Mustacchi  ******************************************************************************/
1223bc36eafdSMike Gerdts 
1224*35786f68SRobert Mustacchi void
AcpiDmAddOneExternalToNamespace(char * Path,UINT8 Type,UINT32 ParamCount)1225*35786f68SRobert Mustacchi AcpiDmAddOneExternalToNamespace (
1226*35786f68SRobert Mustacchi     char                    *Path,
1227*35786f68SRobert Mustacchi     UINT8                   Type,
1228*35786f68SRobert Mustacchi     UINT32                  ParamCount)
1229*35786f68SRobert Mustacchi {
1230*35786f68SRobert Mustacchi     ACPI_STATUS             Status;
1231*35786f68SRobert Mustacchi     ACPI_NAMESPACE_NODE     *Node;
1232*35786f68SRobert Mustacchi 
1233*35786f68SRobert Mustacchi 
1234*35786f68SRobert Mustacchi     Status = AcpiDmResolveExternal (Path, Type, &Node);
1235*35786f68SRobert Mustacchi 
1236*35786f68SRobert Mustacchi     if (ACPI_FAILURE (Status))
1237*35786f68SRobert Mustacchi     {
1238*35786f68SRobert Mustacchi         return;
1239*35786f68SRobert Mustacchi     }
1240*35786f68SRobert Mustacchi 
1241*35786f68SRobert Mustacchi     AcpiDmCreateSubobjectForExternal (Type, &Node, ParamCount);
1242*35786f68SRobert Mustacchi 
1243*35786f68SRobert Mustacchi }
1244bc36eafdSMike Gerdts 
1245*35786f68SRobert Mustacchi 
1246*35786f68SRobert Mustacchi /*******************************************************************************
1247*35786f68SRobert Mustacchi  *
1248*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmAddExternalListToNamespace
1249*35786f68SRobert Mustacchi  *
1250*35786f68SRobert Mustacchi  * PARAMETERS:  None
1251*35786f68SRobert Mustacchi  *
1252*35786f68SRobert Mustacchi  * RETURN:      None
1253*35786f68SRobert Mustacchi  *
1254*35786f68SRobert Mustacchi  * DESCRIPTION: Add all externals within AcpiGbl_ExternalList to the namespace.
1255*35786f68SRobert Mustacchi  *              Allows externals to be "resolved".
1256*35786f68SRobert Mustacchi  *
1257*35786f68SRobert Mustacchi  ******************************************************************************/
1258*35786f68SRobert Mustacchi 
1259*35786f68SRobert Mustacchi void
AcpiDmAddExternalListToNamespace(void)1260*35786f68SRobert Mustacchi AcpiDmAddExternalListToNamespace (
1261*35786f68SRobert Mustacchi     void)
1262*35786f68SRobert Mustacchi {
1263*35786f68SRobert Mustacchi     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
1264*35786f68SRobert Mustacchi 
1265*35786f68SRobert Mustacchi 
1266*35786f68SRobert Mustacchi     while (External)
1267*35786f68SRobert Mustacchi     {
1268*35786f68SRobert Mustacchi         AcpiDmAddOneExternalToNamespace (External->InternalPath,
1269*35786f68SRobert Mustacchi             External->Type, External->Value);
1270bc36eafdSMike Gerdts         External = External->Next;
1271bc36eafdSMike Gerdts     }
1272bc36eafdSMike Gerdts }
1273bc36eafdSMike Gerdts 
1274bc36eafdSMike Gerdts 
1275bc36eafdSMike Gerdts /*******************************************************************************
1276bc36eafdSMike Gerdts  *
1277*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmGetUnresolvedExternalMethodCount
1278bc36eafdSMike Gerdts  *
1279bc36eafdSMike Gerdts  * PARAMETERS:  None
1280bc36eafdSMike Gerdts  *
1281*35786f68SRobert Mustacchi  * RETURN:      The number of unresolved control method externals in the
1282*35786f68SRobert Mustacchi  *              external list
1283*35786f68SRobert Mustacchi  *
1284*35786f68SRobert Mustacchi  * DESCRIPTION: Return the number of unresolved external methods that have been
1285*35786f68SRobert Mustacchi  *              generated. If any unresolved control method externals have been
1286*35786f68SRobert Mustacchi  *              found, we must re-parse the entire definition block with the new
1287*35786f68SRobert Mustacchi  *              information (number of arguments for the methods.)
1288*35786f68SRobert Mustacchi  *              This is limitation of AML, we don't know the number of arguments
1289*35786f68SRobert Mustacchi  *              from the control method invocation itself.
1290bc36eafdSMike Gerdts  *
1291*35786f68SRobert Mustacchi  *              Note: resolved external control methods are external control
1292*35786f68SRobert Mustacchi  *              methods encoded with the AML_EXTERNAL_OP bytecode within the
1293*35786f68SRobert Mustacchi  *              AML being disassembled.
1294bc36eafdSMike Gerdts  *
1295bc36eafdSMike Gerdts  ******************************************************************************/
1296bc36eafdSMike Gerdts 
1297bc36eafdSMike Gerdts UINT32
AcpiDmGetUnresolvedExternalMethodCount(void)1298*35786f68SRobert Mustacchi AcpiDmGetUnresolvedExternalMethodCount (
1299bc36eafdSMike Gerdts     void)
1300bc36eafdSMike Gerdts {
1301bc36eafdSMike Gerdts     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
1302bc36eafdSMike Gerdts     UINT32                  Count = 0;
1303bc36eafdSMike Gerdts 
1304bc36eafdSMike Gerdts 
1305bc36eafdSMike Gerdts     while (External)
1306bc36eafdSMike Gerdts     {
1307*35786f68SRobert Mustacchi         if (External->Type == ACPI_TYPE_METHOD &&
1308*35786f68SRobert Mustacchi             !(External->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE))
1309bc36eafdSMike Gerdts         {
1310bc36eafdSMike Gerdts             Count++;
1311bc36eafdSMike Gerdts         }
1312bc36eafdSMike Gerdts 
1313bc36eafdSMike Gerdts         External = External->Next;
1314bc36eafdSMike Gerdts     }
1315bc36eafdSMike Gerdts 
1316bc36eafdSMike Gerdts     return (Count);
1317bc36eafdSMike Gerdts }
1318bc36eafdSMike Gerdts 
1319bc36eafdSMike Gerdts 
1320bc36eafdSMike Gerdts /*******************************************************************************
1321bc36eafdSMike Gerdts  *
1322bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmClearExternalList
1323bc36eafdSMike Gerdts  *
1324bc36eafdSMike Gerdts  * PARAMETERS:  None
1325bc36eafdSMike Gerdts  *
1326bc36eafdSMike Gerdts  * RETURN:      None
1327bc36eafdSMike Gerdts  *
1328bc36eafdSMike Gerdts  * DESCRIPTION: Free the entire External info list
1329bc36eafdSMike Gerdts  *
1330bc36eafdSMike Gerdts  ******************************************************************************/
1331bc36eafdSMike Gerdts 
1332bc36eafdSMike Gerdts void
AcpiDmClearExternalList(void)1333bc36eafdSMike Gerdts AcpiDmClearExternalList (
1334bc36eafdSMike Gerdts     void)
1335bc36eafdSMike Gerdts {
1336bc36eafdSMike Gerdts     ACPI_EXTERNAL_LIST      *NextExternal;
1337bc36eafdSMike Gerdts 
1338bc36eafdSMike Gerdts 
1339bc36eafdSMike Gerdts     while (AcpiGbl_ExternalList)
1340bc36eafdSMike Gerdts     {
1341bc36eafdSMike Gerdts         NextExternal = AcpiGbl_ExternalList->Next;
1342bc36eafdSMike Gerdts         ACPI_FREE (AcpiGbl_ExternalList->Path);
1343bc36eafdSMike Gerdts         ACPI_FREE (AcpiGbl_ExternalList);
1344bc36eafdSMike Gerdts         AcpiGbl_ExternalList = NextExternal;
1345bc36eafdSMike Gerdts     }
1346bc36eafdSMike Gerdts }
1347bc36eafdSMike Gerdts 
1348bc36eafdSMike Gerdts 
1349bc36eafdSMike Gerdts /*******************************************************************************
1350bc36eafdSMike Gerdts  *
1351bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmEmitExternals
1352bc36eafdSMike Gerdts  *
1353bc36eafdSMike Gerdts  * PARAMETERS:  None
1354bc36eafdSMike Gerdts  *
1355bc36eafdSMike Gerdts  * RETURN:      None
1356bc36eafdSMike Gerdts  *
1357bc36eafdSMike Gerdts  * DESCRIPTION: Emit an External() ASL statement for each of the externals in
1358bc36eafdSMike Gerdts  *              the global external info list.
1359bc36eafdSMike Gerdts  *
1360bc36eafdSMike Gerdts  ******************************************************************************/
1361bc36eafdSMike Gerdts 
1362bc36eafdSMike Gerdts void
AcpiDmEmitExternals(void)1363bc36eafdSMike Gerdts AcpiDmEmitExternals (
1364bc36eafdSMike Gerdts     void)
1365bc36eafdSMike Gerdts {
1366bc36eafdSMike Gerdts     ACPI_EXTERNAL_LIST      *NextExternal;
1367bc36eafdSMike Gerdts 
1368bc36eafdSMike Gerdts 
1369bc36eafdSMike Gerdts     if (!AcpiGbl_ExternalList)
1370bc36eafdSMike Gerdts     {
1371bc36eafdSMike Gerdts         return;
1372bc36eafdSMike Gerdts     }
1373bc36eafdSMike Gerdts 
1374bc36eafdSMike Gerdts     /*
1375bc36eafdSMike Gerdts      * Determine the number of control methods in the external list, and
1376bc36eafdSMike Gerdts      * also how many of those externals were resolved via the namespace.
1377bc36eafdSMike Gerdts      */
1378bc36eafdSMike Gerdts     NextExternal = AcpiGbl_ExternalList;
1379bc36eafdSMike Gerdts     while (NextExternal)
1380bc36eafdSMike Gerdts     {
1381bc36eafdSMike Gerdts         if (NextExternal->Type == ACPI_TYPE_METHOD)
1382bc36eafdSMike Gerdts         {
1383bc36eafdSMike Gerdts             AcpiGbl_NumExternalMethods++;
1384bc36eafdSMike Gerdts             if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
1385bc36eafdSMike Gerdts             {
1386bc36eafdSMike Gerdts                 AcpiGbl_ResolvedExternalMethods++;
1387bc36eafdSMike Gerdts             }
1388bc36eafdSMike Gerdts         }
1389bc36eafdSMike Gerdts 
1390bc36eafdSMike Gerdts         NextExternal = NextExternal->Next;
1391bc36eafdSMike Gerdts     }
1392bc36eafdSMike Gerdts 
1393bc36eafdSMike Gerdts     /* Check if any control methods were unresolved */
1394bc36eafdSMike Gerdts 
1395bc36eafdSMike Gerdts     AcpiDmUnresolvedWarning (1);
1396bc36eafdSMike Gerdts 
1397bc36eafdSMike Gerdts     if (Gbl_ExternalRefFilename)
1398bc36eafdSMike Gerdts     {
1399bc36eafdSMike Gerdts         AcpiOsPrintf (
1400bc36eafdSMike Gerdts             "    /*\n     * External declarations were imported from\n"
1401bc36eafdSMike Gerdts             "     * a reference file -- %s\n     */\n\n",
1402bc36eafdSMike Gerdts             Gbl_ExternalRefFilename);
1403bc36eafdSMike Gerdts     }
1404bc36eafdSMike Gerdts 
1405bc36eafdSMike Gerdts     /*
1406bc36eafdSMike Gerdts      * Walk and emit the list of externals found during the AML parsing
1407bc36eafdSMike Gerdts      */
1408bc36eafdSMike Gerdts     while (AcpiGbl_ExternalList)
1409bc36eafdSMike Gerdts     {
1410bc36eafdSMike Gerdts         if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
1411bc36eafdSMike Gerdts         {
1412bc36eafdSMike Gerdts             AcpiOsPrintf ("    External (%s%s)",
1413bc36eafdSMike Gerdts                 AcpiGbl_ExternalList->Path,
1414bc36eafdSMike Gerdts                 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
1415bc36eafdSMike Gerdts 
1416bc36eafdSMike Gerdts             /* Check for "unresolved" method reference */
1417bc36eafdSMike Gerdts 
1418bc36eafdSMike Gerdts             if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
1419bc36eafdSMike Gerdts                 (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
1420bc36eafdSMike Gerdts             {
1421bc36eafdSMike Gerdts                 AcpiOsPrintf ("    // Warning: Unknown method, "
1422bc36eafdSMike Gerdts                     "guessing %u arguments",
1423bc36eafdSMike Gerdts                     AcpiGbl_ExternalList->Value);
1424bc36eafdSMike Gerdts             }
1425bc36eafdSMike Gerdts 
1426bc36eafdSMike Gerdts             /* Check for external from a external references file */
1427bc36eafdSMike Gerdts 
1428bc36eafdSMike Gerdts             else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
1429bc36eafdSMike Gerdts             {
1430bc36eafdSMike Gerdts                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1431bc36eafdSMike Gerdts                 {
1432bc36eafdSMike Gerdts                     AcpiOsPrintf ("    // %u Arguments",
1433bc36eafdSMike Gerdts                         AcpiGbl_ExternalList->Value);
1434bc36eafdSMike Gerdts                 }
1435bc36eafdSMike Gerdts 
1436bc36eafdSMike Gerdts                 AcpiOsPrintf ("    // From external reference file");
1437bc36eafdSMike Gerdts             }
1438bc36eafdSMike Gerdts 
1439bc36eafdSMike Gerdts             /* This is the normal external case */
1440bc36eafdSMike Gerdts 
1441bc36eafdSMike Gerdts             else
1442bc36eafdSMike Gerdts             {
1443bc36eafdSMike Gerdts                 /* For methods, add a comment with the number of arguments */
1444bc36eafdSMike Gerdts 
1445bc36eafdSMike Gerdts                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1446bc36eafdSMike Gerdts                 {
1447bc36eafdSMike Gerdts                     AcpiOsPrintf ("    // %u Arguments",
1448bc36eafdSMike Gerdts                         AcpiGbl_ExternalList->Value);
1449bc36eafdSMike Gerdts                 }
1450bc36eafdSMike Gerdts             }
1451bc36eafdSMike Gerdts 
1452*35786f68SRobert Mustacchi             if (AcpiGbl_ExternalList->Flags &= ACPI_EXT_CONFLICTING_DECLARATION)
1453*35786f68SRobert Mustacchi             {
1454*35786f68SRobert Mustacchi                 AcpiOsPrintf ("%s", ExternalConflictMessage);
1455*35786f68SRobert Mustacchi                 AcpiDmConflictingDeclaration (AcpiGbl_ExternalList->Path);
1456*35786f68SRobert Mustacchi             }
1457bc36eafdSMike Gerdts             AcpiOsPrintf ("\n");
1458bc36eafdSMike Gerdts         }
1459bc36eafdSMike Gerdts 
1460bc36eafdSMike Gerdts         /* Free this external info block and move on to next external */
1461bc36eafdSMike Gerdts 
1462bc36eafdSMike Gerdts         NextExternal = AcpiGbl_ExternalList->Next;
1463bc36eafdSMike Gerdts         if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
1464bc36eafdSMike Gerdts         {
1465bc36eafdSMike Gerdts             ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
1466bc36eafdSMike Gerdts         }
1467bc36eafdSMike Gerdts 
1468bc36eafdSMike Gerdts         ACPI_FREE (AcpiGbl_ExternalList->Path);
1469bc36eafdSMike Gerdts         ACPI_FREE (AcpiGbl_ExternalList);
1470bc36eafdSMike Gerdts         AcpiGbl_ExternalList = NextExternal;
1471bc36eafdSMike Gerdts     }
1472bc36eafdSMike Gerdts 
1473bc36eafdSMike Gerdts     AcpiOsPrintf ("\n");
1474bc36eafdSMike Gerdts }
1475bc36eafdSMike Gerdts 
1476bc36eafdSMike Gerdts 
1477*35786f68SRobert Mustacchi /*******************************************************************************
1478*35786f68SRobert Mustacchi  *
1479*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmMarkExternalConflict
1480*35786f68SRobert Mustacchi  *
1481*35786f68SRobert Mustacchi  * PARAMETERS:  Path          - Namepath to search
1482*35786f68SRobert Mustacchi  *
1483*35786f68SRobert Mustacchi  * RETURN:      ExternalList
1484*35786f68SRobert Mustacchi  *
1485*35786f68SRobert Mustacchi  * DESCRIPTION: Search the AcpiGbl_ExternalList for a matching path
1486*35786f68SRobert Mustacchi  *
1487*35786f68SRobert Mustacchi  ******************************************************************************/
1488*35786f68SRobert Mustacchi 
1489*35786f68SRobert Mustacchi void
AcpiDmMarkExternalConflict(ACPI_NAMESPACE_NODE * Node)1490*35786f68SRobert Mustacchi AcpiDmMarkExternalConflict (
1491*35786f68SRobert Mustacchi     ACPI_NAMESPACE_NODE     *Node)
1492*35786f68SRobert Mustacchi {
1493*35786f68SRobert Mustacchi     ACPI_EXTERNAL_LIST      *ExternalList = AcpiGbl_ExternalList;
1494*35786f68SRobert Mustacchi     char                    *ExternalPath;
1495*35786f68SRobert Mustacchi     char                    *InternalPath;
1496*35786f68SRobert Mustacchi     char                    *Temp;
1497*35786f68SRobert Mustacchi     ACPI_STATUS             Status;
1498*35786f68SRobert Mustacchi 
1499*35786f68SRobert Mustacchi 
1500*35786f68SRobert Mustacchi     ACPI_FUNCTION_TRACE (DmMarkExternalConflict);
1501*35786f68SRobert Mustacchi 
1502*35786f68SRobert Mustacchi 
1503*35786f68SRobert Mustacchi     if (Node->Flags & ANOBJ_IS_EXTERNAL)
1504*35786f68SRobert Mustacchi     {
1505*35786f68SRobert Mustacchi         return_VOID;
1506*35786f68SRobert Mustacchi     }
1507*35786f68SRobert Mustacchi 
1508*35786f68SRobert Mustacchi     /* Get the full external and internal pathnames to the node */
1509*35786f68SRobert Mustacchi 
1510*35786f68SRobert Mustacchi     Status = AcpiDmGetExternalAndInternalPath (Node,
1511*35786f68SRobert Mustacchi         &ExternalPath, &InternalPath);
1512*35786f68SRobert Mustacchi     if (ACPI_FAILURE (Status))
1513*35786f68SRobert Mustacchi     {
1514*35786f68SRobert Mustacchi         return_VOID;
1515*35786f68SRobert Mustacchi     }
1516*35786f68SRobert Mustacchi 
1517*35786f68SRobert Mustacchi     /* Remove the root backslash */
1518*35786f68SRobert Mustacchi 
1519*35786f68SRobert Mustacchi     Status = AcpiDmRemoveRootPrefix (&InternalPath);
1520*35786f68SRobert Mustacchi     if (ACPI_FAILURE (Status))
1521*35786f68SRobert Mustacchi     {
1522*35786f68SRobert Mustacchi         ACPI_FREE (InternalPath);
1523*35786f68SRobert Mustacchi         ACPI_FREE (ExternalPath);
1524*35786f68SRobert Mustacchi         return_VOID;
1525*35786f68SRobert Mustacchi     }
1526*35786f68SRobert Mustacchi 
1527*35786f68SRobert Mustacchi     while (ExternalList)
1528*35786f68SRobert Mustacchi     {
1529*35786f68SRobert Mustacchi         Temp = ExternalList->InternalPath;
1530*35786f68SRobert Mustacchi         if ((*ExternalList->InternalPath == AML_ROOT_PREFIX) &&
1531*35786f68SRobert Mustacchi             (ExternalList->InternalPath[1]))
1532*35786f68SRobert Mustacchi         {
1533*35786f68SRobert Mustacchi             Temp++;
1534*35786f68SRobert Mustacchi         }
1535*35786f68SRobert Mustacchi 
1536*35786f68SRobert Mustacchi         if (!strcmp (ExternalList->InternalPath, InternalPath))
1537*35786f68SRobert Mustacchi         {
1538*35786f68SRobert Mustacchi             ExternalList->Flags |= ACPI_EXT_CONFLICTING_DECLARATION;
1539*35786f68SRobert Mustacchi         }
1540*35786f68SRobert Mustacchi         ExternalList = ExternalList->Next;
1541*35786f68SRobert Mustacchi     }
1542*35786f68SRobert Mustacchi 
1543*35786f68SRobert Mustacchi     ACPI_FREE (InternalPath);
1544*35786f68SRobert Mustacchi     ACPI_FREE (ExternalPath);
1545*35786f68SRobert Mustacchi 
1546*35786f68SRobert Mustacchi     return_VOID;
1547*35786f68SRobert Mustacchi }
1548*35786f68SRobert Mustacchi 
1549*35786f68SRobert Mustacchi 
1550*35786f68SRobert Mustacchi /*******************************************************************************
1551*35786f68SRobert Mustacchi  *
1552*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmConflictingDeclaration
1553*35786f68SRobert Mustacchi  *
1554*35786f68SRobert Mustacchi  * PARAMETERS:  Path                - Path with conflicting declaration
1555*35786f68SRobert Mustacchi  *
1556*35786f68SRobert Mustacchi  * RETURN:      None
1557*35786f68SRobert Mustacchi  *
1558*35786f68SRobert Mustacchi  * DESCRIPTION: Emit a warning when printing conflicting ASL external
1559*35786f68SRobert Mustacchi  *              declarations.
1560*35786f68SRobert Mustacchi  *
1561*35786f68SRobert Mustacchi  ******************************************************************************/
1562*35786f68SRobert Mustacchi 
1563*35786f68SRobert Mustacchi static void
AcpiDmConflictingDeclaration(char * Path)1564*35786f68SRobert Mustacchi AcpiDmConflictingDeclaration (
1565*35786f68SRobert Mustacchi     char                    *Path)
1566*35786f68SRobert Mustacchi {
1567*35786f68SRobert Mustacchi     fprintf (stderr,
1568*35786f68SRobert Mustacchi         " Warning - Emitting ASL code \"External (%s)\"\n"
1569*35786f68SRobert Mustacchi         "           This is a conflicting declaration with some "
1570*35786f68SRobert Mustacchi         "other declaration within the ASL code.\n"
1571*35786f68SRobert Mustacchi         "           This external declaration may need to be "
1572*35786f68SRobert Mustacchi         "deleted in order to recompile the dsl file.\n\n",
1573*35786f68SRobert Mustacchi         Path);
1574*35786f68SRobert Mustacchi }
1575*35786f68SRobert Mustacchi 
1576*35786f68SRobert Mustacchi 
1577*35786f68SRobert Mustacchi /*******************************************************************************
1578*35786f68SRobert Mustacchi  *
1579*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmEmitExternal
1580*35786f68SRobert Mustacchi  *
1581*35786f68SRobert Mustacchi  * PARAMETERS:  Op                  External Parse Object
1582*35786f68SRobert Mustacchi  *
1583*35786f68SRobert Mustacchi  * RETURN:      None
1584*35786f68SRobert Mustacchi  *
1585*35786f68SRobert Mustacchi  * DESCRIPTION: Emit an External() ASL statement for the current External
1586*35786f68SRobert Mustacchi  *              parse object. Note: External Ops are named types so the
1587*35786f68SRobert Mustacchi  *              namepath is contained within NameOp->Name.Path.
1588*35786f68SRobert Mustacchi  *
1589*35786f68SRobert Mustacchi  ******************************************************************************/
1590*35786f68SRobert Mustacchi 
1591*35786f68SRobert Mustacchi void
AcpiDmEmitExternal(ACPI_PARSE_OBJECT * NameOp,ACPI_PARSE_OBJECT * TypeOp)1592*35786f68SRobert Mustacchi AcpiDmEmitExternal (
1593*35786f68SRobert Mustacchi     ACPI_PARSE_OBJECT       *NameOp,
1594*35786f68SRobert Mustacchi     ACPI_PARSE_OBJECT       *TypeOp)
1595*35786f68SRobert Mustacchi {
1596*35786f68SRobert Mustacchi     AcpiOsPrintf ("External (");
1597*35786f68SRobert Mustacchi     AcpiDmNamestring (NameOp->Named.Path);
1598*35786f68SRobert Mustacchi     AcpiOsPrintf ("%s)",
1599*35786f68SRobert Mustacchi         AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));
1600*35786f68SRobert Mustacchi     AcpiDmCheckForExternalConflict (NameOp->Named.Path);
1601*35786f68SRobert Mustacchi     AcpiOsPrintf ("\n");
1602*35786f68SRobert Mustacchi }
1603*35786f68SRobert Mustacchi 
1604*35786f68SRobert Mustacchi 
1605*35786f68SRobert Mustacchi /*******************************************************************************
1606*35786f68SRobert Mustacchi  *
1607*35786f68SRobert Mustacchi  * FUNCTION:    AcpiDmCheckForExternalConflict
1608*35786f68SRobert Mustacchi  *
1609*35786f68SRobert Mustacchi  * PARAMETERS:  Path                - Path to check
1610*35786f68SRobert Mustacchi  *
1611*35786f68SRobert Mustacchi  * RETURN:      None
1612*35786f68SRobert Mustacchi  *
1613*35786f68SRobert Mustacchi  * DESCRIPTION: Search the External List to see if the input Path has a
1614*35786f68SRobert Mustacchi  *              conflicting declaration.
1615*35786f68SRobert Mustacchi  *
1616*35786f68SRobert Mustacchi  ******************************************************************************/
1617*35786f68SRobert Mustacchi 
1618*35786f68SRobert Mustacchi static void
AcpiDmCheckForExternalConflict(char * Path)1619*35786f68SRobert Mustacchi AcpiDmCheckForExternalConflict (
1620*35786f68SRobert Mustacchi     char                    *Path)
1621*35786f68SRobert Mustacchi {
1622*35786f68SRobert Mustacchi     ACPI_EXTERNAL_LIST      *ExternalList = AcpiGbl_ExternalList;
1623*35786f68SRobert Mustacchi     char                    *ListItemPath;
1624*35786f68SRobert Mustacchi     char                    *InputPath;
1625*35786f68SRobert Mustacchi 
1626*35786f68SRobert Mustacchi 
1627*35786f68SRobert Mustacchi     if (!Path)
1628*35786f68SRobert Mustacchi     {
1629*35786f68SRobert Mustacchi         return;
1630*35786f68SRobert Mustacchi     }
1631*35786f68SRobert Mustacchi 
1632*35786f68SRobert Mustacchi     /* Move past the root prefix '\' */
1633*35786f68SRobert Mustacchi 
1634*35786f68SRobert Mustacchi     InputPath = Path;
1635*35786f68SRobert Mustacchi     if ((*InputPath == AML_ROOT_PREFIX) && InputPath[1])
1636*35786f68SRobert Mustacchi     {
1637*35786f68SRobert Mustacchi         InputPath++;
1638*35786f68SRobert Mustacchi     }
1639*35786f68SRobert Mustacchi 
1640*35786f68SRobert Mustacchi     while (ExternalList)
1641*35786f68SRobert Mustacchi     {
1642*35786f68SRobert Mustacchi         ListItemPath = ExternalList->Path;
1643*35786f68SRobert Mustacchi         if (ListItemPath)
1644*35786f68SRobert Mustacchi         {
1645*35786f68SRobert Mustacchi             /* Move past the root prefix '\' */
1646*35786f68SRobert Mustacchi 
1647*35786f68SRobert Mustacchi             if ((*ListItemPath == AML_ROOT_PREFIX) &&
1648*35786f68SRobert Mustacchi                 ListItemPath[1])
1649*35786f68SRobert Mustacchi             {
1650*35786f68SRobert Mustacchi                 ListItemPath++;
1651*35786f68SRobert Mustacchi             }
1652*35786f68SRobert Mustacchi 
1653*35786f68SRobert Mustacchi             if (!strcmp (ListItemPath, InputPath) &&
1654*35786f68SRobert Mustacchi                 (ExternalList->Flags & ACPI_EXT_CONFLICTING_DECLARATION))
1655*35786f68SRobert Mustacchi             {
1656*35786f68SRobert Mustacchi                 AcpiOsPrintf ("%s", ExternalConflictMessage);
1657*35786f68SRobert Mustacchi                 AcpiDmConflictingDeclaration (Path);
1658*35786f68SRobert Mustacchi 
1659*35786f68SRobert Mustacchi                 return;
1660*35786f68SRobert Mustacchi             }
1661*35786f68SRobert Mustacchi         }
1662*35786f68SRobert Mustacchi         ExternalList = ExternalList->Next;
1663*35786f68SRobert Mustacchi     }
1664*35786f68SRobert Mustacchi }
1665bc36eafdSMike Gerdts /*******************************************************************************
1666bc36eafdSMike Gerdts  *
1667bc36eafdSMike Gerdts  * FUNCTION:    AcpiDmUnresolvedWarning
1668bc36eafdSMike Gerdts  *
1669bc36eafdSMike Gerdts  * PARAMETERS:  Type                - Where to output the warning.
1670bc36eafdSMike Gerdts  *                                    0 means write to stderr
1671bc36eafdSMike Gerdts  *                                    1 means write to AcpiOsPrintf
1672bc36eafdSMike Gerdts  *
1673bc36eafdSMike Gerdts  * RETURN:      None
1674bc36eafdSMike Gerdts  *
1675bc36eafdSMike Gerdts  * DESCRIPTION: Issue warning message if there are unresolved external control
1676bc36eafdSMike Gerdts  *              methods within the disassembly.
1677bc36eafdSMike Gerdts  *
1678bc36eafdSMike Gerdts  ******************************************************************************/
1679bc36eafdSMike Gerdts 
1680*35786f68SRobert Mustacchi /*
1681bc36eafdSMike Gerdts Summary of the external control method problem:
1682bc36eafdSMike Gerdts 
1683bc36eafdSMike Gerdts When the -e option is used with disassembly, the various SSDTs are simply
1684bc36eafdSMike Gerdts loaded into a global namespace for the disassembler to use in order to
1685bc36eafdSMike Gerdts resolve control method references (invocations).
1686bc36eafdSMike Gerdts 
1687bc36eafdSMike Gerdts The disassembler tracks any such references, and will emit an External()
1688bc36eafdSMike Gerdts statement for these types of methods, with the proper number of arguments .
1689bc36eafdSMike Gerdts 
1690bc36eafdSMike Gerdts Without the SSDTs, the AML does not contain enough information to properly
1691bc36eafdSMike Gerdts disassemble the control method invocation -- because the disassembler does
1692bc36eafdSMike Gerdts not know how many arguments to parse.
1693bc36eafdSMike Gerdts 
1694bc36eafdSMike Gerdts An example: Assume we have two control methods. ABCD has one argument, and
1695bc36eafdSMike Gerdts EFGH has zero arguments. Further, we have two additional control methods
1696bc36eafdSMike Gerdts that invoke ABCD and EFGH, named T1 and T2:
1697bc36eafdSMike Gerdts 
1698bc36eafdSMike Gerdts     Method (ABCD, 1)
1699bc36eafdSMike Gerdts     {
1700bc36eafdSMike Gerdts     }
1701bc36eafdSMike Gerdts     Method (EFGH, 0)
1702bc36eafdSMike Gerdts     {
1703bc36eafdSMike Gerdts     }
1704bc36eafdSMike Gerdts     Method (T1)
1705bc36eafdSMike Gerdts     {
1706bc36eafdSMike Gerdts         ABCD (Add (2, 7, Local0))
1707bc36eafdSMike Gerdts     }
1708bc36eafdSMike Gerdts     Method (T2)
1709bc36eafdSMike Gerdts     {
1710bc36eafdSMike Gerdts         EFGH ()
1711bc36eafdSMike Gerdts         Add (2, 7, Local0)
1712bc36eafdSMike Gerdts     }
1713bc36eafdSMike Gerdts 
1714bc36eafdSMike Gerdts Here is the AML code that is generated for T1 and T2:
1715bc36eafdSMike Gerdts 
1716bc36eafdSMike Gerdts      185:      Method (T1)
1717bc36eafdSMike Gerdts 
1718bc36eafdSMike Gerdts 0000034C:  14 10 54 31 5F 5F 00 ...    "..T1__."
1719bc36eafdSMike Gerdts 
1720bc36eafdSMike Gerdts      186:      {
1721bc36eafdSMike Gerdts      187:          ABCD (Add (2, 7, Local0))
1722bc36eafdSMike Gerdts 
1723bc36eafdSMike Gerdts 00000353:  41 42 43 44 ............    "ABCD"
1724bc36eafdSMike Gerdts 00000357:  72 0A 02 0A 07 60 ......    "r....`"
1725bc36eafdSMike Gerdts 
1726bc36eafdSMike Gerdts      188:      }
1727bc36eafdSMike Gerdts 
1728bc36eafdSMike Gerdts      190:      Method (T2)
1729bc36eafdSMike Gerdts 
1730bc36eafdSMike Gerdts 0000035D:  14 10 54 32 5F 5F 00 ...    "..T2__."
1731bc36eafdSMike Gerdts 
1732bc36eafdSMike Gerdts      191:      {
1733bc36eafdSMike Gerdts      192:          EFGH ()
1734bc36eafdSMike Gerdts 
1735bc36eafdSMike Gerdts 00000364:  45 46 47 48 ............    "EFGH"
1736bc36eafdSMike Gerdts 
1737bc36eafdSMike Gerdts      193:          Add (2, 7, Local0)
1738bc36eafdSMike Gerdts 
1739bc36eafdSMike Gerdts 00000368:  72 0A 02 0A 07 60 ......    "r....`"
1740bc36eafdSMike Gerdts      194:      }
1741bc36eafdSMike Gerdts 
1742bc36eafdSMike Gerdts Note that the AML code for T1 and T2 is essentially identical. When
1743bc36eafdSMike Gerdts disassembling this code, the methods ABCD and EFGH must be known to the
1744bc36eafdSMike Gerdts disassembler, otherwise it does not know how to handle the method invocations.
1745bc36eafdSMike Gerdts 
1746bc36eafdSMike Gerdts In other words, if ABCD and EFGH are actually external control methods
1747bc36eafdSMike Gerdts appearing in an SSDT, the disassembler does not know what to do unless
1748bc36eafdSMike Gerdts the owning SSDT has been loaded via the -e option.
1749*35786f68SRobert Mustacchi */
1750bc36eafdSMike Gerdts 
1751bc36eafdSMike Gerdts static char             ExternalWarningPart1[600];
1752bc36eafdSMike Gerdts static char             ExternalWarningPart2[400];
1753bc36eafdSMike Gerdts static char             ExternalWarningPart3[400];
1754bc36eafdSMike Gerdts static char             ExternalWarningPart4[200];
1755bc36eafdSMike Gerdts 
1756bc36eafdSMike Gerdts void
AcpiDmUnresolvedWarning(UINT8 Type)1757bc36eafdSMike Gerdts AcpiDmUnresolvedWarning (
1758bc36eafdSMike Gerdts     UINT8                   Type)
1759bc36eafdSMike Gerdts {
1760bc36eafdSMike Gerdts     char                    *Format;
1761bc36eafdSMike Gerdts     char                    Pad[] = "     *";
1762bc36eafdSMike Gerdts     char                    NoPad[] = "";
1763bc36eafdSMike Gerdts 
1764bc36eafdSMike Gerdts 
1765bc36eafdSMike Gerdts     if (!AcpiGbl_NumExternalMethods)
1766bc36eafdSMike Gerdts     {
1767bc36eafdSMike Gerdts         return;
1768bc36eafdSMike Gerdts     }
1769bc36eafdSMike Gerdts 
1770bc36eafdSMike Gerdts     if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
1771bc36eafdSMike Gerdts     {
1772bc36eafdSMike Gerdts         return;
1773bc36eafdSMike Gerdts     }
1774bc36eafdSMike Gerdts 
1775bc36eafdSMike Gerdts     Format = Type ? Pad : NoPad;
1776bc36eafdSMike Gerdts 
1777bc36eafdSMike Gerdts     sprintf (ExternalWarningPart1,
1778bc36eafdSMike Gerdts         "%s iASL Warning: There %s %u external control method%s found during\n"
1779bc36eafdSMike Gerdts         "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1780bc36eafdSMike Gerdts         "%s ACPI tables may be required to properly disassemble the code. This\n"
1781bc36eafdSMike Gerdts         "%s resulting disassembler output file may not compile because the\n"
1782bc36eafdSMike Gerdts         "%s disassembler did not know how many arguments to assign to the\n"
1783bc36eafdSMike Gerdts         "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
1784bc36eafdSMike Gerdts         "%s runtime and may or may not be available via the host OS.\n",
1785bc36eafdSMike Gerdts         Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
1786bc36eafdSMike Gerdts         AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
1787bc36eafdSMike Gerdts         Format, AcpiGbl_ResolvedExternalMethods,
1788bc36eafdSMike Gerdts         (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
1789bc36eafdSMike Gerdts         (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
1790bc36eafdSMike Gerdts         Format, Format, Format, Format, Format);
1791bc36eafdSMike Gerdts 
1792bc36eafdSMike Gerdts     sprintf (ExternalWarningPart2,
1793bc36eafdSMike Gerdts         "%s To specify the tables needed to resolve external control method\n"
1794bc36eafdSMike Gerdts         "%s references, the -e option can be used to specify the filenames.\n"
1795bc36eafdSMike Gerdts         "%s Example iASL invocations:\n"
1796bc36eafdSMike Gerdts         "%s     iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
1797bc36eafdSMike Gerdts         "%s     iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
1798bc36eafdSMike Gerdts         "%s     iasl -e ssdt*.aml -d dsdt.aml\n",
1799bc36eafdSMike Gerdts         Format, Format, Format, Format, Format, Format);
1800bc36eafdSMike Gerdts 
1801bc36eafdSMike Gerdts     sprintf (ExternalWarningPart3,
1802bc36eafdSMike Gerdts         "%s In addition, the -fe option can be used to specify a file containing\n"
1803bc36eafdSMike Gerdts         "%s control method external declarations with the associated method\n"
1804bc36eafdSMike Gerdts         "%s argument counts. Each line of the file must be of the form:\n"
1805bc36eafdSMike Gerdts         "%s     External (<method pathname>, MethodObj, <argument count>)\n"
1806bc36eafdSMike Gerdts         "%s Invocation:\n"
1807bc36eafdSMike Gerdts         "%s     iasl -fe refs.txt -d dsdt.aml\n",
1808bc36eafdSMike Gerdts         Format, Format, Format, Format, Format, Format);
1809bc36eafdSMike Gerdts 
1810bc36eafdSMike Gerdts     sprintf (ExternalWarningPart4,
1811bc36eafdSMike Gerdts         "%s The following methods were unresolved and many not compile properly\n"
1812bc36eafdSMike Gerdts         "%s because the disassembler had to guess at the number of arguments\n"
1813bc36eafdSMike Gerdts         "%s required for each:\n",
1814bc36eafdSMike Gerdts         Format, Format, Format);
1815bc36eafdSMike Gerdts 
1816bc36eafdSMike Gerdts     if (Type)
1817bc36eafdSMike Gerdts     {
1818bc36eafdSMike Gerdts         if (!AcpiGbl_ExternalFileList)
1819bc36eafdSMike Gerdts         {
1820bc36eafdSMike Gerdts             /* The -e option was not specified */
1821bc36eafdSMike Gerdts 
1822bc36eafdSMike Gerdts            AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     *\n%s     */\n",
1823bc36eafdSMike Gerdts                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
1824bc36eafdSMike Gerdts                ExternalWarningPart4);
1825bc36eafdSMike Gerdts         }
1826bc36eafdSMike Gerdts         else
1827bc36eafdSMike Gerdts         {
1828bc36eafdSMike Gerdts             /* The -e option was specified, but there are still some unresolved externals */
1829bc36eafdSMike Gerdts 
1830bc36eafdSMike Gerdts             AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     */\n",
1831bc36eafdSMike Gerdts                ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
1832bc36eafdSMike Gerdts         }
1833bc36eafdSMike Gerdts     }
1834bc36eafdSMike Gerdts     else
1835bc36eafdSMike Gerdts     {
1836bc36eafdSMike Gerdts         if (!AcpiGbl_ExternalFileList)
1837bc36eafdSMike Gerdts         {
1838bc36eafdSMike Gerdts             /* The -e option was not specified */
1839bc36eafdSMike Gerdts 
1840bc36eafdSMike Gerdts             fprintf (stderr, "\n%s\n%s\n%s\n",
1841bc36eafdSMike Gerdts                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
1842bc36eafdSMike Gerdts         }
1843bc36eafdSMike Gerdts         else
1844bc36eafdSMike Gerdts         {
1845bc36eafdSMike Gerdts             /* The -e option was specified, but there are still some unresolved externals */
1846bc36eafdSMike Gerdts 
1847bc36eafdSMike Gerdts             fprintf (stderr, "\n%s\n%s\n",
1848bc36eafdSMike Gerdts                ExternalWarningPart1, ExternalWarningPart3);
1849bc36eafdSMike Gerdts         }
1850bc36eafdSMike Gerdts     }
1851bc36eafdSMike Gerdts }
1852