xref: /illumos-gate/usr/src/cmd/acpi/iasl/aslmethod.c (revision 35786f68)
1bc36eafdSMike Gerdts /******************************************************************************
2bc36eafdSMike Gerdts  *
3bc36eafdSMike Gerdts  * Module Name: aslmethod.c - Control method analysis walk
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 "aslcompiler.h"
153bc36eafdSMike Gerdts #include "aslcompiler.y.h"
154bc36eafdSMike Gerdts #include "acparser.h"
155bc36eafdSMike Gerdts #include "amlcode.h"
156bc36eafdSMike Gerdts 
157bc36eafdSMike Gerdts 
158bc36eafdSMike Gerdts #define _COMPONENT          ACPI_COMPILER
159bc36eafdSMike Gerdts         ACPI_MODULE_NAME    ("aslmethod")
160bc36eafdSMike Gerdts 
161bc36eafdSMike Gerdts 
162bc36eafdSMike Gerdts /* Local prototypes */
163bc36eafdSMike Gerdts 
164bc36eafdSMike Gerdts static void
165bc36eafdSMike Gerdts MtCheckNamedObjectInMethod (
166bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *Op,
167bc36eafdSMike Gerdts     ASL_METHOD_INFO         *MethodInfo);
168bc36eafdSMike Gerdts 
169bc36eafdSMike Gerdts 
170bc36eafdSMike Gerdts /*******************************************************************************
171bc36eafdSMike Gerdts  *
172bc36eafdSMike Gerdts  * FUNCTION:    MtMethodAnalysisWalkBegin
173bc36eafdSMike Gerdts  *
174bc36eafdSMike Gerdts  * PARAMETERS:  ASL_WALK_CALLBACK
175bc36eafdSMike Gerdts  *
176bc36eafdSMike Gerdts  * RETURN:      Status
177bc36eafdSMike Gerdts  *
178bc36eafdSMike Gerdts  * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
179bc36eafdSMike Gerdts  *              1) Initialized local variables
180bc36eafdSMike Gerdts  *              2) Valid arguments
181bc36eafdSMike Gerdts  *              3) Return types
182bc36eafdSMike Gerdts  *
183bc36eafdSMike Gerdts  ******************************************************************************/
184bc36eafdSMike Gerdts 
185bc36eafdSMike Gerdts ACPI_STATUS
MtMethodAnalysisWalkBegin(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)186bc36eafdSMike Gerdts MtMethodAnalysisWalkBegin (
187bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *Op,
188bc36eafdSMike Gerdts     UINT32                  Level,
189bc36eafdSMike Gerdts     void                    *Context)
190bc36eafdSMike Gerdts {
191bc36eafdSMike Gerdts     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
192bc36eafdSMike Gerdts     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
193bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *Next;
194bc36eafdSMike Gerdts     UINT32                  RegisterNumber;
195bc36eafdSMike Gerdts     UINT32                  i;
196bc36eafdSMike Gerdts     char                    LocalName[] = "Local0";
197bc36eafdSMike Gerdts     char                    ArgName[] = "Arg0";
198bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *ArgNode;
199bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *NextType;
200bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *NextParamType;
201bc36eafdSMike Gerdts     UINT8                   ActualArgs = 0;
202bc36eafdSMike Gerdts 
203bc36eafdSMike Gerdts 
204bc36eafdSMike Gerdts     /* Build cross-reference output file if requested */
205bc36eafdSMike Gerdts 
206bc36eafdSMike Gerdts     if (Gbl_CrossReferenceOutput)
207bc36eafdSMike Gerdts     {
208bc36eafdSMike Gerdts         OtXrefWalkPart1 (Op, Level, MethodInfo);
209bc36eafdSMike Gerdts     }
210bc36eafdSMike Gerdts 
211bc36eafdSMike Gerdts     switch (Op->Asl.ParseOpcode)
212bc36eafdSMike Gerdts     {
213bc36eafdSMike Gerdts     case PARSEOP_METHOD:
214bc36eafdSMike Gerdts 
215bc36eafdSMike Gerdts         TotalMethods++;
216bc36eafdSMike Gerdts 
217bc36eafdSMike Gerdts         /* Create and init method info */
218bc36eafdSMike Gerdts 
219bc36eafdSMike Gerdts         MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
220bc36eafdSMike Gerdts         MethodInfo->Next = WalkInfo->MethodStack;
221bc36eafdSMike Gerdts         MethodInfo->Op = Op;
222bc36eafdSMike Gerdts 
223bc36eafdSMike Gerdts         WalkInfo->MethodStack = MethodInfo;
224bc36eafdSMike Gerdts 
225bc36eafdSMike Gerdts         /*
226bc36eafdSMike Gerdts          * Special handling for _PSx methods. Dependency rules (same scope):
227bc36eafdSMike Gerdts          *
228bc36eafdSMike Gerdts          * 1) _PS0 - One of these must exist: _PS1, _PS2, _PS3
229bc36eafdSMike Gerdts          * 2) _PS1/_PS2/_PS3: A _PS0 must exist
230bc36eafdSMike Gerdts          */
231bc36eafdSMike Gerdts         if (ACPI_COMPARE_NAME (METHOD_NAME__PS0, Op->Asl.NameSeg))
232bc36eafdSMike Gerdts         {
233bc36eafdSMike Gerdts             /* For _PS0, one of _PS1/_PS2/_PS3 must exist */
234bc36eafdSMike Gerdts 
235bc36eafdSMike Gerdts             if ((!ApFindNameInScope (METHOD_NAME__PS1, Op)) &&
236bc36eafdSMike Gerdts                 (!ApFindNameInScope (METHOD_NAME__PS2, Op)) &&
237bc36eafdSMike Gerdts                 (!ApFindNameInScope (METHOD_NAME__PS3, Op)))
238bc36eafdSMike Gerdts             {
239bc36eafdSMike Gerdts                 AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
240bc36eafdSMike Gerdts                     "_PS0 requires one of _PS1/_PS2/_PS3 in same scope");
241bc36eafdSMike Gerdts             }
242bc36eafdSMike Gerdts         }
243bc36eafdSMike Gerdts         else if (
244bc36eafdSMike Gerdts             ACPI_COMPARE_NAME (METHOD_NAME__PS1, Op->Asl.NameSeg) ||
245bc36eafdSMike Gerdts             ACPI_COMPARE_NAME (METHOD_NAME__PS2, Op->Asl.NameSeg) ||
246bc36eafdSMike Gerdts             ACPI_COMPARE_NAME (METHOD_NAME__PS3, Op->Asl.NameSeg))
247bc36eafdSMike Gerdts         {
248bc36eafdSMike Gerdts             /* For _PS1/_PS2/_PS3, a _PS0 must exist */
249bc36eafdSMike Gerdts 
250bc36eafdSMike Gerdts             if (!ApFindNameInScope (METHOD_NAME__PS0, Op))
251bc36eafdSMike Gerdts             {
252bc36eafdSMike Gerdts                 sprintf (MsgBuffer,
253bc36eafdSMike Gerdts                     "%4.4s requires _PS0 in same scope", Op->Asl.NameSeg);
254bc36eafdSMike Gerdts 
255bc36eafdSMike Gerdts                 AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
256bc36eafdSMike Gerdts                     MsgBuffer);
257bc36eafdSMike Gerdts             }
258bc36eafdSMike Gerdts         }
259bc36eafdSMike Gerdts 
260bc36eafdSMike Gerdts         /* Get the name node */
261bc36eafdSMike Gerdts 
262bc36eafdSMike Gerdts         Next = Op->Asl.Child;
263bc36eafdSMike Gerdts 
264bc36eafdSMike Gerdts         /* Get the NumArguments node */
265bc36eafdSMike Gerdts 
266bc36eafdSMike Gerdts         Next = Next->Asl.Next;
267bc36eafdSMike Gerdts         MethodInfo->NumArguments = (UINT8)
268bc36eafdSMike Gerdts             (((UINT8) Next->Asl.Value.Integer) & 0x07);
269bc36eafdSMike Gerdts 
270bc36eafdSMike Gerdts         /* Get the SerializeRule and SyncLevel nodes, ignored here */
271bc36eafdSMike Gerdts 
272bc36eafdSMike Gerdts         Next = Next->Asl.Next;
273bc36eafdSMike Gerdts         MethodInfo->ShouldBeSerialized = (UINT8) Next->Asl.Value.Integer;
274bc36eafdSMike Gerdts 
275bc36eafdSMike Gerdts         Next = Next->Asl.Next;
276bc36eafdSMike Gerdts         ArgNode = Next;
277bc36eafdSMike Gerdts 
278bc36eafdSMike Gerdts         /* Get the ReturnType node */
279bc36eafdSMike Gerdts 
280bc36eafdSMike Gerdts         Next = Next->Asl.Next;
281bc36eafdSMike Gerdts 
282bc36eafdSMike Gerdts         NextType = Next->Asl.Child;
283bc36eafdSMike Gerdts         while (NextType)
284bc36eafdSMike Gerdts         {
285bc36eafdSMike Gerdts             /* Get and map each of the ReturnTypes */
286bc36eafdSMike Gerdts 
287bc36eafdSMike Gerdts             MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
288bc36eafdSMike Gerdts             NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
289bc36eafdSMike Gerdts             NextType = NextType->Asl.Next;
290bc36eafdSMike Gerdts         }
291bc36eafdSMike Gerdts 
292bc36eafdSMike Gerdts         /* Get the ParameterType node */
293bc36eafdSMike Gerdts 
294bc36eafdSMike Gerdts         Next = Next->Asl.Next;
295bc36eafdSMike Gerdts 
296bc36eafdSMike Gerdts         NextType = Next->Asl.Child;
297bc36eafdSMike Gerdts         while (NextType)
298bc36eafdSMike Gerdts         {
299bc36eafdSMike Gerdts             if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
300bc36eafdSMike Gerdts             {
301bc36eafdSMike Gerdts                 NextParamType = NextType->Asl.Child;
302bc36eafdSMike Gerdts                 while (NextParamType)
303bc36eafdSMike Gerdts                 {
304bc36eafdSMike Gerdts                     MethodInfo->ValidArgTypes[ActualArgs] |=
305bc36eafdSMike Gerdts                         AnMapObjTypeToBtype (NextParamType);
306bc36eafdSMike Gerdts 
307bc36eafdSMike Gerdts                     NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
308bc36eafdSMike Gerdts                     NextParamType = NextParamType->Asl.Next;
309bc36eafdSMike Gerdts                 }
310bc36eafdSMike Gerdts             }
311bc36eafdSMike Gerdts             else
312bc36eafdSMike Gerdts             {
313bc36eafdSMike Gerdts                 MethodInfo->ValidArgTypes[ActualArgs] =
314bc36eafdSMike Gerdts                     AnMapObjTypeToBtype (NextType);
315bc36eafdSMike Gerdts 
316bc36eafdSMike Gerdts                 NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
317bc36eafdSMike Gerdts                 ActualArgs++;
318bc36eafdSMike Gerdts             }
319bc36eafdSMike Gerdts 
320bc36eafdSMike Gerdts             NextType = NextType->Asl.Next;
321bc36eafdSMike Gerdts         }
322bc36eafdSMike Gerdts 
323bc36eafdSMike Gerdts         if ((MethodInfo->NumArguments) &&
324bc36eafdSMike Gerdts             (MethodInfo->NumArguments != ActualArgs))
325bc36eafdSMike Gerdts         {
326bc36eafdSMike Gerdts             /* error: Param list did not match number of args */
327bc36eafdSMike Gerdts         }
328bc36eafdSMike Gerdts 
329bc36eafdSMike Gerdts         /* Allow numarguments == 0 for Function() */
330bc36eafdSMike Gerdts 
331bc36eafdSMike Gerdts         if ((!MethodInfo->NumArguments) && (ActualArgs))
332bc36eafdSMike Gerdts         {
333bc36eafdSMike Gerdts             MethodInfo->NumArguments = ActualArgs;
334bc36eafdSMike Gerdts             ArgNode->Asl.Value.Integer |= ActualArgs;
335bc36eafdSMike Gerdts         }
336bc36eafdSMike Gerdts 
337bc36eafdSMike Gerdts         /*
338bc36eafdSMike Gerdts          * Actual arguments are initialized at method entry.
339bc36eafdSMike Gerdts          * All other ArgX "registers" can be used as locals, so we
340bc36eafdSMike Gerdts          * track their initialization.
341bc36eafdSMike Gerdts          */
342bc36eafdSMike Gerdts         for (i = 0; i < MethodInfo->NumArguments; i++)
343bc36eafdSMike Gerdts         {
344bc36eafdSMike Gerdts             MethodInfo->ArgInitialized[i] = TRUE;
345bc36eafdSMike Gerdts         }
346bc36eafdSMike Gerdts         break;
347bc36eafdSMike Gerdts 
348bc36eafdSMike Gerdts     case PARSEOP_METHODCALL:
349bc36eafdSMike Gerdts 
350*35786f68SRobert Mustacchi         /* Check for a recursive method call */
351*35786f68SRobert Mustacchi 
352bc36eafdSMike Gerdts         if (MethodInfo &&
353bc36eafdSMike Gerdts            (Op->Asl.Node == MethodInfo->Op->Asl.Node))
354bc36eafdSMike Gerdts         {
355*35786f68SRobert Mustacchi             if (MethodInfo->CreatesNamedObjects)
356*35786f68SRobert Mustacchi             {
357*35786f68SRobert Mustacchi                 /*
358*35786f68SRobert Mustacchi                  * This is an error, as it will fail at runtime on all ACPI
359*35786f68SRobert Mustacchi                  * implementations. Any named object declarations will be
360*35786f68SRobert Mustacchi                  * executed twice, causing failure the second time. Note,
361*35786f68SRobert Mustacchi                  * this is independent of whether the method is declared
362*35786f68SRobert Mustacchi                  * Serialized, because the same thread is attempting to
363*35786f68SRobert Mustacchi                  * reenter the method, and this will always succeed.
364*35786f68SRobert Mustacchi                  */
365*35786f68SRobert Mustacchi                 AslDualParseOpError (ASL_ERROR, ASL_MSG_ILLEGAL_RECURSION, Op,
366*35786f68SRobert Mustacchi                     Op->Asl.Value.String, ASL_MSG_FOUND_HERE, MethodInfo->Op,
367*35786f68SRobert Mustacchi                     MethodInfo->Op->Asl.ExternalName);
368*35786f68SRobert Mustacchi             }
369*35786f68SRobert Mustacchi             else
370*35786f68SRobert Mustacchi             {
371*35786f68SRobert Mustacchi                 /* Method does not create objects, issue a remark */
372*35786f68SRobert Mustacchi 
373*35786f68SRobert Mustacchi                 AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
374*35786f68SRobert Mustacchi             }
375bc36eafdSMike Gerdts         }
376bc36eafdSMike Gerdts         break;
377bc36eafdSMike Gerdts 
378bc36eafdSMike Gerdts     case PARSEOP_LOCAL0:
379bc36eafdSMike Gerdts     case PARSEOP_LOCAL1:
380bc36eafdSMike Gerdts     case PARSEOP_LOCAL2:
381bc36eafdSMike Gerdts     case PARSEOP_LOCAL3:
382bc36eafdSMike Gerdts     case PARSEOP_LOCAL4:
383bc36eafdSMike Gerdts     case PARSEOP_LOCAL5:
384bc36eafdSMike Gerdts     case PARSEOP_LOCAL6:
385bc36eafdSMike Gerdts     case PARSEOP_LOCAL7:
386bc36eafdSMike Gerdts 
387bc36eafdSMike Gerdts         if (!MethodInfo)
388bc36eafdSMike Gerdts         {
389bc36eafdSMike Gerdts             /*
390bc36eafdSMike Gerdts              * Local was used outside a control method, or there was an error
391bc36eafdSMike Gerdts              * in the method declaration.
392bc36eafdSMike Gerdts              */
393bc36eafdSMike Gerdts             AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD,
394bc36eafdSMike Gerdts                 Op, Op->Asl.ExternalName);
395bc36eafdSMike Gerdts             return (AE_ERROR);
396bc36eafdSMike Gerdts         }
397bc36eafdSMike Gerdts 
398bc36eafdSMike Gerdts         RegisterNumber = (Op->Asl.AmlOpcode & 0x0007);
399bc36eafdSMike Gerdts 
400bc36eafdSMike Gerdts         /*
401bc36eafdSMike Gerdts          * If the local is being used as a target, mark the local
402bc36eafdSMike Gerdts          * initialized
403bc36eafdSMike Gerdts          */
404*35786f68SRobert Mustacchi         if (Op->Asl.CompileFlags & OP_IS_TARGET)
405bc36eafdSMike Gerdts         {
406bc36eafdSMike Gerdts             MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
407bc36eafdSMike Gerdts         }
408bc36eafdSMike Gerdts 
409bc36eafdSMike Gerdts         /*
410bc36eafdSMike Gerdts          * Otherwise, this is a reference, check if the local
411bc36eafdSMike Gerdts          * has been previously initialized.
412bc36eafdSMike Gerdts          *
413bc36eafdSMike Gerdts          * The only operator that accepts an uninitialized value is ObjectType()
414bc36eafdSMike Gerdts          */
415bc36eafdSMike Gerdts         else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
416bc36eafdSMike Gerdts                  (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
417bc36eafdSMike Gerdts         {
418bc36eafdSMike Gerdts             LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
419bc36eafdSMike Gerdts             AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
420bc36eafdSMike Gerdts         }
421bc36eafdSMike Gerdts         break;
422bc36eafdSMike Gerdts 
423bc36eafdSMike Gerdts     case PARSEOP_ARG0:
424bc36eafdSMike Gerdts     case PARSEOP_ARG1:
425bc36eafdSMike Gerdts     case PARSEOP_ARG2:
426bc36eafdSMike Gerdts     case PARSEOP_ARG3:
427bc36eafdSMike Gerdts     case PARSEOP_ARG4:
428bc36eafdSMike Gerdts     case PARSEOP_ARG5:
429bc36eafdSMike Gerdts     case PARSEOP_ARG6:
430bc36eafdSMike Gerdts 
431bc36eafdSMike Gerdts         if (!MethodInfo)
432bc36eafdSMike Gerdts         {
433bc36eafdSMike Gerdts             /*
434bc36eafdSMike Gerdts              * Arg was used outside a control method, or there was an error
435bc36eafdSMike Gerdts              * in the method declaration.
436bc36eafdSMike Gerdts              */
437bc36eafdSMike Gerdts             AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD,
438bc36eafdSMike Gerdts                 Op, Op->Asl.ExternalName);
439bc36eafdSMike Gerdts             return (AE_ERROR);
440bc36eafdSMike Gerdts         }
441bc36eafdSMike Gerdts 
442bc36eafdSMike Gerdts         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
443bc36eafdSMike Gerdts         ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
444bc36eafdSMike Gerdts 
445bc36eafdSMike Gerdts         /*
446bc36eafdSMike Gerdts          * If the Arg is being used as a target, mark the local
447bc36eafdSMike Gerdts          * initialized
448bc36eafdSMike Gerdts          */
449*35786f68SRobert Mustacchi         if (Op->Asl.CompileFlags & OP_IS_TARGET)
450bc36eafdSMike Gerdts         {
451bc36eafdSMike Gerdts             MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
452bc36eafdSMike Gerdts         }
453bc36eafdSMike Gerdts 
454bc36eafdSMike Gerdts         /*
455bc36eafdSMike Gerdts          * Otherwise, this is a reference, check if the Arg
456bc36eafdSMike Gerdts          * has been previously initialized.
457bc36eafdSMike Gerdts          *
458bc36eafdSMike Gerdts          * The only operator that accepts an uninitialized value is ObjectType()
459bc36eafdSMike Gerdts          */
460bc36eafdSMike Gerdts         else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
461bc36eafdSMike Gerdts             (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
462bc36eafdSMike Gerdts         {
463bc36eafdSMike Gerdts             AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
464bc36eafdSMike Gerdts         }
465bc36eafdSMike Gerdts 
466bc36eafdSMike Gerdts         /* Flag this arg if it is not a "real" argument to the method */
467bc36eafdSMike Gerdts 
468bc36eafdSMike Gerdts         if (RegisterNumber >= MethodInfo->NumArguments)
469bc36eafdSMike Gerdts         {
470bc36eafdSMike Gerdts             AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
471bc36eafdSMike Gerdts         }
472bc36eafdSMike Gerdts         break;
473bc36eafdSMike Gerdts 
474bc36eafdSMike Gerdts     case PARSEOP_RETURN:
475bc36eafdSMike Gerdts 
476bc36eafdSMike Gerdts         if (!MethodInfo)
477bc36eafdSMike Gerdts         {
478bc36eafdSMike Gerdts             /*
479bc36eafdSMike Gerdts              * Probably was an error in the method declaration,
480bc36eafdSMike Gerdts              * no additional error here
481bc36eafdSMike Gerdts              */
482bc36eafdSMike Gerdts             ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
483bc36eafdSMike Gerdts             return (AE_ERROR);
484bc36eafdSMike Gerdts         }
485bc36eafdSMike Gerdts 
486bc36eafdSMike Gerdts         /*
487bc36eafdSMike Gerdts          * A child indicates a possible return value. A simple Return or
488*35786f68SRobert Mustacchi          * Return() is marked with OP_IS_NULL_RETURN by the parser so
489bc36eafdSMike Gerdts          * that it is not counted as a "real" return-with-value, although
490bc36eafdSMike Gerdts          * the AML code that is actually emitted is Return(0). The AML
491bc36eafdSMike Gerdts          * definition of Return has a required parameter, so we are
492bc36eafdSMike Gerdts          * forced to convert a null return to Return(0).
493bc36eafdSMike Gerdts          */
494bc36eafdSMike Gerdts         if ((Op->Asl.Child) &&
495bc36eafdSMike Gerdts             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
496*35786f68SRobert Mustacchi             (!(Op->Asl.Child->Asl.CompileFlags & OP_IS_NULL_RETURN)))
497bc36eafdSMike Gerdts         {
498bc36eafdSMike Gerdts             MethodInfo->NumReturnWithValue++;
499bc36eafdSMike Gerdts         }
500bc36eafdSMike Gerdts         else
501bc36eafdSMike Gerdts         {
502bc36eafdSMike Gerdts             MethodInfo->NumReturnNoValue++;
503bc36eafdSMike Gerdts         }
504bc36eafdSMike Gerdts         break;
505bc36eafdSMike Gerdts 
506bc36eafdSMike Gerdts     case PARSEOP_BREAK:
507bc36eafdSMike Gerdts     case PARSEOP_CONTINUE:
508bc36eafdSMike Gerdts 
509bc36eafdSMike Gerdts         Next = Op->Asl.Parent;
510bc36eafdSMike Gerdts         while (Next)
511bc36eafdSMike Gerdts         {
512bc36eafdSMike Gerdts             if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
513bc36eafdSMike Gerdts             {
514bc36eafdSMike Gerdts                 break;
515bc36eafdSMike Gerdts             }
516bc36eafdSMike Gerdts             Next = Next->Asl.Parent;
517bc36eafdSMike Gerdts         }
518bc36eafdSMike Gerdts 
519bc36eafdSMike Gerdts         if (!Next)
520bc36eafdSMike Gerdts         {
521bc36eafdSMike Gerdts             AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
522bc36eafdSMike Gerdts         }
523bc36eafdSMike Gerdts         break;
524bc36eafdSMike Gerdts 
525bc36eafdSMike Gerdts     case PARSEOP_STALL:
526bc36eafdSMike Gerdts 
527bc36eafdSMike Gerdts         /* We can range check if the argument is an integer */
528bc36eafdSMike Gerdts 
529bc36eafdSMike Gerdts         if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
530bc36eafdSMike Gerdts             (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
531bc36eafdSMike Gerdts         {
532bc36eafdSMike Gerdts             AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
533bc36eafdSMike Gerdts         }
534bc36eafdSMike Gerdts         break;
535bc36eafdSMike Gerdts 
536bc36eafdSMike Gerdts     case PARSEOP_DEVICE:
537bc36eafdSMike Gerdts 
538bc36eafdSMike Gerdts         if (!ApFindNameInDeviceTree (METHOD_NAME__HID, Op) &&
539bc36eafdSMike Gerdts             !ApFindNameInDeviceTree (METHOD_NAME__ADR, Op))
540bc36eafdSMike Gerdts         {
541bc36eafdSMike Gerdts             AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
542bc36eafdSMike Gerdts                 "Device object requires a _HID or _ADR in same scope");
543bc36eafdSMike Gerdts         }
544bc36eafdSMike Gerdts         break;
545bc36eafdSMike Gerdts 
546bc36eafdSMike Gerdts     case PARSEOP_EVENT:
547bc36eafdSMike Gerdts     case PARSEOP_MUTEX:
548bc36eafdSMike Gerdts     case PARSEOP_OPERATIONREGION:
549bc36eafdSMike Gerdts     case PARSEOP_POWERRESOURCE:
550bc36eafdSMike Gerdts     case PARSEOP_PROCESSOR:
551bc36eafdSMike Gerdts     case PARSEOP_THERMALZONE:
552bc36eafdSMike Gerdts 
553bc36eafdSMike Gerdts         /*
554bc36eafdSMike Gerdts          * The first operand is a name to be created in the namespace.
555bc36eafdSMike Gerdts          * Check against the reserved list.
556bc36eafdSMike Gerdts          */
557bc36eafdSMike Gerdts         i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
558bc36eafdSMike Gerdts         if (i < ACPI_VALID_RESERVED_NAME_MAX)
559bc36eafdSMike Gerdts         {
560bc36eafdSMike Gerdts             AslError (ASL_ERROR, ASL_MSG_RESERVED_USE,
561bc36eafdSMike Gerdts                 Op, Op->Asl.ExternalName);
562bc36eafdSMike Gerdts         }
563bc36eafdSMike Gerdts         break;
564bc36eafdSMike Gerdts 
565bc36eafdSMike Gerdts     case PARSEOP_NAME:
566bc36eafdSMike Gerdts 
567bc36eafdSMike Gerdts         /* Typecheck any predefined names statically defined with Name() */
568bc36eafdSMike Gerdts 
569bc36eafdSMike Gerdts         ApCheckForPredefinedObject (Op, Op->Asl.NameSeg);
570bc36eafdSMike Gerdts 
571bc36eafdSMike Gerdts         /* Special typechecking for _HID */
572bc36eafdSMike Gerdts 
573bc36eafdSMike Gerdts         if (!strcmp (METHOD_NAME__HID, Op->Asl.NameSeg))
574bc36eafdSMike Gerdts         {
575bc36eafdSMike Gerdts             Next = Op->Asl.Child->Asl.Next;
576bc36eafdSMike Gerdts             AnCheckId (Next, ASL_TYPE_HID);
577bc36eafdSMike Gerdts         }
578bc36eafdSMike Gerdts 
579bc36eafdSMike Gerdts         /* Special typechecking for _CID */
580bc36eafdSMike Gerdts 
581bc36eafdSMike Gerdts         else if (!strcmp (METHOD_NAME__CID, Op->Asl.NameSeg))
582bc36eafdSMike Gerdts         {
583bc36eafdSMike Gerdts             Next = Op->Asl.Child->Asl.Next;
584bc36eafdSMike Gerdts 
585bc36eafdSMike Gerdts             if ((Next->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
586bc36eafdSMike Gerdts                 (Next->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
587bc36eafdSMike Gerdts             {
588bc36eafdSMike Gerdts                 Next = Next->Asl.Child;
589bc36eafdSMike Gerdts                 while (Next)
590bc36eafdSMike Gerdts                 {
591bc36eafdSMike Gerdts                     AnCheckId (Next, ASL_TYPE_CID);
592bc36eafdSMike Gerdts                     Next = Next->Asl.Next;
593bc36eafdSMike Gerdts                 }
594bc36eafdSMike Gerdts             }
595bc36eafdSMike Gerdts             else
596bc36eafdSMike Gerdts             {
597bc36eafdSMike Gerdts                 AnCheckId (Next, ASL_TYPE_CID);
598bc36eafdSMike Gerdts             }
599bc36eafdSMike Gerdts         }
600bc36eafdSMike Gerdts 
601bc36eafdSMike Gerdts         break;
602bc36eafdSMike Gerdts 
603bc36eafdSMike Gerdts     default:
604bc36eafdSMike Gerdts 
605bc36eafdSMike Gerdts         break;
606bc36eafdSMike Gerdts     }
607bc36eafdSMike Gerdts 
608bc36eafdSMike Gerdts     /* Check for named object creation within a non-serialized method */
609bc36eafdSMike Gerdts 
610bc36eafdSMike Gerdts     MtCheckNamedObjectInMethod (Op, MethodInfo);
611bc36eafdSMike Gerdts     return (AE_OK);
612bc36eafdSMike Gerdts }
613bc36eafdSMike Gerdts 
614bc36eafdSMike Gerdts 
615bc36eafdSMike Gerdts /*******************************************************************************
616bc36eafdSMike Gerdts  *
617bc36eafdSMike Gerdts  * FUNCTION:    MtCheckNamedObjectInMethod
618bc36eafdSMike Gerdts  *
619bc36eafdSMike Gerdts  * PARAMETERS:  Op                  - Current parser op
620bc36eafdSMike Gerdts  *              MethodInfo          - Info for method being parsed
621bc36eafdSMike Gerdts  *
622bc36eafdSMike Gerdts  * RETURN:      None
623bc36eafdSMike Gerdts  *
624bc36eafdSMike Gerdts  * DESCRIPTION: Detect if a non-serialized method is creating a named object,
625bc36eafdSMike Gerdts  *              which could possibly cause problems if two threads execute
626bc36eafdSMike Gerdts  *              the method concurrently. Emit a remark in this case.
627bc36eafdSMike Gerdts  *
628bc36eafdSMike Gerdts  ******************************************************************************/
629bc36eafdSMike Gerdts 
630bc36eafdSMike Gerdts static void
MtCheckNamedObjectInMethod(ACPI_PARSE_OBJECT * Op,ASL_METHOD_INFO * MethodInfo)631bc36eafdSMike Gerdts MtCheckNamedObjectInMethod (
632bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *Op,
633bc36eafdSMike Gerdts     ASL_METHOD_INFO         *MethodInfo)
634bc36eafdSMike Gerdts {
635bc36eafdSMike Gerdts     const ACPI_OPCODE_INFO  *OpInfo;
636bc36eafdSMike Gerdts 
637bc36eafdSMike Gerdts 
638bc36eafdSMike Gerdts     /* We don't care about actual method declarations or scopes */
639bc36eafdSMike Gerdts 
640bc36eafdSMike Gerdts     if ((Op->Asl.AmlOpcode == AML_METHOD_OP) ||
641bc36eafdSMike Gerdts         (Op->Asl.AmlOpcode == AML_SCOPE_OP))
642bc36eafdSMike Gerdts     {
643bc36eafdSMike Gerdts         return;
644bc36eafdSMike Gerdts     }
645bc36eafdSMike Gerdts 
646*35786f68SRobert Mustacchi     /* Determine if we are creating a named object within a method */
647*35786f68SRobert Mustacchi 
648*35786f68SRobert Mustacchi     if (!MethodInfo)
649*35786f68SRobert Mustacchi     {
650*35786f68SRobert Mustacchi         return;
651*35786f68SRobert Mustacchi     }
652bc36eafdSMike Gerdts 
653bc36eafdSMike Gerdts     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
654bc36eafdSMike Gerdts     if (OpInfo->Class == AML_CLASS_NAMED_OBJECT)
655bc36eafdSMike Gerdts     {
656bc36eafdSMike Gerdts         /*
657*35786f68SRobert Mustacchi          * 1) Mark the method as a method that creates named objects.
658*35786f68SRobert Mustacchi          *
659*35786f68SRobert Mustacchi          * 2) If the method is non-serialized, emit a remark that the method
660*35786f68SRobert Mustacchi          * should be serialized.
661bc36eafdSMike Gerdts          *
662bc36eafdSMike Gerdts          * Reason: If a thread blocks within the method for any reason, and
663*35786f68SRobert Mustacchi          * another thread enters the method, the method will fail because
664*35786f68SRobert Mustacchi          * an attempt will be made to create the same object twice.
665bc36eafdSMike Gerdts          */
666*35786f68SRobert Mustacchi         MethodInfo->CreatesNamedObjects = TRUE;
667*35786f68SRobert Mustacchi         if (!MethodInfo->ShouldBeSerialized)
668bc36eafdSMike Gerdts         {
669bc36eafdSMike Gerdts             AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op,
670bc36eafdSMike Gerdts                 "due to creation of named objects within");
671bc36eafdSMike Gerdts 
672bc36eafdSMike Gerdts             /* Emit message only ONCE per method */
673bc36eafdSMike Gerdts 
674bc36eafdSMike Gerdts             MethodInfo->ShouldBeSerialized = TRUE;
675bc36eafdSMike Gerdts         }
676bc36eafdSMike Gerdts     }
677bc36eafdSMike Gerdts }
678bc36eafdSMike Gerdts 
679bc36eafdSMike Gerdts 
680bc36eafdSMike Gerdts /*******************************************************************************
681bc36eafdSMike Gerdts  *
682bc36eafdSMike Gerdts  * FUNCTION:    MtMethodAnalysisWalkEnd
683bc36eafdSMike Gerdts  *
684bc36eafdSMike Gerdts  * PARAMETERS:  ASL_WALK_CALLBACK
685bc36eafdSMike Gerdts  *
686bc36eafdSMike Gerdts  * RETURN:      Status
687bc36eafdSMike Gerdts  *
688bc36eafdSMike Gerdts  * DESCRIPTION: Ascending callback for analysis walk. Complete method
689bc36eafdSMike Gerdts  *              return analysis.
690bc36eafdSMike Gerdts  *
691bc36eafdSMike Gerdts  ******************************************************************************/
692bc36eafdSMike Gerdts 
693bc36eafdSMike Gerdts ACPI_STATUS
MtMethodAnalysisWalkEnd(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)694bc36eafdSMike Gerdts MtMethodAnalysisWalkEnd (
695bc36eafdSMike Gerdts     ACPI_PARSE_OBJECT       *Op,
696bc36eafdSMike Gerdts     UINT32                  Level,
697bc36eafdSMike Gerdts     void                    *Context)
698bc36eafdSMike Gerdts {
699bc36eafdSMike Gerdts     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
700bc36eafdSMike Gerdts     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
701bc36eafdSMike Gerdts 
702bc36eafdSMike Gerdts 
703bc36eafdSMike Gerdts     switch (Op->Asl.ParseOpcode)
704bc36eafdSMike Gerdts     {
705bc36eafdSMike Gerdts     case PARSEOP_METHOD:
706bc36eafdSMike Gerdts     case PARSEOP_RETURN:
707bc36eafdSMike Gerdts 
708bc36eafdSMike Gerdts         if (!MethodInfo)
709bc36eafdSMike Gerdts         {
710bc36eafdSMike Gerdts             printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
711bc36eafdSMike Gerdts             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
712bc36eafdSMike Gerdts                 "No method info for this method");
713bc36eafdSMike Gerdts 
714bc36eafdSMike Gerdts             CmCleanupAndExit ();
715bc36eafdSMike Gerdts             return (AE_AML_INTERNAL);
716bc36eafdSMike Gerdts         }
717bc36eafdSMike Gerdts         break;
718bc36eafdSMike Gerdts 
719bc36eafdSMike Gerdts     default:
720bc36eafdSMike Gerdts 
721bc36eafdSMike Gerdts         break;
722bc36eafdSMike Gerdts     }
723bc36eafdSMike Gerdts 
724bc36eafdSMike Gerdts     switch (Op->Asl.ParseOpcode)
725bc36eafdSMike Gerdts     {
726bc36eafdSMike Gerdts     case PARSEOP_METHOD:
727bc36eafdSMike Gerdts 
728bc36eafdSMike Gerdts         WalkInfo->MethodStack = MethodInfo->Next;
729bc36eafdSMike Gerdts 
730bc36eafdSMike Gerdts         /*
731bc36eafdSMike Gerdts          * Check if there is no return statement at the end of the
732bc36eafdSMike Gerdts          * method AND we can actually get there -- i.e., the execution
733bc36eafdSMike Gerdts          * of the method can possibly terminate without a return statement.
734bc36eafdSMike Gerdts          */
735bc36eafdSMike Gerdts         if ((!AnLastStatementIsReturn (Op)) &&
736*35786f68SRobert Mustacchi             (!(Op->Asl.CompileFlags & OP_HAS_NO_EXIT)))
737bc36eafdSMike Gerdts         {
738bc36eafdSMike Gerdts             /*
739bc36eafdSMike Gerdts              * No return statement, and execution can possibly exit
740bc36eafdSMike Gerdts              * via this path. This is equivalent to Return ()
741bc36eafdSMike Gerdts              */
742bc36eafdSMike Gerdts             MethodInfo->NumReturnNoValue++;
743bc36eafdSMike Gerdts         }
744bc36eafdSMike Gerdts 
745bc36eafdSMike Gerdts         /*
746bc36eafdSMike Gerdts          * Check for case where some return statements have a return value
747bc36eafdSMike Gerdts          * and some do not. Exit without a return statement is a return with
748bc36eafdSMike Gerdts          * no value
749bc36eafdSMike Gerdts          */
750bc36eafdSMike Gerdts         if (MethodInfo->NumReturnNoValue &&
751bc36eafdSMike Gerdts             MethodInfo->NumReturnWithValue)
752bc36eafdSMike Gerdts         {
753bc36eafdSMike Gerdts             AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
754bc36eafdSMike Gerdts                 Op->Asl.ExternalName);
755bc36eafdSMike Gerdts         }
756bc36eafdSMike Gerdts 
757bc36eafdSMike Gerdts         /*
758bc36eafdSMike Gerdts          * If there are any RETURN() statements with no value, or there is a
759bc36eafdSMike Gerdts          * control path that allows the method to exit without a return value,
760bc36eafdSMike Gerdts          * we mark the method as a method that does not return a value. This
761bc36eafdSMike Gerdts          * knowledge can be used to check method invocations that expect a
762bc36eafdSMike Gerdts          * returned value.
763bc36eafdSMike Gerdts          */
764bc36eafdSMike Gerdts         if (MethodInfo->NumReturnNoValue)
765bc36eafdSMike Gerdts         {
766bc36eafdSMike Gerdts             if (MethodInfo->NumReturnWithValue)
767bc36eafdSMike Gerdts             {
768*35786f68SRobert Mustacchi                 Op->Asl.CompileFlags |= OP_METHOD_SOME_NO_RETVAL;
769bc36eafdSMike Gerdts             }
770bc36eafdSMike Gerdts             else
771bc36eafdSMike Gerdts             {
772*35786f68SRobert Mustacchi                 Op->Asl.CompileFlags |= OP_METHOD_NO_RETVAL;
773bc36eafdSMike Gerdts             }
774bc36eafdSMike Gerdts         }
775bc36eafdSMike Gerdts 
776bc36eafdSMike Gerdts         /*
777bc36eafdSMike Gerdts          * Check predefined method names for correct return behavior
778bc36eafdSMike Gerdts          * and correct number of arguments. Also, some special checks
779bc36eafdSMike Gerdts          * For GPE and _REG methods.
780bc36eafdSMike Gerdts          */
781bc36eafdSMike Gerdts         if (ApCheckForPredefinedMethod (Op, MethodInfo))
782bc36eafdSMike Gerdts         {
783bc36eafdSMike Gerdts             /* Special check for two names like _L01 and _E01 in same scope */
784bc36eafdSMike Gerdts 
785bc36eafdSMike Gerdts             ApCheckForGpeNameConflict (Op);
786bc36eafdSMike Gerdts 
787bc36eafdSMike Gerdts             /*
788bc36eafdSMike Gerdts              * Special check for _REG: Must have an operation region definition
789bc36eafdSMike Gerdts              * within the same scope!
790bc36eafdSMike Gerdts              */
791bc36eafdSMike Gerdts             ApCheckRegMethod (Op);
792bc36eafdSMike Gerdts         }
793bc36eafdSMike Gerdts 
794bc36eafdSMike Gerdts         ACPI_FREE (MethodInfo);
795bc36eafdSMike Gerdts         break;
796bc36eafdSMike Gerdts 
797bc36eafdSMike Gerdts     case PARSEOP_NAME:
798bc36eafdSMike Gerdts 
799bc36eafdSMike Gerdts          /* Special check for two names like _L01 and _E01 in same scope */
800bc36eafdSMike Gerdts 
801bc36eafdSMike Gerdts         ApCheckForGpeNameConflict (Op);
802bc36eafdSMike Gerdts         break;
803bc36eafdSMike Gerdts 
804bc36eafdSMike Gerdts     case PARSEOP_RETURN:
805bc36eafdSMike Gerdts 
806bc36eafdSMike Gerdts         /*
807bc36eafdSMike Gerdts          * If the parent is a predefined method name, attempt to typecheck
808bc36eafdSMike Gerdts          * the return value. Only static types can be validated.
809bc36eafdSMike Gerdts          */
810bc36eafdSMike Gerdts         ApCheckPredefinedReturnValue (Op, MethodInfo);
811bc36eafdSMike Gerdts 
812bc36eafdSMike Gerdts         /*
813bc36eafdSMike Gerdts          * The parent block does not "exit" and continue execution -- the
814bc36eafdSMike Gerdts          * method is terminated here with the Return() statement.
815bc36eafdSMike Gerdts          */
816*35786f68SRobert Mustacchi         Op->Asl.Parent->Asl.CompileFlags |= OP_HAS_NO_EXIT;
817bc36eafdSMike Gerdts 
818bc36eafdSMike Gerdts         /* Used in the "typing" pass later */
819bc36eafdSMike Gerdts 
820bc36eafdSMike Gerdts         Op->Asl.ParentMethod = MethodInfo->Op;
821bc36eafdSMike Gerdts 
822bc36eafdSMike Gerdts         /*
823bc36eafdSMike Gerdts          * If there is a peer node after the return statement, then this
824bc36eafdSMike Gerdts          * node is unreachable code -- i.e., it won't be executed because of
825bc36eafdSMike Gerdts          * the preceding Return() statement.
826bc36eafdSMike Gerdts          */
827bc36eafdSMike Gerdts         if (Op->Asl.Next)
828bc36eafdSMike Gerdts         {
829bc36eafdSMike Gerdts             AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE,
830bc36eafdSMike Gerdts                 Op->Asl.Next, NULL);
831bc36eafdSMike Gerdts         }
832bc36eafdSMike Gerdts         break;
833bc36eafdSMike Gerdts 
834bc36eafdSMike Gerdts     case PARSEOP_IF:
835bc36eafdSMike Gerdts 
836*35786f68SRobert Mustacchi         if ((Op->Asl.CompileFlags & OP_HAS_NO_EXIT) &&
837bc36eafdSMike Gerdts             (Op->Asl.Next) &&
838bc36eafdSMike Gerdts             (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
839bc36eafdSMike Gerdts         {
840bc36eafdSMike Gerdts             /*
841bc36eafdSMike Gerdts              * This IF has a corresponding ELSE. The IF block has no exit,
842bc36eafdSMike Gerdts              * (it contains an unconditional Return)
843bc36eafdSMike Gerdts              * mark the ELSE block to remember this fact.
844bc36eafdSMike Gerdts              */
845*35786f68SRobert Mustacchi             Op->Asl.Next->Asl.CompileFlags |= OP_IF_HAS_NO_EXIT;
846bc36eafdSMike Gerdts         }
847bc36eafdSMike Gerdts         break;
848bc36eafdSMike Gerdts 
849bc36eafdSMike Gerdts     case PARSEOP_ELSE:
850bc36eafdSMike Gerdts 
851*35786f68SRobert Mustacchi         if ((Op->Asl.CompileFlags & OP_HAS_NO_EXIT) &&
852*35786f68SRobert Mustacchi             (Op->Asl.CompileFlags & OP_IF_HAS_NO_EXIT))
853bc36eafdSMike Gerdts         {
854bc36eafdSMike Gerdts             /*
855bc36eafdSMike Gerdts              * This ELSE block has no exit and the corresponding IF block
856bc36eafdSMike Gerdts              * has no exit either. Therefore, the parent node has no exit.
857bc36eafdSMike Gerdts              */
858*35786f68SRobert Mustacchi             Op->Asl.Parent->Asl.CompileFlags |= OP_HAS_NO_EXIT;
859bc36eafdSMike Gerdts         }
860bc36eafdSMike Gerdts         break;
861bc36eafdSMike Gerdts 
862bc36eafdSMike Gerdts 
863bc36eafdSMike Gerdts     default:
864bc36eafdSMike Gerdts 
865*35786f68SRobert Mustacchi         if ((Op->Asl.CompileFlags & OP_HAS_NO_EXIT) &&
866bc36eafdSMike Gerdts             (Op->Asl.Parent))
867bc36eafdSMike Gerdts         {
868bc36eafdSMike Gerdts             /* If this node has no exit, then the parent has no exit either */
869bc36eafdSMike Gerdts 
870*35786f68SRobert Mustacchi             Op->Asl.Parent->Asl.CompileFlags |= OP_HAS_NO_EXIT;
871bc36eafdSMike Gerdts         }
872bc36eafdSMike Gerdts         break;
873bc36eafdSMike Gerdts     }
874bc36eafdSMike Gerdts 
875bc36eafdSMike Gerdts     return (AE_OK);
876bc36eafdSMike Gerdts }
877