xref: /dflybsd-src/sys/contrib/dev/acpica/source/compiler/aslmethod.c (revision 84fe336011475fd1044abca1e19120611fef0b7a)
10d02842fSSascha Wildner /******************************************************************************
20d02842fSSascha Wildner  *
30d02842fSSascha Wildner  * Module Name: aslmethod.c - Control method analysis walk
40d02842fSSascha Wildner  *
50d02842fSSascha Wildner  *****************************************************************************/
60d02842fSSascha Wildner 
7b4315fc7SSascha Wildner /******************************************************************************
8b4315fc7SSascha Wildner  *
9b4315fc7SSascha Wildner  * 1. Copyright Notice
10b4315fc7SSascha Wildner  *
11383048acSSascha Wildner  * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
120d02842fSSascha Wildner  * All rights reserved.
130d02842fSSascha Wildner  *
14b4315fc7SSascha Wildner  * 2. License
15b4315fc7SSascha Wildner  *
16b4315fc7SSascha Wildner  * 2.1. This is your license from Intel Corp. under its intellectual property
17b4315fc7SSascha Wildner  * rights. You may have additional license terms from the party that provided
18b4315fc7SSascha Wildner  * you this software, covering your right to use that party's intellectual
19b4315fc7SSascha Wildner  * property rights.
20b4315fc7SSascha Wildner  *
21b4315fc7SSascha Wildner  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22b4315fc7SSascha Wildner  * copy of the source code appearing in this file ("Covered Code") an
23b4315fc7SSascha Wildner  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24b4315fc7SSascha Wildner  * base code distributed originally by Intel ("Original Intel Code") to copy,
25b4315fc7SSascha Wildner  * make derivatives, distribute, use and display any portion of the Covered
26b4315fc7SSascha Wildner  * Code in any form, with the right to sublicense such rights; and
27b4315fc7SSascha Wildner  *
28b4315fc7SSascha Wildner  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29b4315fc7SSascha Wildner  * license (with the right to sublicense), under only those claims of Intel
30b4315fc7SSascha Wildner  * patents that are infringed by the Original Intel Code, to make, use, sell,
31b4315fc7SSascha Wildner  * offer to sell, and import the Covered Code and derivative works thereof
32b4315fc7SSascha Wildner  * solely to the minimum extent necessary to exercise the above copyright
33b4315fc7SSascha Wildner  * license, and in no event shall the patent license extend to any additions
34b4315fc7SSascha Wildner  * to or modifications of the Original Intel Code. No other license or right
35b4315fc7SSascha Wildner  * is granted directly or by implication, estoppel or otherwise;
36b4315fc7SSascha Wildner  *
37b4315fc7SSascha Wildner  * The above copyright and patent license is granted only if the following
38b4315fc7SSascha Wildner  * conditions are met:
39b4315fc7SSascha Wildner  *
40b4315fc7SSascha Wildner  * 3. Conditions
41b4315fc7SSascha Wildner  *
42b4315fc7SSascha Wildner  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43b4315fc7SSascha Wildner  * Redistribution of source code of any substantial portion of the Covered
44b4315fc7SSascha Wildner  * Code or modification with rights to further distribute source must include
45b4315fc7SSascha Wildner  * the above Copyright Notice, the above License, this list of Conditions,
46b4315fc7SSascha Wildner  * and the following Disclaimer and Export Compliance provision. In addition,
47b4315fc7SSascha Wildner  * Licensee must cause all Covered Code to which Licensee contributes to
48b4315fc7SSascha Wildner  * contain a file documenting the changes Licensee made to create that Covered
49b4315fc7SSascha Wildner  * Code and the date of any change. Licensee must include in that file the
50b4315fc7SSascha Wildner  * documentation of any changes made by any predecessor Licensee. Licensee
51b4315fc7SSascha Wildner  * must include a prominent statement that the modification is derived,
52b4315fc7SSascha Wildner  * directly or indirectly, from Original Intel Code.
53b4315fc7SSascha Wildner  *
54b4315fc7SSascha Wildner  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55b4315fc7SSascha Wildner  * Redistribution of source code of any substantial portion of the Covered
56b4315fc7SSascha Wildner  * Code or modification without rights to further distribute source must
57b4315fc7SSascha Wildner  * include the following Disclaimer and Export Compliance provision in the
58b4315fc7SSascha Wildner  * documentation and/or other materials provided with distribution. In
59b4315fc7SSascha Wildner  * addition, Licensee may not authorize further sublicense of source of any
60b4315fc7SSascha Wildner  * portion of the Covered Code, and must include terms to the effect that the
61b4315fc7SSascha Wildner  * license from Licensee to its licensee is limited to the intellectual
62b4315fc7SSascha Wildner  * property embodied in the software Licensee provides to its licensee, and
63b4315fc7SSascha Wildner  * not to intellectual property embodied in modifications its licensee may
64b4315fc7SSascha Wildner  * make.
65b4315fc7SSascha Wildner  *
66b4315fc7SSascha Wildner  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67b4315fc7SSascha Wildner  * substantial portion of the Covered Code or modification must reproduce the
68b4315fc7SSascha Wildner  * above Copyright Notice, and the following Disclaimer and Export Compliance
69b4315fc7SSascha Wildner  * provision in the documentation and/or other materials provided with the
70b4315fc7SSascha Wildner  * distribution.
71b4315fc7SSascha Wildner  *
72b4315fc7SSascha Wildner  * 3.4. Intel retains all right, title, and interest in and to the Original
73b4315fc7SSascha Wildner  * Intel Code.
74b4315fc7SSascha Wildner  *
75b4315fc7SSascha Wildner  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76b4315fc7SSascha Wildner  * Intel shall be used in advertising or otherwise to promote the sale, use or
77b4315fc7SSascha Wildner  * other dealings in products derived from or relating to the Covered Code
78b4315fc7SSascha Wildner  * without prior written authorization from Intel.
79b4315fc7SSascha Wildner  *
80b4315fc7SSascha Wildner  * 4. Disclaimer and Export Compliance
81b4315fc7SSascha Wildner  *
82b4315fc7SSascha Wildner  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83b4315fc7SSascha Wildner  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84b4315fc7SSascha Wildner  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85b4315fc7SSascha Wildner  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86b4315fc7SSascha Wildner  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87b4315fc7SSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88b4315fc7SSascha Wildner  * PARTICULAR PURPOSE.
89b4315fc7SSascha Wildner  *
90b4315fc7SSascha Wildner  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91b4315fc7SSascha Wildner  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92b4315fc7SSascha Wildner  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93b4315fc7SSascha Wildner  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94b4315fc7SSascha Wildner  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95b4315fc7SSascha Wildner  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96b4315fc7SSascha Wildner  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97b4315fc7SSascha Wildner  * LIMITED REMEDY.
98b4315fc7SSascha Wildner  *
99b4315fc7SSascha Wildner  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100b4315fc7SSascha Wildner  * software or system incorporating such software without first obtaining any
101b4315fc7SSascha Wildner  * required license or other approval from the U. S. Department of Commerce or
102b4315fc7SSascha Wildner  * any other agency or department of the United States Government. In the
103b4315fc7SSascha Wildner  * event Licensee exports any such software from the United States or
104b4315fc7SSascha Wildner  * re-exports any such software from a foreign destination, Licensee shall
105b4315fc7SSascha Wildner  * ensure that the distribution and export/re-export of the software is in
106b4315fc7SSascha Wildner  * compliance with all laws, regulations, orders, or other restrictions of the
107b4315fc7SSascha Wildner  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108b4315fc7SSascha Wildner  * any of its subsidiaries will export/re-export any technical data, process,
109b4315fc7SSascha Wildner  * software, or service, directly or indirectly, to any country for which the
110b4315fc7SSascha Wildner  * United States government or any agency thereof requires an export license,
111b4315fc7SSascha Wildner  * other governmental approval, or letter of assurance, without first obtaining
112b4315fc7SSascha Wildner  * such license, approval or letter.
113b4315fc7SSascha Wildner  *
114b4315fc7SSascha Wildner  *****************************************************************************
115b4315fc7SSascha Wildner  *
116b4315fc7SSascha Wildner  * Alternatively, you may choose to be licensed under the terms of the
117b4315fc7SSascha Wildner  * following license:
118b4315fc7SSascha Wildner  *
1190d02842fSSascha Wildner  * Redistribution and use in source and binary forms, with or without
1200d02842fSSascha Wildner  * modification, are permitted provided that the following conditions
1210d02842fSSascha Wildner  * are met:
1220d02842fSSascha Wildner  * 1. Redistributions of source code must retain the above copyright
1230d02842fSSascha Wildner  *    notice, this list of conditions, and the following disclaimer,
1240d02842fSSascha Wildner  *    without modification.
1250d02842fSSascha Wildner  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1260d02842fSSascha Wildner  *    substantially similar to the "NO WARRANTY" disclaimer below
1270d02842fSSascha Wildner  *    ("Disclaimer") and any redistribution must be conditioned upon
1280d02842fSSascha Wildner  *    including a substantially similar Disclaimer requirement for further
1290d02842fSSascha Wildner  *    binary redistribution.
1300d02842fSSascha Wildner  * 3. Neither the names of the above-listed copyright holders nor the names
1310d02842fSSascha Wildner  *    of any contributors may be used to endorse or promote products derived
1320d02842fSSascha Wildner  *    from this software without specific prior written permission.
1330d02842fSSascha Wildner  *
134b4315fc7SSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135b4315fc7SSascha Wildner  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136b4315fc7SSascha Wildner  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137b4315fc7SSascha Wildner  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138b4315fc7SSascha Wildner  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139b4315fc7SSascha Wildner  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140b4315fc7SSascha Wildner  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141b4315fc7SSascha Wildner  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142b4315fc7SSascha Wildner  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143b4315fc7SSascha Wildner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144b4315fc7SSascha Wildner  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145b4315fc7SSascha Wildner  *
146b4315fc7SSascha Wildner  * Alternatively, you may choose to be licensed under the terms of the
1470d02842fSSascha Wildner  * GNU General Public License ("GPL") version 2 as published by the Free
1480d02842fSSascha Wildner  * Software Foundation.
1490d02842fSSascha Wildner  *
150b4315fc7SSascha Wildner  *****************************************************************************/
1510d02842fSSascha Wildner 
1520d02842fSSascha Wildner #include "aslcompiler.h"
1530d02842fSSascha Wildner #include "aslcompiler.y.h"
154ff3cb46dSSascha Wildner #include "acnamesp.h"
1550d02842fSSascha Wildner #include "acparser.h"
1560d02842fSSascha Wildner #include "amlcode.h"
1570d02842fSSascha Wildner 
1580d02842fSSascha Wildner 
1590d02842fSSascha Wildner #define _COMPONENT          ACPI_COMPILER
1600d02842fSSascha Wildner         ACPI_MODULE_NAME    ("aslmethod")
1610d02842fSSascha Wildner 
1620d02842fSSascha Wildner 
1630d02842fSSascha Wildner /* Local prototypes */
1640d02842fSSascha Wildner 
1657c9678bcSSascha Wildner static void
1660d02842fSSascha Wildner MtCheckNamedObjectInMethod (
1670d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1680d02842fSSascha Wildner     ASL_METHOD_INFO         *MethodInfo);
1690d02842fSSascha Wildner 
170ff3cb46dSSascha Wildner static void
171ff3cb46dSSascha Wildner MtCheckStaticOperationRegionInMethod (
172ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT       *Op);
173ff3cb46dSSascha Wildner 
1740d02842fSSascha Wildner 
1750d02842fSSascha Wildner /*******************************************************************************
1760d02842fSSascha Wildner  *
1770d02842fSSascha Wildner  * FUNCTION:    MtMethodAnalysisWalkBegin
1780d02842fSSascha Wildner  *
1790d02842fSSascha Wildner  * PARAMETERS:  ASL_WALK_CALLBACK
1800d02842fSSascha Wildner  *
1810d02842fSSascha Wildner  * RETURN:      Status
1820d02842fSSascha Wildner  *
1830d02842fSSascha Wildner  * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
1840d02842fSSascha Wildner  *              1) Initialized local variables
1850d02842fSSascha Wildner  *              2) Valid arguments
1860d02842fSSascha Wildner  *              3) Return types
1870d02842fSSascha Wildner  *
1880d02842fSSascha Wildner  ******************************************************************************/
1890d02842fSSascha Wildner 
1900d02842fSSascha Wildner ACPI_STATUS
MtMethodAnalysisWalkBegin(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)1910d02842fSSascha Wildner MtMethodAnalysisWalkBegin (
1920d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1930d02842fSSascha Wildner     UINT32                  Level,
1940d02842fSSascha Wildner     void                    *Context)
1950d02842fSSascha Wildner {
1960d02842fSSascha Wildner     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
1970d02842fSSascha Wildner     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
1980d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Next;
1990d02842fSSascha Wildner     UINT32                  RegisterNumber;
2000d02842fSSascha Wildner     UINT32                  i;
2010d02842fSSascha Wildner     char                    LocalName[] = "Local0";
2020d02842fSSascha Wildner     char                    ArgName[] = "Arg0";
2030d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *ArgNode;
2040d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *NextType;
2050d02842fSSascha Wildner     UINT8                   ActualArgs = 0;
206e5412f1eSSascha Wildner     BOOLEAN                 HidExists;
207e5412f1eSSascha Wildner     BOOLEAN                 AdrExists;
2080672a19bSSascha Wildner     BOOLEAN                 PrsExists;
2090672a19bSSascha Wildner     BOOLEAN                 CrsExists;
2100672a19bSSascha Wildner     BOOLEAN                 SrsExists;
2110672a19bSSascha Wildner     BOOLEAN                 DisExists;
2120d02842fSSascha Wildner 
2130d02842fSSascha Wildner 
2147c9678bcSSascha Wildner     /* Build cross-reference output file if requested */
2157c9678bcSSascha Wildner 
216806343b9SSascha Wildner     if (AslGbl_CrossReferenceOutput)
2177c9678bcSSascha Wildner     {
2187c9678bcSSascha Wildner         OtXrefWalkPart1 (Op, Level, MethodInfo);
2197c9678bcSSascha Wildner     }
2207c9678bcSSascha Wildner 
2210d02842fSSascha Wildner     switch (Op->Asl.ParseOpcode)
2220d02842fSSascha Wildner     {
2230d02842fSSascha Wildner     case PARSEOP_METHOD:
2240d02842fSSascha Wildner 
225806343b9SSascha Wildner         AslGbl_TotalMethods++;
2260d02842fSSascha Wildner 
2270d02842fSSascha Wildner         /* Create and init method info */
2280d02842fSSascha Wildner 
2290d02842fSSascha Wildner         MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
2300d02842fSSascha Wildner         MethodInfo->Next = WalkInfo->MethodStack;
2310d02842fSSascha Wildner         MethodInfo->Op = Op;
2320d02842fSSascha Wildner 
2330d02842fSSascha Wildner         WalkInfo->MethodStack = MethodInfo;
2340d02842fSSascha Wildner 
23579eafdd7SSascha Wildner         /*
23679eafdd7SSascha Wildner          * Special handling for _PSx methods. Dependency rules (same scope):
23779eafdd7SSascha Wildner          *
23879eafdd7SSascha Wildner          * 1) _PS0 - One of these must exist: _PS1, _PS2, _PS3
23979eafdd7SSascha Wildner          * 2) _PS1/_PS2/_PS3: A _PS0 must exist
24079eafdd7SSascha Wildner          */
241c1776041SSascha Wildner         if (ACPI_COMPARE_NAMESEG (METHOD_NAME__PS0, Op->Asl.NameSeg))
242066b6da2SSascha Wildner         {
24379eafdd7SSascha Wildner             /* For _PS0, one of _PS1/_PS2/_PS3 must exist */
24479eafdd7SSascha Wildner 
24579eafdd7SSascha Wildner             if ((!ApFindNameInScope (METHOD_NAME__PS1, Op)) &&
24679eafdd7SSascha Wildner                 (!ApFindNameInScope (METHOD_NAME__PS2, Op)) &&
24779eafdd7SSascha Wildner                 (!ApFindNameInScope (METHOD_NAME__PS3, Op)))
248066b6da2SSascha Wildner             {
249066b6da2SSascha Wildner                 AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
25079eafdd7SSascha Wildner                     "_PS0 requires one of _PS1/_PS2/_PS3 in same scope");
25179eafdd7SSascha Wildner             }
25279eafdd7SSascha Wildner         }
25379eafdd7SSascha Wildner         else if (
254c1776041SSascha Wildner             ACPI_COMPARE_NAMESEG (METHOD_NAME__PS1, Op->Asl.NameSeg) ||
255c1776041SSascha Wildner             ACPI_COMPARE_NAMESEG (METHOD_NAME__PS2, Op->Asl.NameSeg) ||
256c1776041SSascha Wildner             ACPI_COMPARE_NAMESEG (METHOD_NAME__PS3, Op->Asl.NameSeg))
25779eafdd7SSascha Wildner         {
25879eafdd7SSascha Wildner             /* For _PS1/_PS2/_PS3, a _PS0 must exist */
25979eafdd7SSascha Wildner 
26079eafdd7SSascha Wildner             if (!ApFindNameInScope (METHOD_NAME__PS0, Op))
26179eafdd7SSascha Wildner             {
262806343b9SSascha Wildner                 sprintf (AslGbl_MsgBuffer,
26379eafdd7SSascha Wildner                     "%4.4s requires _PS0 in same scope", Op->Asl.NameSeg);
26479eafdd7SSascha Wildner 
26579eafdd7SSascha Wildner                 AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
266806343b9SSascha Wildner                     AslGbl_MsgBuffer);
267066b6da2SSascha Wildner             }
268066b6da2SSascha Wildner         }
269066b6da2SSascha Wildner 
2709e1c0880SSascha Wildner         /* Get the name node */
2710d02842fSSascha Wildner 
2720d02842fSSascha Wildner         Next = Op->Asl.Child;
2730d02842fSSascha Wildner 
2740d02842fSSascha Wildner         /* Get the NumArguments node */
2750d02842fSSascha Wildner 
2760d02842fSSascha Wildner         Next = Next->Asl.Next;
2770d02842fSSascha Wildner         MethodInfo->NumArguments = (UINT8)
2780d02842fSSascha Wildner             (((UINT8) Next->Asl.Value.Integer) & 0x07);
2790d02842fSSascha Wildner 
2800d02842fSSascha Wildner         /* Get the SerializeRule and SyncLevel nodes, ignored here */
2810d02842fSSascha Wildner 
2820d02842fSSascha Wildner         Next = Next->Asl.Next;
2830d02842fSSascha Wildner         MethodInfo->ShouldBeSerialized = (UINT8) Next->Asl.Value.Integer;
2840d02842fSSascha Wildner 
2850d02842fSSascha Wildner         Next = Next->Asl.Next;
2860d02842fSSascha Wildner         ArgNode = Next;
2870d02842fSSascha Wildner 
2880d02842fSSascha Wildner         /* Get the ReturnType node */
2890d02842fSSascha Wildner 
2900d02842fSSascha Wildner         Next = Next->Asl.Next;
2910d02842fSSascha Wildner 
2920d02842fSSascha Wildner         NextType = Next->Asl.Child;
2930d02842fSSascha Wildner 
294ff3cb46dSSascha Wildner         MethodInfo->ValidReturnTypes = MtProcessTypeOp (NextType);
29508343eafSSascha Wildner         Op->Asl.AcpiBtype |= MethodInfo->ValidReturnTypes;
2960d02842fSSascha Wildner 
2970d02842fSSascha Wildner         /* Get the ParameterType node */
2980d02842fSSascha Wildner 
2990d02842fSSascha Wildner         Next = Next->Asl.Next;
3000d02842fSSascha Wildner 
3010d02842fSSascha Wildner         NextType = Next->Asl.Child;
302ff3cb46dSSascha Wildner         if (!NextType)
3030d02842fSSascha Wildner         {
304ff3cb46dSSascha Wildner             /*
305ff3cb46dSSascha Wildner              * The optional parameter types list was omitted  at the source
306ff3cb46dSSascha Wildner              * level. Use the Argument count parameter instead.
307ff3cb46dSSascha Wildner              */
308ff3cb46dSSascha Wildner             ActualArgs = MethodInfo->NumArguments;
3090d02842fSSascha Wildner         }
3100d02842fSSascha Wildner         else
3110d02842fSSascha Wildner         {
312ff3cb46dSSascha Wildner             ActualArgs = MtProcessParameterTypeList (NextType,
313ff3cb46dSSascha Wildner                 MethodInfo->ValidArgTypes);
3144758d649SSascha Wildner             MethodInfo->NumArguments = ActualArgs;
3154758d649SSascha Wildner             ArgNode->Asl.Value.Integer |= ActualArgs;
3160d02842fSSascha Wildner         }
3170d02842fSSascha Wildner 
3180d02842fSSascha Wildner         if ((MethodInfo->NumArguments) &&
3190d02842fSSascha Wildner             (MethodInfo->NumArguments != ActualArgs))
3200d02842fSSascha Wildner         {
321ff3cb46dSSascha Wildner             sprintf (AslGbl_MsgBuffer,
322ff3cb46dSSascha Wildner                 "Length = %u", ActualArgs);
323ff3cb46dSSascha Wildner             AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_MISMATCH,
324ff3cb46dSSascha Wildner                 Op->Asl.Child->Asl.Next, AslGbl_MsgBuffer);
3250d02842fSSascha Wildner         }
3260d02842fSSascha Wildner 
3270d02842fSSascha Wildner         /* Allow numarguments == 0 for Function() */
3280d02842fSSascha Wildner 
3290d02842fSSascha Wildner         if ((!MethodInfo->NumArguments) && (ActualArgs))
3300d02842fSSascha Wildner         {
3310d02842fSSascha Wildner             MethodInfo->NumArguments = ActualArgs;
3320d02842fSSascha Wildner             ArgNode->Asl.Value.Integer |= ActualArgs;
3330d02842fSSascha Wildner         }
3340d02842fSSascha Wildner 
3350d02842fSSascha Wildner         /*
3360d02842fSSascha Wildner          * Actual arguments are initialized at method entry.
3370d02842fSSascha Wildner          * All other ArgX "registers" can be used as locals, so we
3380d02842fSSascha Wildner          * track their initialization.
3390d02842fSSascha Wildner          */
3400d02842fSSascha Wildner         for (i = 0; i < MethodInfo->NumArguments; i++)
3410d02842fSSascha Wildner         {
3420d02842fSSascha Wildner             MethodInfo->ArgInitialized[i] = TRUE;
3430d02842fSSascha Wildner         }
3440d02842fSSascha Wildner         break;
3450d02842fSSascha Wildner 
3460d02842fSSascha Wildner     case PARSEOP_METHODCALL:
3470d02842fSSascha Wildner 
3487bcb6cafSSascha Wildner         /* Check for a recursive method call */
3497bcb6cafSSascha Wildner 
3500d02842fSSascha Wildner         if (MethodInfo &&
3510d02842fSSascha Wildner            (Op->Asl.Node == MethodInfo->Op->Asl.Node))
3520d02842fSSascha Wildner         {
3537bcb6cafSSascha Wildner             if (MethodInfo->CreatesNamedObjects)
3547bcb6cafSSascha Wildner             {
3557bcb6cafSSascha Wildner                 /*
3567bcb6cafSSascha Wildner                  * This is an error, as it will fail at runtime on all ACPI
3577bcb6cafSSascha Wildner                  * implementations. Any named object declarations will be
3587bcb6cafSSascha Wildner                  * executed twice, causing failure the second time. Note,
3597bcb6cafSSascha Wildner                  * this is independent of whether the method is declared
3607bcb6cafSSascha Wildner                  * Serialized, because the same thread is attempting to
3617bcb6cafSSascha Wildner                  * reenter the method, and this will always succeed.
3627bcb6cafSSascha Wildner                  */
3637bcb6cafSSascha Wildner                 AslDualParseOpError (ASL_ERROR, ASL_MSG_ILLEGAL_RECURSION, Op,
3647bcb6cafSSascha Wildner                     Op->Asl.Value.String, ASL_MSG_FOUND_HERE, MethodInfo->Op,
3657bcb6cafSSascha Wildner                     MethodInfo->Op->Asl.ExternalName);
3667bcb6cafSSascha Wildner             }
3677bcb6cafSSascha Wildner             else
3687bcb6cafSSascha Wildner             {
3697bcb6cafSSascha Wildner                 /* Method does not create objects, issue a remark */
3707bcb6cafSSascha Wildner 
3710d02842fSSascha Wildner                 AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
3720d02842fSSascha Wildner             }
3737bcb6cafSSascha Wildner         }
3740d02842fSSascha Wildner         break;
3750d02842fSSascha Wildner 
3760d02842fSSascha Wildner     case PARSEOP_LOCAL0:
3770d02842fSSascha Wildner     case PARSEOP_LOCAL1:
3780d02842fSSascha Wildner     case PARSEOP_LOCAL2:
3790d02842fSSascha Wildner     case PARSEOP_LOCAL3:
3800d02842fSSascha Wildner     case PARSEOP_LOCAL4:
3810d02842fSSascha Wildner     case PARSEOP_LOCAL5:
3820d02842fSSascha Wildner     case PARSEOP_LOCAL6:
3830d02842fSSascha Wildner     case PARSEOP_LOCAL7:
3840d02842fSSascha Wildner 
3850d02842fSSascha Wildner         if (!MethodInfo)
3860d02842fSSascha Wildner         {
3870d02842fSSascha Wildner             /*
3880d02842fSSascha Wildner              * Local was used outside a control method, or there was an error
3890d02842fSSascha Wildner              * in the method declaration.
3900d02842fSSascha Wildner              */
391820c5b08SSascha Wildner             AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD,
392820c5b08SSascha Wildner                 Op, Op->Asl.ExternalName);
3930d02842fSSascha Wildner             return (AE_ERROR);
3940d02842fSSascha Wildner         }
3950d02842fSSascha Wildner 
396267c04fdSSascha Wildner         RegisterNumber = (Op->Asl.AmlOpcode & 0x0007);
3970d02842fSSascha Wildner 
3980d02842fSSascha Wildner         /*
3990d02842fSSascha Wildner          * If the local is being used as a target, mark the local
4000d02842fSSascha Wildner          * initialized
4010d02842fSSascha Wildner          */
4021093ca81SSascha Wildner         if (Op->Asl.CompileFlags & OP_IS_TARGET)
4030d02842fSSascha Wildner         {
4040d02842fSSascha Wildner             MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
4050d02842fSSascha Wildner         }
4060d02842fSSascha Wildner 
4070d02842fSSascha Wildner         /*
4080d02842fSSascha Wildner          * Otherwise, this is a reference, check if the local
4090d02842fSSascha Wildner          * has been previously initialized.
4100d02842fSSascha Wildner          *
4110d02842fSSascha Wildner          * The only operator that accepts an uninitialized value is ObjectType()
4120d02842fSSascha Wildner          */
4130d02842fSSascha Wildner         else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
4140d02842fSSascha Wildner                  (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
4150d02842fSSascha Wildner         {
4160d02842fSSascha Wildner             LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
4170d02842fSSascha Wildner             AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
4180d02842fSSascha Wildner         }
4190d02842fSSascha Wildner         break;
4200d02842fSSascha Wildner 
4210d02842fSSascha Wildner     case PARSEOP_ARG0:
4220d02842fSSascha Wildner     case PARSEOP_ARG1:
4230d02842fSSascha Wildner     case PARSEOP_ARG2:
4240d02842fSSascha Wildner     case PARSEOP_ARG3:
4250d02842fSSascha Wildner     case PARSEOP_ARG4:
4260d02842fSSascha Wildner     case PARSEOP_ARG5:
4270d02842fSSascha Wildner     case PARSEOP_ARG6:
4280d02842fSSascha Wildner 
4290d02842fSSascha Wildner         if (!MethodInfo)
4300d02842fSSascha Wildner         {
4310d02842fSSascha Wildner             /*
4320d02842fSSascha Wildner              * Arg was used outside a control method, or there was an error
4330d02842fSSascha Wildner              * in the method declaration.
4340d02842fSSascha Wildner              */
435820c5b08SSascha Wildner             AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD,
436820c5b08SSascha Wildner                 Op, Op->Asl.ExternalName);
4370d02842fSSascha Wildner             return (AE_ERROR);
4380d02842fSSascha Wildner         }
4390d02842fSSascha Wildner 
4400d02842fSSascha Wildner         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
4410d02842fSSascha Wildner         ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
4420d02842fSSascha Wildner 
4430d02842fSSascha Wildner         /*
4440d02842fSSascha Wildner          * If the Arg is being used as a target, mark the local
4450d02842fSSascha Wildner          * initialized
4460d02842fSSascha Wildner          */
4471093ca81SSascha Wildner         if (Op->Asl.CompileFlags & OP_IS_TARGET)
4480d02842fSSascha Wildner         {
4490d02842fSSascha Wildner             MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
4500d02842fSSascha Wildner         }
4510d02842fSSascha Wildner 
4520d02842fSSascha Wildner         /*
4530d02842fSSascha Wildner          * Otherwise, this is a reference, check if the Arg
4540d02842fSSascha Wildner          * has been previously initialized.
4550d02842fSSascha Wildner          *
4560d02842fSSascha Wildner          * The only operator that accepts an uninitialized value is ObjectType()
4570d02842fSSascha Wildner          */
4580d02842fSSascha Wildner         else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
4590d02842fSSascha Wildner             (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
4600d02842fSSascha Wildner         {
4610d02842fSSascha Wildner             AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
4620d02842fSSascha Wildner         }
4630d02842fSSascha Wildner 
4640d02842fSSascha Wildner         /* Flag this arg if it is not a "real" argument to the method */
4650d02842fSSascha Wildner 
4660d02842fSSascha Wildner         if (RegisterNumber >= MethodInfo->NumArguments)
4670d02842fSSascha Wildner         {
4680d02842fSSascha Wildner             AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
4690d02842fSSascha Wildner         }
4700d02842fSSascha Wildner         break;
4710d02842fSSascha Wildner 
4720d02842fSSascha Wildner     case PARSEOP_RETURN:
4730d02842fSSascha Wildner 
4740d02842fSSascha Wildner         if (!MethodInfo)
4750d02842fSSascha Wildner         {
4760d02842fSSascha Wildner             /*
4770d02842fSSascha Wildner              * Probably was an error in the method declaration,
4780d02842fSSascha Wildner              * no additional error here
4790d02842fSSascha Wildner              */
4800d02842fSSascha Wildner             ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
4810d02842fSSascha Wildner             return (AE_ERROR);
4820d02842fSSascha Wildner         }
4830d02842fSSascha Wildner 
4840d02842fSSascha Wildner         /*
4850d02842fSSascha Wildner          * A child indicates a possible return value. A simple Return or
4861093ca81SSascha Wildner          * Return() is marked with OP_IS_NULL_RETURN by the parser so
4870d02842fSSascha Wildner          * that it is not counted as a "real" return-with-value, although
4880d02842fSSascha Wildner          * the AML code that is actually emitted is Return(0). The AML
4890d02842fSSascha Wildner          * definition of Return has a required parameter, so we are
4900d02842fSSascha Wildner          * forced to convert a null return to Return(0).
4910d02842fSSascha Wildner          */
4920d02842fSSascha Wildner         if ((Op->Asl.Child) &&
4930d02842fSSascha Wildner             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
4941093ca81SSascha Wildner             (!(Op->Asl.Child->Asl.CompileFlags & OP_IS_NULL_RETURN)))
4950d02842fSSascha Wildner         {
4960d02842fSSascha Wildner             MethodInfo->NumReturnWithValue++;
4970d02842fSSascha Wildner         }
4980d02842fSSascha Wildner         else
4990d02842fSSascha Wildner         {
5000d02842fSSascha Wildner             MethodInfo->NumReturnNoValue++;
5010d02842fSSascha Wildner         }
5020d02842fSSascha Wildner         break;
5030d02842fSSascha Wildner 
5040d02842fSSascha Wildner     case PARSEOP_BREAK:
5050d02842fSSascha Wildner     case PARSEOP_CONTINUE:
5060d02842fSSascha Wildner 
5070d02842fSSascha Wildner         Next = Op->Asl.Parent;
5080d02842fSSascha Wildner         while (Next)
5090d02842fSSascha Wildner         {
5100d02842fSSascha Wildner             if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
5110d02842fSSascha Wildner             {
5120d02842fSSascha Wildner                 break;
5130d02842fSSascha Wildner             }
5140d02842fSSascha Wildner             Next = Next->Asl.Parent;
5150d02842fSSascha Wildner         }
5160d02842fSSascha Wildner 
5170d02842fSSascha Wildner         if (!Next)
5180d02842fSSascha Wildner         {
5190d02842fSSascha Wildner             AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
5200d02842fSSascha Wildner         }
5210d02842fSSascha Wildner         break;
5220d02842fSSascha Wildner 
5230d02842fSSascha Wildner     case PARSEOP_STALL:
5240d02842fSSascha Wildner 
5250d02842fSSascha Wildner         /* We can range check if the argument is an integer */
5260d02842fSSascha Wildner 
5270d02842fSSascha Wildner         if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
5280d02842fSSascha Wildner             (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
5290d02842fSSascha Wildner         {
5300d02842fSSascha Wildner             AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
5310d02842fSSascha Wildner         }
5320d02842fSSascha Wildner         break;
5330d02842fSSascha Wildner 
5340d02842fSSascha Wildner     case PARSEOP_DEVICE:
53579eafdd7SSascha Wildner 
536e5412f1eSSascha Wildner         /* Check usage of _HID and _ADR objects */
537e5412f1eSSascha Wildner 
538e5412f1eSSascha Wildner         HidExists = ApFindNameInDeviceTree (METHOD_NAME__HID, Op);
539e5412f1eSSascha Wildner         AdrExists = ApFindNameInDeviceTree (METHOD_NAME__ADR, Op);
540e5412f1eSSascha Wildner 
541e5412f1eSSascha Wildner         if (!HidExists && !AdrExists)
54279eafdd7SSascha Wildner         {
5430672a19bSSascha Wildner             AslError (ASL_ERROR, ASL_MSG_MISSING_DEPENDENCY, Op,
5440672a19bSSascha Wildner                 "Device object requires a _HID or _ADR");
54579eafdd7SSascha Wildner         }
546e5412f1eSSascha Wildner         else if (HidExists && AdrExists)
547e5412f1eSSascha Wildner         {
548e5412f1eSSascha Wildner             /*
549e5412f1eSSascha Wildner              * According to the ACPI spec, "A device object must contain
550e5412f1eSSascha Wildner              * either an _HID object or an _ADR object, but should not contain
551e5412f1eSSascha Wildner              * both".
552e5412f1eSSascha Wildner              */
553e5412f1eSSascha Wildner             AslError (ASL_WARNING, ASL_MSG_MULTIPLE_TYPES, Op,
554e5412f1eSSascha Wildner                 "Device object requires either a _HID or _ADR, but not both");
555e5412f1eSSascha Wildner         }
5560672a19bSSascha Wildner 
5570672a19bSSascha Wildner         /*
5580672a19bSSascha Wildner          * Check usage of _CRS, _DIS, _PRS, and _SRS objects (July 2021).
5590672a19bSSascha Wildner          *
5600672a19bSSascha Wildner          * Under the Device Object:
5610672a19bSSascha Wildner          *
562*84fe3360SSascha Wildner          * 1) If _PRS present, must have _CRS and _SRS
563*84fe3360SSascha Wildner          * 2) If _SRS present, must have _PRS (_PRS requires _CRS and _SRS)
564*84fe3360SSascha Wildner          * 3) If _DIS present, must have _SRS (_SRS requires _PRS, _PRS requires _CRS and _SRS)
565*84fe3360SSascha Wildner          * 4) If _SRS present, probably should have a _DIS (Remark only)
5660672a19bSSascha Wildner          */
5670672a19bSSascha Wildner         CrsExists = ApFindNameInDeviceTree (METHOD_NAME__CRS, Op);
5680672a19bSSascha Wildner         DisExists = ApFindNameInDeviceTree (METHOD_NAME__DIS, Op);
5690672a19bSSascha Wildner         PrsExists = ApFindNameInDeviceTree (METHOD_NAME__PRS, Op);
5700672a19bSSascha Wildner         SrsExists = ApFindNameInDeviceTree (METHOD_NAME__SRS, Op);
5710672a19bSSascha Wildner 
572*84fe3360SSascha Wildner         /* 1) If _PRS is present, must have a _CRS and _SRS */
5730672a19bSSascha Wildner 
5740672a19bSSascha Wildner         if (PrsExists)
5750672a19bSSascha Wildner         {
5760672a19bSSascha Wildner             if (!CrsExists)
5770672a19bSSascha Wildner             {
5780672a19bSSascha Wildner                 AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
579*84fe3360SSascha Wildner                     "Device has a _PRS, missing a _CRS, required");
5800672a19bSSascha Wildner             }
5810672a19bSSascha Wildner             if (!SrsExists)
5820672a19bSSascha Wildner             {
5830672a19bSSascha Wildner                 AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
584*84fe3360SSascha Wildner                     "Device has a _PRS, missing a _SRS, required");
5850672a19bSSascha Wildner             }
5860672a19bSSascha Wildner         }
5870672a19bSSascha Wildner 
588*84fe3360SSascha Wildner         /* 2) If _SRS is present, must have _PRS (_PRS requires _CRS and _SRS) */
5890672a19bSSascha Wildner 
590*84fe3360SSascha Wildner         if ((SrsExists) && (!PrsExists))
5910672a19bSSascha Wildner         {
5920672a19bSSascha Wildner             AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
593*84fe3360SSascha Wildner                 "Device has a _SRS, missing a _PRS, required");
5940672a19bSSascha Wildner         }
595*84fe3360SSascha Wildner 
596*84fe3360SSascha Wildner         /* 3) If _DIS is present, must have a _SRS */
597*84fe3360SSascha Wildner 
598*84fe3360SSascha Wildner         if ((DisExists) && (!SrsExists))
5990672a19bSSascha Wildner         {
6000672a19bSSascha Wildner             AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
601*84fe3360SSascha Wildner                 "Device has a _DIS, missing a _SRS, required");
6020672a19bSSascha Wildner         }
603*84fe3360SSascha Wildner 
604*84fe3360SSascha Wildner         /*
605*84fe3360SSascha Wildner          * 4) If _SRS is present, should have a _DIS (_PRS requires _CRS
606*84fe3360SSascha Wildner          * and _SRS)  Remark only.
607*84fe3360SSascha Wildner          */
608*84fe3360SSascha Wildner         if ((SrsExists) && (!DisExists))
6090672a19bSSascha Wildner         {
6100672a19bSSascha Wildner             AslError (ASL_REMARK, ASL_MSG_MISSING_DEPENDENCY, Op,
611*84fe3360SSascha Wildner                 "Device has a _SRS, no corresponding _DIS");
6120672a19bSSascha Wildner         }
61379eafdd7SSascha Wildner         break;
61479eafdd7SSascha Wildner 
6150d02842fSSascha Wildner     case PARSEOP_EVENT:
6160d02842fSSascha Wildner     case PARSEOP_MUTEX:
6170d02842fSSascha Wildner     case PARSEOP_OPERATIONREGION:
6180d02842fSSascha Wildner     case PARSEOP_POWERRESOURCE:
6190d02842fSSascha Wildner     case PARSEOP_PROCESSOR:
6200d02842fSSascha Wildner     case PARSEOP_THERMALZONE:
6210d02842fSSascha Wildner 
6220d02842fSSascha Wildner         /*
6230d02842fSSascha Wildner          * The first operand is a name to be created in the namespace.
6240d02842fSSascha Wildner          * Check against the reserved list.
6250d02842fSSascha Wildner          */
6260d02842fSSascha Wildner         i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
6270d02842fSSascha Wildner         if (i < ACPI_VALID_RESERVED_NAME_MAX)
6280d02842fSSascha Wildner         {
629820c5b08SSascha Wildner             AslError (ASL_ERROR, ASL_MSG_RESERVED_USE,
630820c5b08SSascha Wildner                 Op, Op->Asl.ExternalName);
6310d02842fSSascha Wildner         }
632ff3cb46dSSascha Wildner 
633ff3cb46dSSascha Wildner         MtCheckStaticOperationRegionInMethod (Op);
6340d02842fSSascha Wildner         break;
6350d02842fSSascha Wildner 
6360d02842fSSascha Wildner     case PARSEOP_NAME:
6370d02842fSSascha Wildner 
6380d02842fSSascha Wildner         /* Typecheck any predefined names statically defined with Name() */
6390d02842fSSascha Wildner 
6400d02842fSSascha Wildner         ApCheckForPredefinedObject (Op, Op->Asl.NameSeg);
6410d02842fSSascha Wildner 
6420d02842fSSascha Wildner         /* Special typechecking for _HID */
6430d02842fSSascha Wildner 
644e5412f1eSSascha Wildner         if (ACPI_COMPARE_NAMESEG (METHOD_NAME__HID, Op->Asl.NameSeg))
6450d02842fSSascha Wildner         {
6460d02842fSSascha Wildner             Next = Op->Asl.Child->Asl.Next;
6470d02842fSSascha Wildner             AnCheckId (Next, ASL_TYPE_HID);
6480d02842fSSascha Wildner         }
6490d02842fSSascha Wildner 
6500d02842fSSascha Wildner         /* Special typechecking for _CID */
6510d02842fSSascha Wildner 
652e5412f1eSSascha Wildner         else if (ACPI_COMPARE_NAMESEG (METHOD_NAME__CID, Op->Asl.NameSeg))
6530d02842fSSascha Wildner         {
6540d02842fSSascha Wildner             Next = Op->Asl.Child->Asl.Next;
6550d02842fSSascha Wildner 
6560d02842fSSascha Wildner             if ((Next->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
6570d02842fSSascha Wildner                 (Next->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
6580d02842fSSascha Wildner             {
6590d02842fSSascha Wildner                 Next = Next->Asl.Child;
6600d02842fSSascha Wildner                 while (Next)
6610d02842fSSascha Wildner                 {
6620d02842fSSascha Wildner                     AnCheckId (Next, ASL_TYPE_CID);
6630d02842fSSascha Wildner                     Next = Next->Asl.Next;
6640d02842fSSascha Wildner                 }
6650d02842fSSascha Wildner             }
6660d02842fSSascha Wildner             else
6670d02842fSSascha Wildner             {
6680d02842fSSascha Wildner                 AnCheckId (Next, ASL_TYPE_CID);
6690d02842fSSascha Wildner             }
6700d02842fSSascha Wildner         }
6719e1c0880SSascha Wildner 
6720d02842fSSascha Wildner         break;
6730d02842fSSascha Wildner 
6740d02842fSSascha Wildner     default:
6750d02842fSSascha Wildner 
6760d02842fSSascha Wildner         break;
6770d02842fSSascha Wildner     }
6780d02842fSSascha Wildner 
6790d02842fSSascha Wildner     /* Check for named object creation within a non-serialized method */
6800d02842fSSascha Wildner 
6810d02842fSSascha Wildner     MtCheckNamedObjectInMethod (Op, MethodInfo);
6820d02842fSSascha Wildner     return (AE_OK);
6830d02842fSSascha Wildner }
6840d02842fSSascha Wildner 
6850d02842fSSascha Wildner 
6860d02842fSSascha Wildner /*******************************************************************************
6870d02842fSSascha Wildner  *
688ff3cb46dSSascha Wildner  * FUNCTION:    MtProcessTypeOp
689ff3cb46dSSascha Wildner  *
690ff3cb46dSSascha Wildner  * PARAMETERS:  Op                  - Op representing a btype
691ff3cb46dSSascha Wildner  *
692ff3cb46dSSascha Wildner  * RETURN:      Btype represented by Op
693ff3cb46dSSascha Wildner  *
694ff3cb46dSSascha Wildner  * DESCRIPTION: Process a parse object that represents single parameter type or
695ff3cb46dSSascha Wildner  *              a return type in method, function, and external declarations.
696ff3cb46dSSascha Wildner  *
697ff3cb46dSSascha Wildner  ******************************************************************************/
698ff3cb46dSSascha Wildner 
699ff3cb46dSSascha Wildner UINT32
MtProcessTypeOp(ACPI_PARSE_OBJECT * TypeOp)700ff3cb46dSSascha Wildner MtProcessTypeOp (
701ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT       *TypeOp)
702ff3cb46dSSascha Wildner {
703ff3cb46dSSascha Wildner     UINT32                  Btype = ACPI_BTYPE_ANY;
704ff3cb46dSSascha Wildner 
705ff3cb46dSSascha Wildner 
706ff3cb46dSSascha Wildner     while (TypeOp)
707ff3cb46dSSascha Wildner     {
708ff3cb46dSSascha Wildner         Btype |= AnMapObjTypeToBtype (TypeOp);
709ff3cb46dSSascha Wildner         TypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
710ff3cb46dSSascha Wildner         TypeOp = TypeOp->Asl.Next;
711ff3cb46dSSascha Wildner     }
712ff3cb46dSSascha Wildner 
713ff3cb46dSSascha Wildner     return (Btype);
714ff3cb46dSSascha Wildner }
715ff3cb46dSSascha Wildner 
716ff3cb46dSSascha Wildner 
717ff3cb46dSSascha Wildner /*******************************************************************************
718ff3cb46dSSascha Wildner  *
719ff3cb46dSSascha Wildner  * FUNCTION:    MtProcessParameterTypeList
720ff3cb46dSSascha Wildner  *
721ff3cb46dSSascha Wildner  * PARAMETERS:  Op                  - Op representing a btype
722ff3cb46dSSascha Wildner  *
723ff3cb46dSSascha Wildner  * RETURN:      Btype represented by Op
724ff3cb46dSSascha Wildner  *
725ff3cb46dSSascha Wildner  * DESCRIPTION: Process a parse object that represents a parameter type list in
726ff3cb46dSSascha Wildner  *              method, function, and external declarations.
727ff3cb46dSSascha Wildner  *
728ff3cb46dSSascha Wildner  ******************************************************************************/
729ff3cb46dSSascha Wildner 
730ff3cb46dSSascha Wildner UINT8
MtProcessParameterTypeList(ACPI_PARSE_OBJECT * ParamTypeOp,UINT32 * TypeList)731ff3cb46dSSascha Wildner MtProcessParameterTypeList (
732ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT       *ParamTypeOp,
733ff3cb46dSSascha Wildner     UINT32                  *TypeList)
734ff3cb46dSSascha Wildner {
735ff3cb46dSSascha Wildner     UINT8                   ParameterCount = 0;
736ff3cb46dSSascha Wildner 
737ff3cb46dSSascha Wildner 
7384758d649SSascha Wildner     if (ParamTypeOp && ParamTypeOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
7394758d649SSascha Wildner     {
7404758d649SSascha Wildner         /* Special case for a single parameter without braces */
7414758d649SSascha Wildner 
7424758d649SSascha Wildner         TypeList[ParameterCount] =
7434758d649SSascha Wildner             MtProcessTypeOp (ParamTypeOp);
7444758d649SSascha Wildner 
7454758d649SSascha Wildner         return (1);
7464758d649SSascha Wildner     }
7474758d649SSascha Wildner 
748ff3cb46dSSascha Wildner     while (ParamTypeOp)
749ff3cb46dSSascha Wildner     {
750ff3cb46dSSascha Wildner         TypeList[ParameterCount] =
751ff3cb46dSSascha Wildner             MtProcessTypeOp (ParamTypeOp->Asl.Child);
752ff3cb46dSSascha Wildner 
753ff3cb46dSSascha Wildner         ParameterCount++;
754ff3cb46dSSascha Wildner         ParamTypeOp = ParamTypeOp->Asl.Next;
755ff3cb46dSSascha Wildner     }
756ff3cb46dSSascha Wildner 
757ff3cb46dSSascha Wildner     return (ParameterCount);
758ff3cb46dSSascha Wildner }
759ff3cb46dSSascha Wildner 
760ff3cb46dSSascha Wildner 
761ff3cb46dSSascha Wildner /*******************************************************************************
762ff3cb46dSSascha Wildner  *
7630d02842fSSascha Wildner  * FUNCTION:    MtCheckNamedObjectInMethod
7640d02842fSSascha Wildner  *
7650d02842fSSascha Wildner  * PARAMETERS:  Op                  - Current parser op
7660d02842fSSascha Wildner  *              MethodInfo          - Info for method being parsed
7670d02842fSSascha Wildner  *
7680d02842fSSascha Wildner  * RETURN:      None
7690d02842fSSascha Wildner  *
7700d02842fSSascha Wildner  * DESCRIPTION: Detect if a non-serialized method is creating a named object,
7710d02842fSSascha Wildner  *              which could possibly cause problems if two threads execute
7720d02842fSSascha Wildner  *              the method concurrently. Emit a remark in this case.
7730d02842fSSascha Wildner  *
7740d02842fSSascha Wildner  ******************************************************************************/
7750d02842fSSascha Wildner 
7767c9678bcSSascha Wildner static void
MtCheckNamedObjectInMethod(ACPI_PARSE_OBJECT * Op,ASL_METHOD_INFO * MethodInfo)7770d02842fSSascha Wildner MtCheckNamedObjectInMethod (
7780d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
7790d02842fSSascha Wildner     ASL_METHOD_INFO         *MethodInfo)
7800d02842fSSascha Wildner {
7810d02842fSSascha Wildner     const ACPI_OPCODE_INFO  *OpInfo;
782ff3cb46dSSascha Wildner     char                    *ExternalPath;
7830d02842fSSascha Wildner 
7840d02842fSSascha Wildner 
785820c5b08SSascha Wildner     /* We don't care about actual method declarations or scopes */
7860d02842fSSascha Wildner 
787820c5b08SSascha Wildner     if ((Op->Asl.AmlOpcode == AML_METHOD_OP) ||
788820c5b08SSascha Wildner         (Op->Asl.AmlOpcode == AML_SCOPE_OP))
7890d02842fSSascha Wildner     {
7900d02842fSSascha Wildner         return;
7910d02842fSSascha Wildner     }
7920d02842fSSascha Wildner 
7937bcb6cafSSascha Wildner     /* Determine if we are creating a named object within a method */
7947bcb6cafSSascha Wildner 
7957bcb6cafSSascha Wildner     if (!MethodInfo)
7967bcb6cafSSascha Wildner     {
7977bcb6cafSSascha Wildner         return;
7987bcb6cafSSascha Wildner     }
7990d02842fSSascha Wildner 
8000d02842fSSascha Wildner     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
801d0dff17aSSascha Wildner     if ((OpInfo->Class == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_FIELD_OP))
8020d02842fSSascha Wildner     {
8030d02842fSSascha Wildner         /*
8047bcb6cafSSascha Wildner          * 1) Mark the method as a method that creates named objects.
8057bcb6cafSSascha Wildner          *
806ff3cb46dSSascha Wildner          * 2) Issue a remark indicating the inefficiency of creating named
807ff3cb46dSSascha Wildner          * objects within a method (Except for compiler-emitted temporary
808ff3cb46dSSascha Wildner          * variables).
809ff3cb46dSSascha Wildner          *
810ff3cb46dSSascha Wildner          * 3) If the method is non-serialized, emit a remark that the method
8117bcb6cafSSascha Wildner          * should be serialized.
8120d02842fSSascha Wildner          *
8130d02842fSSascha Wildner          * Reason: If a thread blocks within the method for any reason, and
8147bcb6cafSSascha Wildner          * another thread enters the method, the method will fail because
8157bcb6cafSSascha Wildner          * an attempt will be made to create the same object twice.
816d0dff17aSSascha Wildner          *
817d0dff17aSSascha Wildner          * Note: The Field opcode is disallowed here because Field() does not
818d0dff17aSSascha Wildner          * create a new named object.
8190d02842fSSascha Wildner          */
820ff3cb46dSSascha Wildner         ExternalPath = AcpiNsGetNormalizedPathname (MethodInfo->Op->Asl.Node, TRUE);
821ff3cb46dSSascha Wildner 
822ff3cb46dSSascha Wildner         /* No error for compiler temp variables (name starts with "_T_") */
823ff3cb46dSSascha Wildner 
824ff3cb46dSSascha Wildner         if ((Op->Asl.NameSeg[0] != '_') &&
825ff3cb46dSSascha Wildner             (Op->Asl.NameSeg[1] != 'T') &&
826ff3cb46dSSascha Wildner             (Op->Asl.NameSeg[2] != '_'))
827ff3cb46dSSascha Wildner         {
828ff3cb46dSSascha Wildner             AslError (ASL_REMARK, ASL_MSG_NAMED_OBJECT_CREATION, Op,
829ff3cb46dSSascha Wildner                 ExternalPath);
830ff3cb46dSSascha Wildner         }
831ff3cb46dSSascha Wildner 
8327bcb6cafSSascha Wildner         MethodInfo->CreatesNamedObjects = TRUE;
8337bcb6cafSSascha Wildner         if (!MethodInfo->ShouldBeSerialized)
8340d02842fSSascha Wildner         {
8350d02842fSSascha Wildner             AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op,
836ff3cb46dSSascha Wildner                 ExternalPath);
8370d02842fSSascha Wildner 
8380d02842fSSascha Wildner             /* Emit message only ONCE per method */
8390d02842fSSascha Wildner 
8400d02842fSSascha Wildner             MethodInfo->ShouldBeSerialized = TRUE;
8410d02842fSSascha Wildner         }
842ff3cb46dSSascha Wildner 
843ff3cb46dSSascha Wildner         if (ExternalPath)
844ff3cb46dSSascha Wildner         {
845ff3cb46dSSascha Wildner             ACPI_FREE (ExternalPath);
8460d02842fSSascha Wildner         }
8470d02842fSSascha Wildner     }
848ff3cb46dSSascha Wildner }
849ff3cb46dSSascha Wildner 
850ff3cb46dSSascha Wildner 
851ff3cb46dSSascha Wildner /*******************************************************************************
852ff3cb46dSSascha Wildner  *
853ff3cb46dSSascha Wildner  * FUNCTION:    MtCheckStaticOperationRegionInMethod
854ff3cb46dSSascha Wildner  *
855ff3cb46dSSascha Wildner  * PARAMETERS:  Op                  - Current parser op
856ff3cb46dSSascha Wildner  *
857ff3cb46dSSascha Wildner  * RETURN:      None
858ff3cb46dSSascha Wildner  *
859ff3cb46dSSascha Wildner  * DESCRIPTION: Warns if an Operation Region with static address or length
860ff3cb46dSSascha Wildner  *              is declared inside a control method
861ff3cb46dSSascha Wildner  *
862ff3cb46dSSascha Wildner  ******************************************************************************/
863ff3cb46dSSascha Wildner 
864ff3cb46dSSascha Wildner static void
MtCheckStaticOperationRegionInMethod(ACPI_PARSE_OBJECT * Op)865ff3cb46dSSascha Wildner MtCheckStaticOperationRegionInMethod(
866ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT*       Op)
867ff3cb46dSSascha Wildner {
868ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT*       AddressOp;
869ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT*       LengthOp;
870ff3cb46dSSascha Wildner 
871ff3cb46dSSascha Wildner 
872ff3cb46dSSascha Wildner     if (Op->Asl.ParseOpcode != PARSEOP_OPERATIONREGION)
873ff3cb46dSSascha Wildner     {
874ff3cb46dSSascha Wildner         return;
875ff3cb46dSSascha Wildner     }
876ff3cb46dSSascha Wildner 
877ff3cb46dSSascha Wildner     /*
878ff3cb46dSSascha Wildner      * OperationRegion should have 4 arguments defined. At this point, we
879ff3cb46dSSascha Wildner      * assume that the parse tree is well-formed.
880ff3cb46dSSascha Wildner      */
881ff3cb46dSSascha Wildner     AddressOp = Op->Asl.Child->Asl.Next->Asl.Next;
882ff3cb46dSSascha Wildner     LengthOp = Op->Asl.Child->Asl.Next->Asl.Next->Asl.Next;
883ff3cb46dSSascha Wildner 
884ff3cb46dSSascha Wildner     if (UtGetParentMethodOp (Op) &&
885ff3cb46dSSascha Wildner         AddressOp->Asl.ParseOpcode == PARSEOP_INTEGER &&
886ff3cb46dSSascha Wildner         LengthOp->Asl.ParseOpcode == PARSEOP_INTEGER)
887ff3cb46dSSascha Wildner     {
888ff3cb46dSSascha Wildner         /*
889ff3cb46dSSascha Wildner          * At this point, a static operation region declared inside of a
890ff3cb46dSSascha Wildner          * control method has been found. Throw a warning because this is
891ff3cb46dSSascha Wildner          * highly inefficient.
892ff3cb46dSSascha Wildner          */
893ff3cb46dSSascha Wildner         AslError(ASL_WARNING, ASL_MSG_STATIC_OPREGION_IN_METHOD, Op, NULL);
894ff3cb46dSSascha Wildner     }
895ff3cb46dSSascha Wildner 
896ff3cb46dSSascha Wildner     return;
897ff3cb46dSSascha Wildner }
8980d02842fSSascha Wildner 
8990d02842fSSascha Wildner 
9000d02842fSSascha Wildner /*******************************************************************************
9010d02842fSSascha Wildner  *
9020d02842fSSascha Wildner  * FUNCTION:    MtMethodAnalysisWalkEnd
9030d02842fSSascha Wildner  *
9040d02842fSSascha Wildner  * PARAMETERS:  ASL_WALK_CALLBACK
9050d02842fSSascha Wildner  *
9060d02842fSSascha Wildner  * RETURN:      Status
9070d02842fSSascha Wildner  *
9080d02842fSSascha Wildner  * DESCRIPTION: Ascending callback for analysis walk. Complete method
9090d02842fSSascha Wildner  *              return analysis.
9100d02842fSSascha Wildner  *
9110d02842fSSascha Wildner  ******************************************************************************/
9120d02842fSSascha Wildner 
9130d02842fSSascha Wildner ACPI_STATUS
MtMethodAnalysisWalkEnd(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)9140d02842fSSascha Wildner MtMethodAnalysisWalkEnd (
9150d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
9160d02842fSSascha Wildner     UINT32                  Level,
9170d02842fSSascha Wildner     void                    *Context)
9180d02842fSSascha Wildner {
9190d02842fSSascha Wildner     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
9200d02842fSSascha Wildner     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
921ff3cb46dSSascha Wildner     char                    *ExternalPath;
9220d02842fSSascha Wildner 
9230d02842fSSascha Wildner 
9240d02842fSSascha Wildner     switch (Op->Asl.ParseOpcode)
9250d02842fSSascha Wildner     {
9260d02842fSSascha Wildner     case PARSEOP_METHOD:
9270d02842fSSascha Wildner     case PARSEOP_RETURN:
9280d02842fSSascha Wildner 
9290d02842fSSascha Wildner         if (!MethodInfo)
9300d02842fSSascha Wildner         {
9310d02842fSSascha Wildner             printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
9320d02842fSSascha Wildner             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
9330d02842fSSascha Wildner                 "No method info for this method");
9340d02842fSSascha Wildner 
9350d02842fSSascha Wildner             CmCleanupAndExit ();
9360d02842fSSascha Wildner             return (AE_AML_INTERNAL);
9370d02842fSSascha Wildner         }
9380d02842fSSascha Wildner         break;
9390d02842fSSascha Wildner 
9400d02842fSSascha Wildner     default:
9410d02842fSSascha Wildner 
9420d02842fSSascha Wildner         break;
9430d02842fSSascha Wildner     }
9440d02842fSSascha Wildner 
9450d02842fSSascha Wildner     switch (Op->Asl.ParseOpcode)
9460d02842fSSascha Wildner     {
9470d02842fSSascha Wildner     case PARSEOP_METHOD:
9480d02842fSSascha Wildner 
9490d02842fSSascha Wildner         WalkInfo->MethodStack = MethodInfo->Next;
9500d02842fSSascha Wildner 
9510d02842fSSascha Wildner         /*
9520d02842fSSascha Wildner          * Check if there is no return statement at the end of the
9530d02842fSSascha Wildner          * method AND we can actually get there -- i.e., the execution
9540d02842fSSascha Wildner          * of the method can possibly terminate without a return statement.
9550d02842fSSascha Wildner          */
9560d02842fSSascha Wildner         if ((!AnLastStatementIsReturn (Op)) &&
9571093ca81SSascha Wildner             (!(Op->Asl.CompileFlags & OP_HAS_NO_EXIT)))
9580d02842fSSascha Wildner         {
9590d02842fSSascha Wildner             /*
9600d02842fSSascha Wildner              * No return statement, and execution can possibly exit
9610d02842fSSascha Wildner              * via this path. This is equivalent to Return ()
9620d02842fSSascha Wildner              */
9630d02842fSSascha Wildner             MethodInfo->NumReturnNoValue++;
9640d02842fSSascha Wildner         }
9650d02842fSSascha Wildner 
9660d02842fSSascha Wildner         /*
9670d02842fSSascha Wildner          * Check for case where some return statements have a return value
9680d02842fSSascha Wildner          * and some do not. Exit without a return statement is a return with
9690d02842fSSascha Wildner          * no value
9700d02842fSSascha Wildner          */
9710d02842fSSascha Wildner         if (MethodInfo->NumReturnNoValue &&
9720d02842fSSascha Wildner             MethodInfo->NumReturnWithValue)
9730d02842fSSascha Wildner         {
974ff3cb46dSSascha Wildner             ExternalPath = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE);
975ff3cb46dSSascha Wildner 
9760d02842fSSascha Wildner             AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
977ff3cb46dSSascha Wildner                 ExternalPath);
978ff3cb46dSSascha Wildner 
979ff3cb46dSSascha Wildner             if (ExternalPath)
980ff3cb46dSSascha Wildner             {
981ff3cb46dSSascha Wildner                 ACPI_FREE (ExternalPath);
982ff3cb46dSSascha Wildner             }
9830d02842fSSascha Wildner         }
9840d02842fSSascha Wildner 
9850d02842fSSascha Wildner         /*
9860d02842fSSascha Wildner          * If there are any RETURN() statements with no value, or there is a
9870d02842fSSascha Wildner          * control path that allows the method to exit without a return value,
9880d02842fSSascha Wildner          * we mark the method as a method that does not return a value. This
9890d02842fSSascha Wildner          * knowledge can be used to check method invocations that expect a
9900d02842fSSascha Wildner          * returned value.
9910d02842fSSascha Wildner          */
9920d02842fSSascha Wildner         if (MethodInfo->NumReturnNoValue)
9930d02842fSSascha Wildner         {
9940d02842fSSascha Wildner             if (MethodInfo->NumReturnWithValue)
9950d02842fSSascha Wildner             {
9961093ca81SSascha Wildner                 Op->Asl.CompileFlags |= OP_METHOD_SOME_NO_RETVAL;
9970d02842fSSascha Wildner             }
9980d02842fSSascha Wildner             else
9990d02842fSSascha Wildner             {
10001093ca81SSascha Wildner                 Op->Asl.CompileFlags |= OP_METHOD_NO_RETVAL;
10010d02842fSSascha Wildner             }
10020d02842fSSascha Wildner         }
10030d02842fSSascha Wildner 
10040d02842fSSascha Wildner         /*
10050d02842fSSascha Wildner          * Check predefined method names for correct return behavior
10060d02842fSSascha Wildner          * and correct number of arguments. Also, some special checks
10070d02842fSSascha Wildner          * For GPE and _REG methods.
10080d02842fSSascha Wildner          */
10090d02842fSSascha Wildner         if (ApCheckForPredefinedMethod (Op, MethodInfo))
10100d02842fSSascha Wildner         {
10110d02842fSSascha Wildner             /* Special check for two names like _L01 and _E01 in same scope */
10120d02842fSSascha Wildner 
10130d02842fSSascha Wildner             ApCheckForGpeNameConflict (Op);
10140d02842fSSascha Wildner 
10150d02842fSSascha Wildner             /*
10160d02842fSSascha Wildner              * Special check for _REG: Must have an operation region definition
10170d02842fSSascha Wildner              * within the same scope!
10180d02842fSSascha Wildner              */
10190d02842fSSascha Wildner             ApCheckRegMethod (Op);
10200d02842fSSascha Wildner         }
10210d02842fSSascha Wildner 
10220d02842fSSascha Wildner         ACPI_FREE (MethodInfo);
10230d02842fSSascha Wildner         break;
10240d02842fSSascha Wildner 
10250d02842fSSascha Wildner     case PARSEOP_NAME:
10260d02842fSSascha Wildner 
10270d02842fSSascha Wildner          /* Special check for two names like _L01 and _E01 in same scope */
10280d02842fSSascha Wildner 
10290d02842fSSascha Wildner         ApCheckForGpeNameConflict (Op);
10300d02842fSSascha Wildner         break;
10310d02842fSSascha Wildner 
10320d02842fSSascha Wildner     case PARSEOP_RETURN:
10330d02842fSSascha Wildner 
10340d02842fSSascha Wildner         /*
10350d02842fSSascha Wildner          * If the parent is a predefined method name, attempt to typecheck
10360d02842fSSascha Wildner          * the return value. Only static types can be validated.
10370d02842fSSascha Wildner          */
10380d02842fSSascha Wildner         ApCheckPredefinedReturnValue (Op, MethodInfo);
10390d02842fSSascha Wildner 
10400d02842fSSascha Wildner         /*
10410d02842fSSascha Wildner          * The parent block does not "exit" and continue execution -- the
10420d02842fSSascha Wildner          * method is terminated here with the Return() statement.
10430d02842fSSascha Wildner          */
10441093ca81SSascha Wildner         Op->Asl.Parent->Asl.CompileFlags |= OP_HAS_NO_EXIT;
10450d02842fSSascha Wildner 
10460d02842fSSascha Wildner         /* Used in the "typing" pass later */
10470d02842fSSascha Wildner 
10480d02842fSSascha Wildner         Op->Asl.ParentMethod = MethodInfo->Op;
10490d02842fSSascha Wildner 
10500d02842fSSascha Wildner         /*
10510d02842fSSascha Wildner          * If there is a peer node after the return statement, then this
10520d02842fSSascha Wildner          * node is unreachable code -- i.e., it won't be executed because of
10530d02842fSSascha Wildner          * the preceding Return() statement.
10540d02842fSSascha Wildner          */
10550d02842fSSascha Wildner         if (Op->Asl.Next)
10560d02842fSSascha Wildner         {
1057820c5b08SSascha Wildner             AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE,
1058820c5b08SSascha Wildner                 Op->Asl.Next, NULL);
10590d02842fSSascha Wildner         }
10600d02842fSSascha Wildner         break;
10610d02842fSSascha Wildner 
10620d02842fSSascha Wildner     case PARSEOP_IF:
10630d02842fSSascha Wildner 
10641093ca81SSascha Wildner         if ((Op->Asl.CompileFlags & OP_HAS_NO_EXIT) &&
10650d02842fSSascha Wildner             (Op->Asl.Next) &&
10660d02842fSSascha Wildner             (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
10670d02842fSSascha Wildner         {
10680d02842fSSascha Wildner             /*
10690d02842fSSascha Wildner              * This IF has a corresponding ELSE. The IF block has no exit,
10700d02842fSSascha Wildner              * (it contains an unconditional Return)
10710d02842fSSascha Wildner              * mark the ELSE block to remember this fact.
10720d02842fSSascha Wildner              */
10731093ca81SSascha Wildner             Op->Asl.Next->Asl.CompileFlags |= OP_IF_HAS_NO_EXIT;
10740d02842fSSascha Wildner         }
10750d02842fSSascha Wildner         break;
10760d02842fSSascha Wildner 
10770d02842fSSascha Wildner     case PARSEOP_ELSE:
10780d02842fSSascha Wildner 
10791093ca81SSascha Wildner         if ((Op->Asl.CompileFlags & OP_HAS_NO_EXIT) &&
10801093ca81SSascha Wildner             (Op->Asl.CompileFlags & OP_IF_HAS_NO_EXIT))
10810d02842fSSascha Wildner         {
10820d02842fSSascha Wildner             /*
10830d02842fSSascha Wildner              * This ELSE block has no exit and the corresponding IF block
10840d02842fSSascha Wildner              * has no exit either. Therefore, the parent node has no exit.
10850d02842fSSascha Wildner              */
10861093ca81SSascha Wildner             Op->Asl.Parent->Asl.CompileFlags |= OP_HAS_NO_EXIT;
10870d02842fSSascha Wildner         }
10880d02842fSSascha Wildner         break;
10890d02842fSSascha Wildner 
10900d02842fSSascha Wildner 
10910d02842fSSascha Wildner     default:
10920d02842fSSascha Wildner 
10931093ca81SSascha Wildner         if ((Op->Asl.CompileFlags & OP_HAS_NO_EXIT) &&
10940d02842fSSascha Wildner             (Op->Asl.Parent))
10950d02842fSSascha Wildner         {
10960d02842fSSascha Wildner             /* If this node has no exit, then the parent has no exit either */
10970d02842fSSascha Wildner 
10981093ca81SSascha Wildner             Op->Asl.Parent->Asl.CompileFlags |= OP_HAS_NO_EXIT;
10990d02842fSSascha Wildner         }
11000d02842fSSascha Wildner         break;
11010d02842fSSascha Wildner     }
11020d02842fSSascha Wildner 
11030d02842fSSascha Wildner     return (AE_OK);
11040d02842fSSascha Wildner }
1105