xref: /freebsd/sys/contrib/dev/acpica/compiler/aslexternal.c (revision f8146b882bc156c1d8ddf14bbea67253ebc064bb)
1*f8146b88SJung-uk Kim /******************************************************************************
2*f8146b88SJung-uk Kim  *
3*f8146b88SJung-uk Kim  * Module Name: aslexternal - ASL External opcode compiler support
4*f8146b88SJung-uk Kim  *
5*f8146b88SJung-uk Kim  *****************************************************************************/
6*f8146b88SJung-uk Kim 
7*f8146b88SJung-uk Kim /*
8*f8146b88SJung-uk Kim  * Copyright (C) 2000 - 2016, Intel Corp.
9*f8146b88SJung-uk Kim  * All rights reserved.
10*f8146b88SJung-uk Kim  *
11*f8146b88SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12*f8146b88SJung-uk Kim  * modification, are permitted provided that the following conditions
13*f8146b88SJung-uk Kim  * are met:
14*f8146b88SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15*f8146b88SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16*f8146b88SJung-uk Kim  *    without modification.
17*f8146b88SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*f8146b88SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19*f8146b88SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20*f8146b88SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21*f8146b88SJung-uk Kim  *    binary redistribution.
22*f8146b88SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23*f8146b88SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24*f8146b88SJung-uk Kim  *    from this software without specific prior written permission.
25*f8146b88SJung-uk Kim  *
26*f8146b88SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27*f8146b88SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28*f8146b88SJung-uk Kim  * Software Foundation.
29*f8146b88SJung-uk Kim  *
30*f8146b88SJung-uk Kim  * NO WARRANTY
31*f8146b88SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*f8146b88SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*f8146b88SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*f8146b88SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*f8146b88SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*f8146b88SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*f8146b88SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*f8146b88SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*f8146b88SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*f8146b88SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*f8146b88SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42*f8146b88SJung-uk Kim  */
43*f8146b88SJung-uk Kim 
44*f8146b88SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
45*f8146b88SJung-uk Kim #include "aslcompiler.y.h"
46*f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
47*f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
48*f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
49*f8146b88SJung-uk Kim 
50*f8146b88SJung-uk Kim 
51*f8146b88SJung-uk Kim #define _COMPONENT          ACPI_COMPILER
52*f8146b88SJung-uk Kim         ACPI_MODULE_NAME    ("aslexternal")
53*f8146b88SJung-uk Kim 
54*f8146b88SJung-uk Kim 
55*f8146b88SJung-uk Kim /* Local prototypes */
56*f8146b88SJung-uk Kim 
57*f8146b88SJung-uk Kim static void
58*f8146b88SJung-uk Kim ExInsertArgCount (
59*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Op);
60*f8146b88SJung-uk Kim 
61*f8146b88SJung-uk Kim static void
62*f8146b88SJung-uk Kim ExMoveExternals (
63*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *DefinitionBlockOp);
64*f8146b88SJung-uk Kim 
65*f8146b88SJung-uk Kim 
66*f8146b88SJung-uk Kim /*******************************************************************************
67*f8146b88SJung-uk Kim  *
68*f8146b88SJung-uk Kim  * FUNCTION:    ExDoExternal
69*f8146b88SJung-uk Kim  *
70*f8146b88SJung-uk Kim  * PARAMETERS:  Op                  - Current Parse node
71*f8146b88SJung-uk Kim  *
72*f8146b88SJung-uk Kim  * RETURN:      None
73*f8146b88SJung-uk Kim  *
74*f8146b88SJung-uk Kim  * DESCRIPTION: Add an External() definition to the global list. This list
75*f8146b88SJung-uk Kim  *              is used to generate External opcodes.
76*f8146b88SJung-uk Kim  *
77*f8146b88SJung-uk Kim  ******************************************************************************/
78*f8146b88SJung-uk Kim 
79*f8146b88SJung-uk Kim void
80*f8146b88SJung-uk Kim ExDoExternal (
81*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
82*f8146b88SJung-uk Kim {
83*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *ListOp;
84*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Prev;
85*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Next;
86*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *ArgCountOp;
87*f8146b88SJung-uk Kim 
88*f8146b88SJung-uk Kim 
89*f8146b88SJung-uk Kim     ArgCountOp = Op->Asl.Child->Asl.Next->Asl.Next;
90*f8146b88SJung-uk Kim     ArgCountOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
91*f8146b88SJung-uk Kim     ArgCountOp->Asl.ParseOpcode = PARSEOP_BYTECONST;
92*f8146b88SJung-uk Kim     ArgCountOp->Asl.Value.Integer = 0;
93*f8146b88SJung-uk Kim     UtSetParseOpName (ArgCountOp);
94*f8146b88SJung-uk Kim 
95*f8146b88SJung-uk Kim     /* Create new list node of arbitrary type */
96*f8146b88SJung-uk Kim 
97*f8146b88SJung-uk Kim     ListOp = TrAllocateNode (PARSEOP_DEFAULT_ARG);
98*f8146b88SJung-uk Kim 
99*f8146b88SJung-uk Kim     /* Store External node as child */
100*f8146b88SJung-uk Kim 
101*f8146b88SJung-uk Kim     ListOp->Asl.Child = Op;
102*f8146b88SJung-uk Kim     ListOp->Asl.Next = NULL;
103*f8146b88SJung-uk Kim 
104*f8146b88SJung-uk Kim     if (Gbl_ExternalsListHead)
105*f8146b88SJung-uk Kim     {
106*f8146b88SJung-uk Kim         /* Link new External to end of list */
107*f8146b88SJung-uk Kim 
108*f8146b88SJung-uk Kim         Prev = Gbl_ExternalsListHead;
109*f8146b88SJung-uk Kim         Next = Prev;
110*f8146b88SJung-uk Kim         while (Next)
111*f8146b88SJung-uk Kim         {
112*f8146b88SJung-uk Kim             Prev = Next;
113*f8146b88SJung-uk Kim             Next = Next->Asl.Next;
114*f8146b88SJung-uk Kim         }
115*f8146b88SJung-uk Kim 
116*f8146b88SJung-uk Kim         Prev->Asl.Next = ListOp;
117*f8146b88SJung-uk Kim     }
118*f8146b88SJung-uk Kim     else
119*f8146b88SJung-uk Kim     {
120*f8146b88SJung-uk Kim         Gbl_ExternalsListHead = ListOp;
121*f8146b88SJung-uk Kim     }
122*f8146b88SJung-uk Kim }
123*f8146b88SJung-uk Kim 
124*f8146b88SJung-uk Kim 
125*f8146b88SJung-uk Kim /*******************************************************************************
126*f8146b88SJung-uk Kim  *
127*f8146b88SJung-uk Kim  * FUNCTION:    ExInsertArgCount
128*f8146b88SJung-uk Kim  *
129*f8146b88SJung-uk Kim  * PARAMETERS:  Op              - Op for a method invocation
130*f8146b88SJung-uk Kim  *
131*f8146b88SJung-uk Kim  * RETURN:      None
132*f8146b88SJung-uk Kim  *
133*f8146b88SJung-uk Kim  * DESCRIPTION: Obtain the number of arguments for a control method -- from
134*f8146b88SJung-uk Kim  *              the actual invocation.
135*f8146b88SJung-uk Kim  *
136*f8146b88SJung-uk Kim  ******************************************************************************/
137*f8146b88SJung-uk Kim 
138*f8146b88SJung-uk Kim static void
139*f8146b88SJung-uk Kim ExInsertArgCount (
140*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
141*f8146b88SJung-uk Kim {
142*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Next;
143*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *NameOp;
144*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Child;
145*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *ArgCountOp;
146*f8146b88SJung-uk Kim     char *                  ExternalName;
147*f8146b88SJung-uk Kim     char *                  CallName;
148*f8146b88SJung-uk Kim     UINT16                  ArgCount = 0;
149*f8146b88SJung-uk Kim     ACPI_STATUS             Status;
150*f8146b88SJung-uk Kim 
151*f8146b88SJung-uk Kim 
152*f8146b88SJung-uk Kim     CallName = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE);
153*f8146b88SJung-uk Kim 
154*f8146b88SJung-uk Kim     Next = Gbl_ExternalsListHead;
155*f8146b88SJung-uk Kim     while (Next)
156*f8146b88SJung-uk Kim     {
157*f8146b88SJung-uk Kim         ArgCount = 0;
158*f8146b88SJung-uk Kim 
159*f8146b88SJung-uk Kim         /* Skip if External node already handled */
160*f8146b88SJung-uk Kim 
161*f8146b88SJung-uk Kim         if (Next->Asl.Child->Asl.CompileFlags & NODE_VISITED)
162*f8146b88SJung-uk Kim         {
163*f8146b88SJung-uk Kim             Next = Next->Asl.Next;
164*f8146b88SJung-uk Kim             continue;
165*f8146b88SJung-uk Kim         }
166*f8146b88SJung-uk Kim 
167*f8146b88SJung-uk Kim         NameOp = Next->Asl.Child->Asl.Child;
168*f8146b88SJung-uk Kim         ExternalName = AcpiNsGetNormalizedPathname (NameOp->Asl.Node, TRUE);
169*f8146b88SJung-uk Kim 
170*f8146b88SJung-uk Kim         if (strcmp (CallName, ExternalName))
171*f8146b88SJung-uk Kim         {
172*f8146b88SJung-uk Kim             ACPI_FREE (ExternalName);
173*f8146b88SJung-uk Kim             Next = Next->Asl.Next;
174*f8146b88SJung-uk Kim             continue;
175*f8146b88SJung-uk Kim         }
176*f8146b88SJung-uk Kim 
177*f8146b88SJung-uk Kim         Next->Asl.Child->Asl.CompileFlags |= NODE_VISITED;
178*f8146b88SJung-uk Kim 
179*f8146b88SJung-uk Kim         /*
180*f8146b88SJung-uk Kim          * Since we will reposition Externals to the Root, set Namepath
181*f8146b88SJung-uk Kim          * to the fully qualified name and recalculate the aml length
182*f8146b88SJung-uk Kim          */
183*f8146b88SJung-uk Kim         Status = UtInternalizeName (ExternalName,
184*f8146b88SJung-uk Kim             &NameOp->Asl.Value.String);
185*f8146b88SJung-uk Kim 
186*f8146b88SJung-uk Kim         ACPI_FREE (ExternalName);
187*f8146b88SJung-uk Kim         if (ACPI_FAILURE (Status))
188*f8146b88SJung-uk Kim         {
189*f8146b88SJung-uk Kim             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
190*f8146b88SJung-uk Kim                 NULL, "- Could not Internalize External");
191*f8146b88SJung-uk Kim             break;
192*f8146b88SJung-uk Kim         }
193*f8146b88SJung-uk Kim 
194*f8146b88SJung-uk Kim         NameOp->Asl.AmlLength = strlen (NameOp->Asl.Value.String);
195*f8146b88SJung-uk Kim 
196*f8146b88SJung-uk Kim         /* Get argument count */
197*f8146b88SJung-uk Kim 
198*f8146b88SJung-uk Kim         Child = Op->Asl.Child;
199*f8146b88SJung-uk Kim         while (Child)
200*f8146b88SJung-uk Kim         {
201*f8146b88SJung-uk Kim             ArgCount++;
202*f8146b88SJung-uk Kim             Child = Child->Asl.Next;
203*f8146b88SJung-uk Kim         }
204*f8146b88SJung-uk Kim 
205*f8146b88SJung-uk Kim         /* Setup ArgCount operand */
206*f8146b88SJung-uk Kim 
207*f8146b88SJung-uk Kim         ArgCountOp = Next->Asl.Child->Asl.Child->Asl.Next->Asl.Next;
208*f8146b88SJung-uk Kim         ArgCountOp->Asl.Value.Integer = ArgCount;
209*f8146b88SJung-uk Kim         break;
210*f8146b88SJung-uk Kim     }
211*f8146b88SJung-uk Kim 
212*f8146b88SJung-uk Kim     ACPI_FREE (CallName);
213*f8146b88SJung-uk Kim }
214*f8146b88SJung-uk Kim 
215*f8146b88SJung-uk Kim 
216*f8146b88SJung-uk Kim /*******************************************************************************
217*f8146b88SJung-uk Kim  *
218*f8146b88SJung-uk Kim  * FUNCTION:    ExAmlExternalWalkBegin
219*f8146b88SJung-uk Kim  *
220*f8146b88SJung-uk Kim  * PARAMETERS:  ASL_WALK_CALLBACK
221*f8146b88SJung-uk Kim  *
222*f8146b88SJung-uk Kim  * RETURN:      None
223*f8146b88SJung-uk Kim  *
224*f8146b88SJung-uk Kim  * DESCRIPTION: Parse tree walk to create external opcode list for methods.
225*f8146b88SJung-uk Kim  *
226*f8146b88SJung-uk Kim  ******************************************************************************/
227*f8146b88SJung-uk Kim 
228*f8146b88SJung-uk Kim ACPI_STATUS
229*f8146b88SJung-uk Kim ExAmlExternalWalkBegin (
230*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
231*f8146b88SJung-uk Kim     UINT32                  Level,
232*f8146b88SJung-uk Kim     void                    *Context)
233*f8146b88SJung-uk Kim {
234*f8146b88SJung-uk Kim 
235*f8146b88SJung-uk Kim     /* External list head saved in the definition block op */
236*f8146b88SJung-uk Kim 
237*f8146b88SJung-uk Kim     if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)
238*f8146b88SJung-uk Kim     {
239*f8146b88SJung-uk Kim         Gbl_ExternalsListHead = Op->Asl.Value.Arg;
240*f8146b88SJung-uk Kim     }
241*f8146b88SJung-uk Kim 
242*f8146b88SJung-uk Kim     if (!Gbl_ExternalsListHead)
243*f8146b88SJung-uk Kim     {
244*f8146b88SJung-uk Kim         return (AE_OK);
245*f8146b88SJung-uk Kim     }
246*f8146b88SJung-uk Kim 
247*f8146b88SJung-uk Kim     if (Op->Asl.ParseOpcode != PARSEOP_METHODCALL)
248*f8146b88SJung-uk Kim     {
249*f8146b88SJung-uk Kim         return (AE_OK);
250*f8146b88SJung-uk Kim     }
251*f8146b88SJung-uk Kim 
252*f8146b88SJung-uk Kim     /*
253*f8146b88SJung-uk Kim      * The NameOp child under an ExternalOp gets turned into PARSE_METHODCALL
254*f8146b88SJung-uk Kim      * by XfNamespaceLocateBegin(). Ignore these.
255*f8146b88SJung-uk Kim      */
256*f8146b88SJung-uk Kim     if (Op->Asl.Parent &&
257*f8146b88SJung-uk Kim         Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_EXTERNAL)
258*f8146b88SJung-uk Kim     {
259*f8146b88SJung-uk Kim         return (AE_OK);
260*f8146b88SJung-uk Kim     }
261*f8146b88SJung-uk Kim 
262*f8146b88SJung-uk Kim     ExInsertArgCount (Op);
263*f8146b88SJung-uk Kim     return (AE_OK);
264*f8146b88SJung-uk Kim }
265*f8146b88SJung-uk Kim 
266*f8146b88SJung-uk Kim 
267*f8146b88SJung-uk Kim /*******************************************************************************
268*f8146b88SJung-uk Kim  *
269*f8146b88SJung-uk Kim  * FUNCTION:    ExAmlExternalWalkEnd
270*f8146b88SJung-uk Kim  *
271*f8146b88SJung-uk Kim  * PARAMETERS:  ASL_WALK_CALLBACK
272*f8146b88SJung-uk Kim  *
273*f8146b88SJung-uk Kim  * RETURN:      None
274*f8146b88SJung-uk Kim  *
275*f8146b88SJung-uk Kim  * DESCRIPTION: Parse tree walk to create external opcode list for methods.
276*f8146b88SJung-uk Kim  *              Here, we just want to catch the case where a definition block
277*f8146b88SJung-uk Kim  *              has been completed. Then we move all of the externals into
278*f8146b88SJung-uk Kim  *              a single block in the parse tree and thus the AML code.
279*f8146b88SJung-uk Kim  *
280*f8146b88SJung-uk Kim  ******************************************************************************/
281*f8146b88SJung-uk Kim 
282*f8146b88SJung-uk Kim ACPI_STATUS
283*f8146b88SJung-uk Kim ExAmlExternalWalkEnd (
284*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
285*f8146b88SJung-uk Kim     UINT32                  Level,
286*f8146b88SJung-uk Kim     void                    *Context)
287*f8146b88SJung-uk Kim {
288*f8146b88SJung-uk Kim 
289*f8146b88SJung-uk Kim     if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)
290*f8146b88SJung-uk Kim     {
291*f8146b88SJung-uk Kim         /*
292*f8146b88SJung-uk Kim          * Process any existing external list. (Support for
293*f8146b88SJung-uk Kim          * multiple definition blocks in a single file/compile)
294*f8146b88SJung-uk Kim          */
295*f8146b88SJung-uk Kim         ExMoveExternals (Op);
296*f8146b88SJung-uk Kim         Gbl_ExternalsListHead = NULL;
297*f8146b88SJung-uk Kim     }
298*f8146b88SJung-uk Kim 
299*f8146b88SJung-uk Kim     return (AE_OK);
300*f8146b88SJung-uk Kim }
301*f8146b88SJung-uk Kim 
302*f8146b88SJung-uk Kim 
303*f8146b88SJung-uk Kim /*******************************************************************************
304*f8146b88SJung-uk Kim  *
305*f8146b88SJung-uk Kim  * FUNCTION:    ExMoveExternals
306*f8146b88SJung-uk Kim  *
307*f8146b88SJung-uk Kim  * PARAMETERS:  DefinitionBlockOp       - Op for current definition block
308*f8146b88SJung-uk Kim  *
309*f8146b88SJung-uk Kim  * RETURN:      None
310*f8146b88SJung-uk Kim  *
311*f8146b88SJung-uk Kim  * DESCRIPTION: Move all externals present in the source file into a single
312*f8146b88SJung-uk Kim  *              block of AML code, surrounded by an "If (0)" to prevent
313*f8146b88SJung-uk Kim  *              AML interpreters from attempting to execute the External
314*f8146b88SJung-uk Kim  *              opcodes.
315*f8146b88SJung-uk Kim  *
316*f8146b88SJung-uk Kim  ******************************************************************************/
317*f8146b88SJung-uk Kim 
318*f8146b88SJung-uk Kim static void
319*f8146b88SJung-uk Kim ExMoveExternals (
320*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *DefinitionBlockOp)
321*f8146b88SJung-uk Kim {
322*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *ParentOp;
323*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *ExternalOp;
324*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *PredicateOp;
325*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *NextOp;
326*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Prev;
327*f8146b88SJung-uk Kim     ACPI_PARSE_OBJECT       *Next;
328*f8146b88SJung-uk Kim     ACPI_OBJECT_TYPE        ObjType;
329*f8146b88SJung-uk Kim     UINT32                  i;
330*f8146b88SJung-uk Kim 
331*f8146b88SJung-uk Kim 
332*f8146b88SJung-uk Kim     if (!Gbl_ExternalsListHead)
333*f8146b88SJung-uk Kim     {
334*f8146b88SJung-uk Kim         return;
335*f8146b88SJung-uk Kim     }
336*f8146b88SJung-uk Kim 
337*f8146b88SJung-uk Kim     /* Remove the External nodes from the tree */
338*f8146b88SJung-uk Kim 
339*f8146b88SJung-uk Kim     NextOp = Gbl_ExternalsListHead;
340*f8146b88SJung-uk Kim     while (NextOp)
341*f8146b88SJung-uk Kim     {
342*f8146b88SJung-uk Kim         /*
343*f8146b88SJung-uk Kim          * The External is stored in child pointer of each node in the
344*f8146b88SJung-uk Kim          * list
345*f8146b88SJung-uk Kim          */
346*f8146b88SJung-uk Kim         ExternalOp = NextOp->Asl.Child;
347*f8146b88SJung-uk Kim 
348*f8146b88SJung-uk Kim         /* Set line numbers (for listings, etc.) */
349*f8146b88SJung-uk Kim 
350*f8146b88SJung-uk Kim         ExternalOp->Asl.LineNumber = 0;
351*f8146b88SJung-uk Kim         ExternalOp->Asl.LogicalLineNumber = 0;
352*f8146b88SJung-uk Kim 
353*f8146b88SJung-uk Kim         Next = ExternalOp->Asl.Child;
354*f8146b88SJung-uk Kim         Next->Asl.LineNumber = 0;
355*f8146b88SJung-uk Kim         Next->Asl.LogicalLineNumber = 0;
356*f8146b88SJung-uk Kim 
357*f8146b88SJung-uk Kim         Next = Next->Asl.Next;
358*f8146b88SJung-uk Kim         Next->Asl.LineNumber = 0;
359*f8146b88SJung-uk Kim         Next->Asl.LogicalLineNumber = 0;
360*f8146b88SJung-uk Kim 
361*f8146b88SJung-uk Kim         Next = Next->Asl.Next;
362*f8146b88SJung-uk Kim         Next->Asl.LineNumber = 0;
363*f8146b88SJung-uk Kim         Next->Asl.LogicalLineNumber = 0;
364*f8146b88SJung-uk Kim 
365*f8146b88SJung-uk Kim         Next = Next->Asl.Next;
366*f8146b88SJung-uk Kim         Next->Asl.LineNumber = 0;
367*f8146b88SJung-uk Kim         Next->Asl.LogicalLineNumber = 0;
368*f8146b88SJung-uk Kim 
369*f8146b88SJung-uk Kim         ParentOp = ExternalOp->Asl.Parent;
370*f8146b88SJung-uk Kim         Prev = Next = ParentOp->Asl.Child;
371*f8146b88SJung-uk Kim 
372*f8146b88SJung-uk Kim         /* Now find the External node's position in parse tree */
373*f8146b88SJung-uk Kim 
374*f8146b88SJung-uk Kim         while (Next != ExternalOp)
375*f8146b88SJung-uk Kim         {
376*f8146b88SJung-uk Kim             Prev = Next;
377*f8146b88SJung-uk Kim             Next = Next->Asl.Next;
378*f8146b88SJung-uk Kim         }
379*f8146b88SJung-uk Kim 
380*f8146b88SJung-uk Kim         /* Remove the External from the parse tree */
381*f8146b88SJung-uk Kim 
382*f8146b88SJung-uk Kim         if (Prev == ExternalOp)
383*f8146b88SJung-uk Kim         {
384*f8146b88SJung-uk Kim             /* External was the first child node */
385*f8146b88SJung-uk Kim 
386*f8146b88SJung-uk Kim             ParentOp->Asl.Child = ExternalOp->Asl.Next;
387*f8146b88SJung-uk Kim         }
388*f8146b88SJung-uk Kim 
389*f8146b88SJung-uk Kim         Prev->Asl.Next = ExternalOp->Asl.Next;
390*f8146b88SJung-uk Kim         ExternalOp->Asl.Next = NULL;
391*f8146b88SJung-uk Kim         ExternalOp->Asl.Parent = Gbl_ExternalsListHead;
392*f8146b88SJung-uk Kim 
393*f8146b88SJung-uk Kim         /* Point the External to the next in the list */
394*f8146b88SJung-uk Kim 
395*f8146b88SJung-uk Kim         if (NextOp->Asl.Next)
396*f8146b88SJung-uk Kim         {
397*f8146b88SJung-uk Kim             ExternalOp->Asl.Next = NextOp->Asl.Next->Asl.Child;
398*f8146b88SJung-uk Kim         }
399*f8146b88SJung-uk Kim 
400*f8146b88SJung-uk Kim         NextOp = NextOp->Asl.Next;
401*f8146b88SJung-uk Kim     }
402*f8146b88SJung-uk Kim 
403*f8146b88SJung-uk Kim     /*
404*f8146b88SJung-uk Kim      * Loop again to remove MethodObj Externals for which
405*f8146b88SJung-uk Kim      * a MethodCall was not found (dead external reference)
406*f8146b88SJung-uk Kim      */
407*f8146b88SJung-uk Kim     Prev = Gbl_ExternalsListHead->Asl.Child;
408*f8146b88SJung-uk Kim     Next = Prev;
409*f8146b88SJung-uk Kim     while (Next)
410*f8146b88SJung-uk Kim     {
411*f8146b88SJung-uk Kim         ObjType = (ACPI_OBJECT_TYPE)
412*f8146b88SJung-uk Kim             Next->Asl.Child->Asl.Next->Asl.Value.Integer;
413*f8146b88SJung-uk Kim 
414*f8146b88SJung-uk Kim         if (ObjType == ACPI_TYPE_METHOD &&
415*f8146b88SJung-uk Kim             !(Next->Asl.CompileFlags & NODE_VISITED))
416*f8146b88SJung-uk Kim         {
417*f8146b88SJung-uk Kim             if (Next == Prev)
418*f8146b88SJung-uk Kim             {
419*f8146b88SJung-uk Kim                 Gbl_ExternalsListHead->Asl.Child = Next->Asl.Next;
420*f8146b88SJung-uk Kim                 Next->Asl.Next = NULL;
421*f8146b88SJung-uk Kim                 Prev = Gbl_ExternalsListHead->Asl.Child;
422*f8146b88SJung-uk Kim                 Next = Prev;
423*f8146b88SJung-uk Kim                 continue;
424*f8146b88SJung-uk Kim             }
425*f8146b88SJung-uk Kim             else
426*f8146b88SJung-uk Kim             {
427*f8146b88SJung-uk Kim                 Prev->Asl.Next = Next->Asl.Next;
428*f8146b88SJung-uk Kim                 Next->Asl.Next = NULL;
429*f8146b88SJung-uk Kim                 Next = Prev->Asl.Next;
430*f8146b88SJung-uk Kim                 continue;
431*f8146b88SJung-uk Kim             }
432*f8146b88SJung-uk Kim         }
433*f8146b88SJung-uk Kim 
434*f8146b88SJung-uk Kim         Prev = Next;
435*f8146b88SJung-uk Kim         Next = Next->Asl.Next;
436*f8146b88SJung-uk Kim     }
437*f8146b88SJung-uk Kim 
438*f8146b88SJung-uk Kim     /* If list is now empty, don't bother to make If (0) block */
439*f8146b88SJung-uk Kim 
440*f8146b88SJung-uk Kim     if (!Gbl_ExternalsListHead->Asl.Child)
441*f8146b88SJung-uk Kim     {
442*f8146b88SJung-uk Kim         return;
443*f8146b88SJung-uk Kim     }
444*f8146b88SJung-uk Kim 
445*f8146b88SJung-uk Kim     /* Convert Gbl_ExternalsListHead parent to If(). */
446*f8146b88SJung-uk Kim 
447*f8146b88SJung-uk Kim     Gbl_ExternalsListHead->Asl.ParseOpcode = PARSEOP_IF;
448*f8146b88SJung-uk Kim     Gbl_ExternalsListHead->Asl.AmlOpcode = AML_IF_OP;
449*f8146b88SJung-uk Kim     Gbl_ExternalsListHead->Asl.CompileFlags = NODE_AML_PACKAGE;
450*f8146b88SJung-uk Kim     UtSetParseOpName (Gbl_ExternalsListHead);
451*f8146b88SJung-uk Kim 
452*f8146b88SJung-uk Kim     /* Create a Zero op for the If predicate */
453*f8146b88SJung-uk Kim 
454*f8146b88SJung-uk Kim     PredicateOp = TrAllocateNode (PARSEOP_ZERO);
455*f8146b88SJung-uk Kim     PredicateOp->Asl.AmlOpcode = AML_ZERO_OP;
456*f8146b88SJung-uk Kim 
457*f8146b88SJung-uk Kim     PredicateOp->Asl.Parent = Gbl_ExternalsListHead;
458*f8146b88SJung-uk Kim     PredicateOp->Asl.Child = NULL;
459*f8146b88SJung-uk Kim     PredicateOp->Asl.Next = Gbl_ExternalsListHead->Asl.Child;
460*f8146b88SJung-uk Kim     Gbl_ExternalsListHead->Asl.Child = PredicateOp;
461*f8146b88SJung-uk Kim 
462*f8146b88SJung-uk Kim     /* Set line numbers (for listings, etc.) */
463*f8146b88SJung-uk Kim 
464*f8146b88SJung-uk Kim     Gbl_ExternalsListHead->Asl.LineNumber = 0;
465*f8146b88SJung-uk Kim     Gbl_ExternalsListHead->Asl.LogicalLineNumber = 0;
466*f8146b88SJung-uk Kim 
467*f8146b88SJung-uk Kim     PredicateOp->Asl.LineNumber = 0;
468*f8146b88SJung-uk Kim     PredicateOp->Asl.LogicalLineNumber = 0;
469*f8146b88SJung-uk Kim 
470*f8146b88SJung-uk Kim     /* Insert block back in the list */
471*f8146b88SJung-uk Kim 
472*f8146b88SJung-uk Kim     Prev = DefinitionBlockOp->Asl.Child;
473*f8146b88SJung-uk Kim     Next = Prev;
474*f8146b88SJung-uk Kim 
475*f8146b88SJung-uk Kim     /* Find last default arg */
476*f8146b88SJung-uk Kim 
477*f8146b88SJung-uk Kim     for (i = 0; i < 6; i++)
478*f8146b88SJung-uk Kim     {
479*f8146b88SJung-uk Kim         Prev = Next;
480*f8146b88SJung-uk Kim         Next = Prev->Asl.Next;
481*f8146b88SJung-uk Kim     }
482*f8146b88SJung-uk Kim 
483*f8146b88SJung-uk Kim     if (Next)
484*f8146b88SJung-uk Kim     {
485*f8146b88SJung-uk Kim         /* Definition Block is not empty */
486*f8146b88SJung-uk Kim 
487*f8146b88SJung-uk Kim         Gbl_ExternalsListHead->Asl.Next = Next;
488*f8146b88SJung-uk Kim     }
489*f8146b88SJung-uk Kim     else
490*f8146b88SJung-uk Kim     {
491*f8146b88SJung-uk Kim         /* Definition Block is empty. */
492*f8146b88SJung-uk Kim 
493*f8146b88SJung-uk Kim         Gbl_ExternalsListHead->Asl.Next = NULL;
494*f8146b88SJung-uk Kim     }
495*f8146b88SJung-uk Kim 
496*f8146b88SJung-uk Kim     Prev->Asl.Next = Gbl_ExternalsListHead;
497*f8146b88SJung-uk Kim     Gbl_ExternalsListHead->Asl.Parent = Prev->Asl.Parent;
498*f8146b88SJung-uk Kim }
499