xref: /dflybsd-src/sys/contrib/dev/acpica/source/compiler/aslxref.c (revision 383048aca08c2de51d27aa8638a36982a0d74550)
10d02842fSSascha Wildner /******************************************************************************
20d02842fSSascha Wildner  *
30d02842fSSascha Wildner  * Module Name: aslxref - Namespace cross-reference
40d02842fSSascha Wildner  *
50d02842fSSascha Wildner  *****************************************************************************/
60d02842fSSascha Wildner 
7b4315fc7SSascha Wildner /******************************************************************************
8b4315fc7SSascha Wildner  *
9b4315fc7SSascha Wildner  * 1. Copyright Notice
10b4315fc7SSascha Wildner  *
11*383048acSSascha 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"
1540d02842fSSascha Wildner #include "acparser.h"
1550d02842fSSascha Wildner #include "amlcode.h"
1560d02842fSSascha Wildner #include "acnamesp.h"
1570d02842fSSascha Wildner #include "acdispat.h"
1580d02842fSSascha Wildner 
1590d02842fSSascha Wildner 
1600d02842fSSascha Wildner #define _COMPONENT          ACPI_COMPILER
1610d02842fSSascha Wildner         ACPI_MODULE_NAME    ("aslxref")
1620d02842fSSascha Wildner 
1630d02842fSSascha Wildner /* Local prototypes */
1640d02842fSSascha Wildner 
1650d02842fSSascha Wildner static ACPI_STATUS
1660d02842fSSascha Wildner XfNamespaceLocateBegin (
1670d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1680d02842fSSascha Wildner     UINT32                  Level,
1690d02842fSSascha Wildner     void                    *Context);
1700d02842fSSascha Wildner 
1710d02842fSSascha Wildner static ACPI_STATUS
1720d02842fSSascha Wildner XfNamespaceLocateEnd (
1730d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1740d02842fSSascha Wildner     UINT32                  Level,
1750d02842fSSascha Wildner     void                    *Context);
1760d02842fSSascha Wildner 
17700ffa116SSascha Wildner static BOOLEAN
17800ffa116SSascha Wildner XfValidateCrossReference (
17900ffa116SSascha Wildner     ACPI_PARSE_OBJECT       *Op,
18000ffa116SSascha Wildner     const ACPI_OPCODE_INFO  *OpInfo,
18100ffa116SSascha Wildner     ACPI_NAMESPACE_NODE     *Node);
18200ffa116SSascha Wildner 
1830d02842fSSascha Wildner static BOOLEAN
1840d02842fSSascha Wildner XfObjectExists (
1850d02842fSSascha Wildner     char                    *Name);
1860d02842fSSascha Wildner 
1870d02842fSSascha Wildner static ACPI_STATUS
1880d02842fSSascha Wildner XfCompareOneNamespaceObject (
1890d02842fSSascha Wildner     ACPI_HANDLE             ObjHandle,
1900d02842fSSascha Wildner     UINT32                  Level,
1910d02842fSSascha Wildner     void                    *Context,
1920d02842fSSascha Wildner     void                    **ReturnValue);
1930d02842fSSascha Wildner 
1940d02842fSSascha Wildner static void
1950d02842fSSascha Wildner XfCheckFieldRange (
1960d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1970d02842fSSascha Wildner     UINT32                  RegionBitLength,
1980d02842fSSascha Wildner     UINT32                  FieldBitOffset,
1990d02842fSSascha Wildner     UINT32                  FieldBitLength,
2000d02842fSSascha Wildner     UINT32                  AccessBitWidth);
2010d02842fSSascha Wildner 
2020f79e681SSascha Wildner static BOOLEAN
2030f79e681SSascha Wildner XfFindCondRefOfName (
2040f79e681SSascha Wildner     ACPI_NAMESPACE_NODE     *Node,
2050f79e681SSascha Wildner     ACPI_PARSE_OBJECT       *Op);
2060f79e681SSascha Wildner 
2070f79e681SSascha Wildner static BOOLEAN
2080f79e681SSascha Wildner XfRefIsGuardedByIfCondRefOf (
2090f79e681SSascha Wildner     ACPI_NAMESPACE_NODE     *Node,
2100f79e681SSascha Wildner     ACPI_PARSE_OBJECT       *Op);
2110f79e681SSascha Wildner 
2120d02842fSSascha Wildner 
2130d02842fSSascha Wildner /*******************************************************************************
2140d02842fSSascha Wildner  *
2150d02842fSSascha Wildner  * FUNCTION:    XfCrossReferenceNamespace
2160d02842fSSascha Wildner  *
2170d02842fSSascha Wildner  * PARAMETERS:  None
2180d02842fSSascha Wildner  *
2190d02842fSSascha Wildner  * RETURN:      Status
2200d02842fSSascha Wildner  *
2210d02842fSSascha Wildner  * DESCRIPTION: Perform a cross reference check of the parse tree against the
2220d02842fSSascha Wildner  *              namespace. Every named referenced within the parse tree
2230d02842fSSascha Wildner  *              should be get resolved with a namespace lookup. If not, the
2240d02842fSSascha Wildner  *              original reference in the ASL code is invalid -- i.e., refers
2250d02842fSSascha Wildner  *              to a non-existent object.
2260d02842fSSascha Wildner  *
2270d02842fSSascha Wildner  * NOTE:  The ASL "External" operator causes the name to be inserted into the
2280d02842fSSascha Wildner  *        namespace so that references to the external name will be resolved
2290d02842fSSascha Wildner  *        correctly here.
2300d02842fSSascha Wildner  *
2310d02842fSSascha Wildner  ******************************************************************************/
2320d02842fSSascha Wildner 
2330d02842fSSascha Wildner ACPI_STATUS
XfCrossReferenceNamespace(void)2340d02842fSSascha Wildner XfCrossReferenceNamespace (
2350d02842fSSascha Wildner     void)
2360d02842fSSascha Wildner {
2370d02842fSSascha Wildner     ACPI_WALK_STATE         *WalkState;
2380d02842fSSascha Wildner 
2390d02842fSSascha Wildner 
2400d02842fSSascha Wildner     /*
2410d02842fSSascha Wildner      * Create a new walk state for use when looking up names
2420d02842fSSascha Wildner      * within the namespace (Passed as context to the callbacks)
2430d02842fSSascha Wildner      */
2440d02842fSSascha Wildner     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
2450d02842fSSascha Wildner     if (!WalkState)
2460d02842fSSascha Wildner     {
2470d02842fSSascha Wildner         return (AE_NO_MEMORY);
2480d02842fSSascha Wildner     }
2490d02842fSSascha Wildner 
2500d02842fSSascha Wildner     /* Walk the entire parse tree */
2510d02842fSSascha Wildner 
252806343b9SSascha Wildner     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
2537c9678bcSSascha Wildner         XfNamespaceLocateBegin, XfNamespaceLocateEnd, WalkState);
25479eafdd7SSascha Wildner 
25579eafdd7SSascha Wildner     ACPI_FREE (WalkState);
2560d02842fSSascha Wildner     return (AE_OK);
2570d02842fSSascha Wildner }
2580d02842fSSascha Wildner 
2590d02842fSSascha Wildner 
2600d02842fSSascha Wildner /*******************************************************************************
2610d02842fSSascha Wildner  *
2620d02842fSSascha Wildner  * FUNCTION:    XfObjectExists
2630d02842fSSascha Wildner  *
2640d02842fSSascha Wildner  * PARAMETERS:  Name            - 4 char ACPI name
2650d02842fSSascha Wildner  *
2660d02842fSSascha Wildner  * RETURN:      TRUE if name exists in namespace
2670d02842fSSascha Wildner  *
2680d02842fSSascha Wildner  * DESCRIPTION: Walk the namespace to find an object
2690d02842fSSascha Wildner  *
2700d02842fSSascha Wildner  ******************************************************************************/
2710d02842fSSascha Wildner 
2720d02842fSSascha Wildner static BOOLEAN
XfObjectExists(char * Name)2730d02842fSSascha Wildner XfObjectExists (
2740d02842fSSascha Wildner     char                    *Name)
2750d02842fSSascha Wildner {
2760d02842fSSascha Wildner     ACPI_STATUS             Status;
2770d02842fSSascha Wildner 
2780d02842fSSascha Wildner 
2790d02842fSSascha Wildner     /* Walk entire namespace from the supplied root */
2800d02842fSSascha Wildner 
2810d02842fSSascha Wildner     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
2820d02842fSSascha Wildner         ACPI_UINT32_MAX, FALSE, XfCompareOneNamespaceObject, NULL,
2830d02842fSSascha Wildner         Name, NULL);
2840d02842fSSascha Wildner     if (Status == AE_CTRL_TRUE)
2850d02842fSSascha Wildner     {
2860d02842fSSascha Wildner         /* At least one instance of the name was found */
2870d02842fSSascha Wildner 
2880d02842fSSascha Wildner         return (TRUE);
2890d02842fSSascha Wildner     }
2900d02842fSSascha Wildner 
2910d02842fSSascha Wildner     return (FALSE);
2920d02842fSSascha Wildner }
2930d02842fSSascha Wildner 
2940d02842fSSascha Wildner 
2950d02842fSSascha Wildner /*******************************************************************************
2960d02842fSSascha Wildner  *
2970d02842fSSascha Wildner  * FUNCTION:    XfCompareOneNamespaceObject
2980d02842fSSascha Wildner  *
2990d02842fSSascha Wildner  * PARAMETERS:  ACPI_WALK_CALLBACK
3000d02842fSSascha Wildner  *
3010d02842fSSascha Wildner  * RETURN:      Status
3020d02842fSSascha Wildner  *
3030d02842fSSascha Wildner  * DESCRIPTION: Compare name of one object.
3040d02842fSSascha Wildner  *
3050d02842fSSascha Wildner  ******************************************************************************/
3060d02842fSSascha Wildner 
3070d02842fSSascha Wildner static ACPI_STATUS
XfCompareOneNamespaceObject(ACPI_HANDLE ObjHandle,UINT32 Level,void * Context,void ** ReturnValue)3080d02842fSSascha Wildner XfCompareOneNamespaceObject (
3090d02842fSSascha Wildner     ACPI_HANDLE             ObjHandle,
3100d02842fSSascha Wildner     UINT32                  Level,
3110d02842fSSascha Wildner     void                    *Context,
3120d02842fSSascha Wildner     void                    **ReturnValue)
3130d02842fSSascha Wildner {
3140d02842fSSascha Wildner     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
3150d02842fSSascha Wildner 
3160d02842fSSascha Wildner 
3170d02842fSSascha Wildner     /* Simply check the name */
3180d02842fSSascha Wildner 
3190d02842fSSascha Wildner     if (*((UINT32 *) (Context)) == Node->Name.Integer)
3200d02842fSSascha Wildner     {
3210d02842fSSascha Wildner         /* Abort walk if we found one instance */
3220d02842fSSascha Wildner 
3230d02842fSSascha Wildner         return (AE_CTRL_TRUE);
3240d02842fSSascha Wildner     }
3250d02842fSSascha Wildner 
3260d02842fSSascha Wildner     return (AE_OK);
3270d02842fSSascha Wildner }
3280d02842fSSascha Wildner 
3290d02842fSSascha Wildner 
3300d02842fSSascha Wildner /*******************************************************************************
3310d02842fSSascha Wildner  *
3320d02842fSSascha Wildner  * FUNCTION:    XfCheckFieldRange
3330d02842fSSascha Wildner  *
3340d02842fSSascha Wildner  * PARAMETERS:  RegionBitLength     - Length of entire parent region
3350d02842fSSascha Wildner  *              FieldBitOffset      - Start of the field unit (within region)
3360d02842fSSascha Wildner  *              FieldBitLength      - Entire length of field unit
3370d02842fSSascha Wildner  *              AccessBitWidth      - Access width of the field unit
3380d02842fSSascha Wildner  *
3390d02842fSSascha Wildner  * RETURN:      None
3400d02842fSSascha Wildner  *
3410d02842fSSascha Wildner  * DESCRIPTION: Check one field unit to make sure it fits in the parent
3420d02842fSSascha Wildner  *              op region.
3430d02842fSSascha Wildner  *
3440d02842fSSascha Wildner  * Note: AccessBitWidth must be either 8,16,32, or 64
3450d02842fSSascha Wildner  *
3460d02842fSSascha Wildner  ******************************************************************************/
3470d02842fSSascha Wildner 
3480d02842fSSascha Wildner static void
XfCheckFieldRange(ACPI_PARSE_OBJECT * Op,UINT32 RegionBitLength,UINT32 FieldBitOffset,UINT32 FieldBitLength,UINT32 AccessBitWidth)3490d02842fSSascha Wildner XfCheckFieldRange (
3500d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
3510d02842fSSascha Wildner     UINT32                  RegionBitLength,
3520d02842fSSascha Wildner     UINT32                  FieldBitOffset,
3530d02842fSSascha Wildner     UINT32                  FieldBitLength,
3540d02842fSSascha Wildner     UINT32                  AccessBitWidth)
3550d02842fSSascha Wildner {
3560d02842fSSascha Wildner     UINT32                  FieldEndBitOffset;
3570d02842fSSascha Wildner 
3580d02842fSSascha Wildner 
3590d02842fSSascha Wildner     /*
3600d02842fSSascha Wildner      * Check each field unit against the region size. The entire
3610d02842fSSascha Wildner      * field unit (start offset plus length) must fit within the
3620d02842fSSascha Wildner      * region.
3630d02842fSSascha Wildner      */
3640d02842fSSascha Wildner     FieldEndBitOffset = FieldBitOffset + FieldBitLength;
3650d02842fSSascha Wildner 
3660d02842fSSascha Wildner     if (FieldEndBitOffset > RegionBitLength)
3670d02842fSSascha Wildner     {
3680d02842fSSascha Wildner         /* Field definition itself is beyond the end-of-region */
3690d02842fSSascha Wildner 
3700d02842fSSascha Wildner         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
3710d02842fSSascha Wildner         return;
3720d02842fSSascha Wildner     }
3730d02842fSSascha Wildner 
3740d02842fSSascha Wildner     /*
3750d02842fSSascha Wildner      * Now check that the field plus AccessWidth doesn't go beyond
3760d02842fSSascha Wildner      * the end-of-region. Assumes AccessBitWidth is a power of 2
3770d02842fSSascha Wildner      */
3780d02842fSSascha Wildner     FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
3790d02842fSSascha Wildner 
3800d02842fSSascha Wildner     if (FieldEndBitOffset > RegionBitLength)
3810d02842fSSascha Wildner     {
3820d02842fSSascha Wildner         /* Field definition combined with the access is beyond EOR */
3830d02842fSSascha Wildner 
3840d02842fSSascha Wildner         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
3850d02842fSSascha Wildner     }
3860d02842fSSascha Wildner }
3870d02842fSSascha Wildner 
38879eafdd7SSascha Wildner 
38979eafdd7SSascha Wildner /*******************************************************************************
39079eafdd7SSascha Wildner  *
3910d02842fSSascha Wildner  * FUNCTION:    XfNamespaceLocateBegin
3920d02842fSSascha Wildner  *
3930d02842fSSascha Wildner  * PARAMETERS:  ASL_WALK_CALLBACK
3940d02842fSSascha Wildner  *
3950d02842fSSascha Wildner  * RETURN:      Status
3960d02842fSSascha Wildner  *
3970d02842fSSascha Wildner  * DESCRIPTION: Descending callback used during cross-reference. For named
3980d02842fSSascha Wildner  *              object references, attempt to locate the name in the
3990d02842fSSascha Wildner  *              namespace.
4000d02842fSSascha Wildner  *
4010d02842fSSascha Wildner  * NOTE: ASL references to named fields within resource descriptors are
4020d02842fSSascha Wildner  *       resolved to integer values here. Therefore, this step is an
4030d02842fSSascha Wildner  *       important part of the code generation. We don't know that the
4040d02842fSSascha Wildner  *       name refers to a resource descriptor until now.
4050d02842fSSascha Wildner  *
4060d02842fSSascha Wildner  ******************************************************************************/
4070d02842fSSascha Wildner 
4080d02842fSSascha Wildner static ACPI_STATUS
XfNamespaceLocateBegin(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)4090d02842fSSascha Wildner XfNamespaceLocateBegin (
4100d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
4110d02842fSSascha Wildner     UINT32                  Level,
4120d02842fSSascha Wildner     void                    *Context)
4130d02842fSSascha Wildner {
4140d02842fSSascha Wildner     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
4150d02842fSSascha Wildner     ACPI_NAMESPACE_NODE     *Node;
4160d02842fSSascha Wildner     ACPI_STATUS             Status;
4170d02842fSSascha Wildner     ACPI_OBJECT_TYPE        ObjectType;
4180d02842fSSascha Wildner     char                    *Path;
4190d02842fSSascha Wildner     UINT8                   PassedArgs;
4200d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *NextOp;
4210d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *OwningOp;
4220d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *SpaceIdOp;
4230d02842fSSascha Wildner     UINT32                  MinimumLength;
4240d02842fSSascha Wildner     UINT32                  Offset;
4250d02842fSSascha Wildner     UINT32                  FieldBitLength;
4260d02842fSSascha Wildner     UINT32                  TagBitLength;
4270d02842fSSascha Wildner     UINT8                   Message = 0;
4280d02842fSSascha Wildner     const ACPI_OPCODE_INFO  *OpInfo;
4290d02842fSSascha Wildner     UINT32                  Flags;
430267c04fdSSascha Wildner     ASL_METHOD_LOCAL        *MethodLocals = NULL;
431267c04fdSSascha Wildner     ASL_METHOD_LOCAL        *MethodArgs = NULL;
432267c04fdSSascha Wildner     int                     RegisterNumber;
433267c04fdSSascha Wildner     UINT32                  i;
434835079a2SSascha Wildner     ACPI_NAMESPACE_NODE     *DeclarationParentMethod;
435835079a2SSascha Wildner     ACPI_PARSE_OBJECT       *ReferenceParentMethod;
436c5a52fd3SSascha Wildner     char                    *ExternalPath;
4370d02842fSSascha Wildner 
4380d02842fSSascha Wildner 
4390d02842fSSascha Wildner     ACPI_FUNCTION_TRACE_PTR (XfNamespaceLocateBegin, Op);
4400d02842fSSascha Wildner 
441267c04fdSSascha Wildner 
442267c04fdSSascha Wildner     if ((Op->Asl.AmlOpcode == AML_METHOD_OP) && Op->Asl.Node)
443267c04fdSSascha Wildner     {
444267c04fdSSascha Wildner         Node = Op->Asl.Node;
445267c04fdSSascha Wildner 
446267c04fdSSascha Wildner         /* Support for method LocalX/ArgX analysis */
447267c04fdSSascha Wildner 
448267c04fdSSascha Wildner         if (!Node->MethodLocals)
449267c04fdSSascha Wildner         {
450267c04fdSSascha Wildner             /* Create local/arg info blocks */
451267c04fdSSascha Wildner 
452267c04fdSSascha Wildner             MethodLocals = UtLocalCalloc (
453267c04fdSSascha Wildner                 sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_LOCALS);
454267c04fdSSascha Wildner             Node->MethodLocals = MethodLocals;
455267c04fdSSascha Wildner 
456267c04fdSSascha Wildner             MethodArgs = UtLocalCalloc (
457267c04fdSSascha Wildner                 sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_ARGS);
458267c04fdSSascha Wildner             Node->MethodArgs = MethodArgs;
459267c04fdSSascha Wildner 
460267c04fdSSascha Wildner             /*
461267c04fdSSascha Wildner              * Get the method argument count
462267c04fdSSascha Wildner              * First, get the name node
463267c04fdSSascha Wildner              */
464267c04fdSSascha Wildner             NextOp = Op->Asl.Child;
465267c04fdSSascha Wildner 
466267c04fdSSascha Wildner             /* Get the NumArguments node */
467267c04fdSSascha Wildner 
468267c04fdSSascha Wildner             NextOp = NextOp->Asl.Next;
469267c04fdSSascha Wildner             Node->ArgCount = (UINT8)
470267c04fdSSascha Wildner                 (((UINT8) NextOp->Asl.Value.Integer) & 0x07);
471267c04fdSSascha Wildner 
47200ffa116SSascha Wildner             /* We will track all possible ArgXs */
473267c04fdSSascha Wildner 
474267c04fdSSascha Wildner             for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
475267c04fdSSascha Wildner             {
476267c04fdSSascha Wildner                 if (i < Node->ArgCount)
477267c04fdSSascha Wildner                 {
478267c04fdSSascha Wildner                     /* Real Args are always "initialized" */
479267c04fdSSascha Wildner 
480267c04fdSSascha Wildner                     MethodArgs[i].Flags = ASL_ARG_INITIALIZED;
481267c04fdSSascha Wildner                 }
482267c04fdSSascha Wildner                 else
483267c04fdSSascha Wildner                 {
484267c04fdSSascha Wildner                     /* Other ArgXs can be used as locals */
485267c04fdSSascha Wildner 
486267c04fdSSascha Wildner                     MethodArgs[i].Flags = ASL_ARG_IS_LOCAL;
487267c04fdSSascha Wildner                 }
488267c04fdSSascha Wildner 
489267c04fdSSascha Wildner                 MethodArgs[i].Op = Op;
490267c04fdSSascha Wildner             }
491267c04fdSSascha Wildner         }
492267c04fdSSascha Wildner     }
493267c04fdSSascha Wildner 
4940d02842fSSascha Wildner     /*
4950d02842fSSascha Wildner      * If this node is the actual declaration of a name
4960d02842fSSascha Wildner      * [such as the XXXX name in "Method (XXXX)"],
4970d02842fSSascha Wildner      * we are not interested in it here. We only care about names that are
4980d02842fSSascha Wildner      * references to other objects within the namespace and the parent objects
4990d02842fSSascha Wildner      * of name declarations
5000d02842fSSascha Wildner      */
5011093ca81SSascha Wildner     if (Op->Asl.CompileFlags & OP_IS_NAME_DECLARATION)
5020d02842fSSascha Wildner     {
5030d02842fSSascha Wildner         return_ACPI_STATUS (AE_OK);
5040d02842fSSascha Wildner     }
5050d02842fSSascha Wildner 
5060d02842fSSascha Wildner     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
5070d02842fSSascha Wildner 
508267c04fdSSascha Wildner     /* Check method LocalX variables */
509267c04fdSSascha Wildner 
510267c04fdSSascha Wildner     if (OpInfo->Type == AML_TYPE_LOCAL_VARIABLE)
511267c04fdSSascha Wildner     {
512267c04fdSSascha Wildner         /* Find parent method Op */
513267c04fdSSascha Wildner 
514ff3cb46dSSascha Wildner         NextOp = UtGetParentMethodOp (Op);
515267c04fdSSascha Wildner         if (!NextOp)
516267c04fdSSascha Wildner         {
517267c04fdSSascha Wildner             return_ACPI_STATUS (AE_OK);
518267c04fdSSascha Wildner         }
519267c04fdSSascha Wildner 
520267c04fdSSascha Wildner         /* Get method node */
521267c04fdSSascha Wildner 
522267c04fdSSascha Wildner         Node = NextOp->Asl.Node;
523267c04fdSSascha Wildner 
524267c04fdSSascha Wildner         RegisterNumber = Op->Asl.AmlOpcode & 0x0007; /* 0x60 through 0x67 */
525267c04fdSSascha Wildner         MethodLocals = Node->MethodLocals;
526267c04fdSSascha Wildner 
5271093ca81SSascha Wildner         if (Op->Asl.CompileFlags & OP_IS_TARGET)
528267c04fdSSascha Wildner         {
529267c04fdSSascha Wildner             /* Local is being initialized */
530267c04fdSSascha Wildner 
531267c04fdSSascha Wildner             MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_INITIALIZED;
532267c04fdSSascha Wildner             MethodLocals[RegisterNumber].Op = Op;
533267c04fdSSascha Wildner 
534267c04fdSSascha Wildner             return_ACPI_STATUS (AE_OK);
535267c04fdSSascha Wildner         }
536267c04fdSSascha Wildner 
537267c04fdSSascha Wildner         /* Mark this Local as referenced */
538267c04fdSSascha Wildner 
539267c04fdSSascha Wildner         MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_REFERENCED;
540267c04fdSSascha Wildner         MethodLocals[RegisterNumber].Op = Op;
541267c04fdSSascha Wildner 
542267c04fdSSascha Wildner         return_ACPI_STATUS (AE_OK);
543267c04fdSSascha Wildner     }
544267c04fdSSascha Wildner 
545267c04fdSSascha Wildner     /* Check method ArgX variables */
546267c04fdSSascha Wildner 
547267c04fdSSascha Wildner     if (OpInfo->Type == AML_TYPE_METHOD_ARGUMENT)
548267c04fdSSascha Wildner     {
549267c04fdSSascha Wildner         /* Find parent method Op */
550267c04fdSSascha Wildner 
551ff3cb46dSSascha Wildner         NextOp = UtGetParentMethodOp (Op);
552267c04fdSSascha Wildner         if (!NextOp)
553267c04fdSSascha Wildner         {
554267c04fdSSascha Wildner             return_ACPI_STATUS (AE_OK);
555267c04fdSSascha Wildner         }
556267c04fdSSascha Wildner 
557267c04fdSSascha Wildner         /* Get method node */
558267c04fdSSascha Wildner 
559267c04fdSSascha Wildner         Node = NextOp->Asl.Node;
560267c04fdSSascha Wildner 
561267c04fdSSascha Wildner         /* Get Arg # */
562267c04fdSSascha Wildner 
563267c04fdSSascha Wildner         RegisterNumber = Op->Asl.AmlOpcode - AML_ARG0; /* 0x68 through 0x6F */
564267c04fdSSascha Wildner         MethodArgs = Node->MethodArgs;
565267c04fdSSascha Wildner 
566c5f0c4c2SSascha Wildner         /* Mark this Arg as referenced */
567c5f0c4c2SSascha Wildner 
568c5f0c4c2SSascha Wildner         MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED;
569c5f0c4c2SSascha Wildner         MethodArgs[RegisterNumber].Op = Op;
570c5f0c4c2SSascha Wildner 
5711093ca81SSascha Wildner         if (Op->Asl.CompileFlags & OP_IS_TARGET)
572267c04fdSSascha Wildner         {
573267c04fdSSascha Wildner             /* Arg is being initialized */
574267c04fdSSascha Wildner 
575267c04fdSSascha Wildner             MethodArgs[RegisterNumber].Flags |= ASL_ARG_INITIALIZED;
576267c04fdSSascha Wildner         }
577267c04fdSSascha Wildner 
578267c04fdSSascha Wildner         return_ACPI_STATUS (AE_OK);
579267c04fdSSascha Wildner     }
580267c04fdSSascha Wildner 
581267c04fdSSascha Wildner     /*
582267c04fdSSascha Wildner      * After method ArgX and LocalX, we are only interested in opcodes
583267c04fdSSascha Wildner      * that have an associated name
584267c04fdSSascha Wildner      */
5850d02842fSSascha Wildner     if ((!(OpInfo->Flags & AML_NAMED)) &&
5860d02842fSSascha Wildner         (!(OpInfo->Flags & AML_CREATE)) &&
5870d02842fSSascha Wildner         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
5880d02842fSSascha Wildner         (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
5891093ca81SSascha Wildner         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL) &&
590835079a2SSascha Wildner         (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
5910d02842fSSascha Wildner     {
5920d02842fSSascha Wildner         return_ACPI_STATUS (AE_OK);
5930d02842fSSascha Wildner     }
5940d02842fSSascha Wildner 
5950d02842fSSascha Wildner     /*
5960d02842fSSascha Wildner      * We must enable the "search-to-root" for single NameSegs, but
5970d02842fSSascha Wildner      * we have to be very careful about opening up scopes
5980d02842fSSascha Wildner      */
5990d02842fSSascha Wildner     Flags = ACPI_NS_SEARCH_PARENT;
6000d02842fSSascha Wildner     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
6010d02842fSSascha Wildner         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
6021093ca81SSascha Wildner         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
6030f79e681SSascha Wildner         (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)   ||
6040f79e681SSascha Wildner         (Op->Asl.ParseOpcode == PARSEOP_CONDREFOF))
6050d02842fSSascha Wildner     {
6060d02842fSSascha Wildner         /*
6070d02842fSSascha Wildner          * These are name references, do not push the scope stack
6080d02842fSSascha Wildner          * for them.
6090d02842fSSascha Wildner          */
6100d02842fSSascha Wildner         Flags |= ACPI_NS_DONT_OPEN_SCOPE;
6110d02842fSSascha Wildner     }
6120d02842fSSascha Wildner 
6130d02842fSSascha Wildner     /* Get the NamePath from the appropriate place */
6140d02842fSSascha Wildner 
6150d02842fSSascha Wildner     if (OpInfo->Flags & AML_NAMED)
6160d02842fSSascha Wildner     {
6170d02842fSSascha Wildner         /* For nearly all NAMED operators, the name reference is the first child */
6180d02842fSSascha Wildner 
6190d02842fSSascha Wildner         Path = Op->Asl.Child->Asl.Value.String;
6200d02842fSSascha Wildner         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
6210d02842fSSascha Wildner         {
6220d02842fSSascha Wildner             /*
6230d02842fSSascha Wildner              * ALIAS is the only oddball opcode, the name declaration
6240d02842fSSascha Wildner              * (alias name) is the second operand
6250d02842fSSascha Wildner              */
6260d02842fSSascha Wildner             Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
6270d02842fSSascha Wildner         }
6280d02842fSSascha Wildner     }
6290d02842fSSascha Wildner     else if (OpInfo->Flags & AML_CREATE)
6300d02842fSSascha Wildner     {
6310d02842fSSascha Wildner         /* Name must appear as the last parameter */
6320d02842fSSascha Wildner 
6330d02842fSSascha Wildner         NextOp = Op->Asl.Child;
6341093ca81SSascha Wildner         while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION))
6350d02842fSSascha Wildner         {
6360d02842fSSascha Wildner             NextOp = NextOp->Asl.Next;
6370d02842fSSascha Wildner         }
638820c5b08SSascha Wildner 
6390d02842fSSascha Wildner         Path = NextOp->Asl.Value.String;
6400d02842fSSascha Wildner     }
6410d02842fSSascha Wildner     else
6420d02842fSSascha Wildner     {
6430d02842fSSascha Wildner         Path = Op->Asl.Value.String;
6440d02842fSSascha Wildner     }
6450d02842fSSascha Wildner 
6460d02842fSSascha Wildner     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
6470d02842fSSascha Wildner     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
6480d02842fSSascha Wildner         "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
6490d02842fSSascha Wildner 
6500d02842fSSascha Wildner     /*
6510d02842fSSascha Wildner      * Lookup the name in the namespace. Name must exist at this point, or it
6520d02842fSSascha Wildner      * is an invalid reference.
6530d02842fSSascha Wildner      *
6540d02842fSSascha Wildner      * The namespace is also used as a lookup table for references to resource
6550d02842fSSascha Wildner      * descriptors and the fields within them.
6560d02842fSSascha Wildner      */
657806343b9SSascha Wildner     AslGbl_NsLookupCount++;
6580d02842fSSascha Wildner 
6590d02842fSSascha Wildner     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
6607bcb6cafSSascha Wildner         ACPI_IMODE_EXECUTE, Flags, WalkState, &Node);
6610d02842fSSascha Wildner     if (ACPI_FAILURE (Status))
6620d02842fSSascha Wildner     {
6630d02842fSSascha Wildner         if (Status == AE_NOT_FOUND)
6640d02842fSSascha Wildner         {
6650d02842fSSascha Wildner             /*
6660d02842fSSascha Wildner              * We didn't find the name reference by path -- we can qualify this
6670d02842fSSascha Wildner              * a little better before we print an error message
6680d02842fSSascha Wildner              */
6690f79e681SSascha Wildner 
6700f79e681SSascha Wildner             if ((Op->Asl.Parent) &&
6710f79e681SSascha Wildner                 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
6720f79e681SSascha Wildner             {
6730f79e681SSascha Wildner                 /*
6740f79e681SSascha Wildner                  * One special case: CondRefOf operator - if the name doesn't
6750f79e681SSascha Wildner                  * exist at this point, it means that there's no actual or
6760f79e681SSascha Wildner                  * external declaration. If the name is not found, just ignore
6770f79e681SSascha Wildner                  * it, the point of the operator is to determine if the name
6780f79e681SSascha Wildner                  * exists at runtime. We wanted to see if this named object
6790f79e681SSascha Wildner                  * exists to facilitate analysis to allow protected usage of
6800f79e681SSascha Wildner                  * undeclared externals.
6810f79e681SSascha Wildner                  */
6820f79e681SSascha Wildner                 return_ACPI_STATUS (AE_OK);
6830f79e681SSascha Wildner             }
6840f79e681SSascha Wildner             else if (strlen (Path) == ACPI_NAMESEG_SIZE)
6850d02842fSSascha Wildner             {
6860d02842fSSascha Wildner                 /* A simple, one-segment ACPI name */
6870d02842fSSascha Wildner 
6880d02842fSSascha Wildner                 if (XfObjectExists (Path))
6890d02842fSSascha Wildner                 {
6900d02842fSSascha Wildner                     /*
6910d02842fSSascha Wildner                      * There exists such a name, but we couldn't get to it
6920d02842fSSascha Wildner                      * from this scope
6930d02842fSSascha Wildner                      */
6940d02842fSSascha Wildner                     AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
6950d02842fSSascha Wildner                         Op->Asl.ExternalName);
6960d02842fSSascha Wildner                 }
6970d02842fSSascha Wildner                 else
6980d02842fSSascha Wildner                 {
6990d02842fSSascha Wildner                     /* The name doesn't exist, period */
7000d02842fSSascha Wildner 
7010d02842fSSascha Wildner                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
7020d02842fSSascha Wildner                         Op, Op->Asl.ExternalName);
7030d02842fSSascha Wildner                 }
7040d02842fSSascha Wildner             }
7050d02842fSSascha Wildner             else
7060d02842fSSascha Wildner             {
7076721db86SSascha Wildner                 /* The NamePath contains multiple NameSegs */
7080d02842fSSascha Wildner 
7096721db86SSascha Wildner                 if ((OpInfo->Flags & AML_CREATE) ||
7106721db86SSascha Wildner                     (OpInfo->ObjectType == ACPI_TYPE_LOCAL_ALIAS))
7110d02842fSSascha Wildner                 {
7126721db86SSascha Wildner                     /*
7136721db86SSascha Wildner                      * The new name is the last parameter. For the
7146721db86SSascha Wildner                      * CreateXXXXField and Alias operators
7156721db86SSascha Wildner                      */
7166721db86SSascha Wildner                     NextOp = Op->Asl.Child;
7176721db86SSascha Wildner                     while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION))
7186721db86SSascha Wildner                     {
7196721db86SSascha Wildner                         NextOp = NextOp->Asl.Next;
7206721db86SSascha Wildner                     }
7216721db86SSascha Wildner 
7226721db86SSascha Wildner                     AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, NextOp,
7236721db86SSascha Wildner                         NextOp->Asl.ExternalName);
7246721db86SSascha Wildner                 }
7256721db86SSascha Wildner                 else if (OpInfo->Flags & AML_NAMED)
7266721db86SSascha Wildner                 {
7276721db86SSascha Wildner                     /* The new name is the first parameter */
7286721db86SSascha Wildner 
7296721db86SSascha Wildner                     AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, Op,
7306721db86SSascha Wildner                         Op->Asl.ExternalName);
7316721db86SSascha Wildner                 }
7326721db86SSascha Wildner                 else if (Path[0] == AML_ROOT_PREFIX)
7336721db86SSascha Wildner                 {
7346721db86SSascha Wildner                     /* Full namepath from root, the object does not exist */
7350d02842fSSascha Wildner 
7360d02842fSSascha Wildner                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
7370d02842fSSascha Wildner                         Op->Asl.ExternalName);
7380d02842fSSascha Wildner                 }
7390d02842fSSascha Wildner                 else
7400d02842fSSascha Wildner                 {
7410d02842fSSascha Wildner                     /*
7426721db86SSascha Wildner                      * Generic "not found" error. Cannot determine whether it
7436721db86SSascha Wildner                      * doesn't exist or just can't be reached. However, we
7446721db86SSascha Wildner                      * can differentiate between a NameSeg vs. NamePath.
7450d02842fSSascha Wildner                      */
746c1776041SSascha Wildner                     if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
7476721db86SSascha Wildner                     {
7480d02842fSSascha Wildner                         AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
7490d02842fSSascha Wildner                             Op->Asl.ExternalName);
7500d02842fSSascha Wildner                     }
7516721db86SSascha Wildner                     else
7526721db86SSascha Wildner                     {
7536721db86SSascha Wildner                         AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
7546721db86SSascha Wildner                             Op->Asl.ExternalName);
7556721db86SSascha Wildner                     }
7566721db86SSascha Wildner                 }
7570d02842fSSascha Wildner             }
7580d02842fSSascha Wildner 
7590d02842fSSascha Wildner             Status = AE_OK;
7600d02842fSSascha Wildner         }
7610d02842fSSascha Wildner 
7620d02842fSSascha Wildner         return_ACPI_STATUS (Status);
7630d02842fSSascha Wildner     }
7640d02842fSSascha Wildner 
76500ffa116SSascha Wildner     /* Check for an attempt to access an object in another method */
76600ffa116SSascha Wildner 
76700ffa116SSascha Wildner     if (!XfValidateCrossReference (Op, OpInfo, Node))
76800ffa116SSascha Wildner     {
76900ffa116SSascha Wildner         AslError (ASL_ERROR, ASL_MSG_TEMPORARY_OBJECT, Op,
77000ffa116SSascha Wildner             Op->Asl.ExternalName);
77100ffa116SSascha Wildner         return_ACPI_STATUS (Status);
77200ffa116SSascha Wildner     }
77300ffa116SSascha Wildner 
7747bcb6cafSSascha Wildner    /* Object was found above, check for an illegal forward reference */
7757bcb6cafSSascha Wildner 
7767bcb6cafSSascha Wildner     if (Op->Asl.CompileFlags & OP_NOT_FOUND_DURING_LOAD)
7777bcb6cafSSascha Wildner     {
7787bcb6cafSSascha Wildner         /*
7797bcb6cafSSascha Wildner          * During the load phase, this Op was flagged as a possible
780835079a2SSascha Wildner          * illegal forward reference. In other words, Op is a name path or
781835079a2SSascha Wildner          * name segment that refers to a named object declared after the
782835079a2SSascha Wildner          * reference. In this scinario, Node refers to the actual declaration
783835079a2SSascha Wildner          * and Op is a parse node that references the named object.
7847bcb6cafSSascha Wildner          *
785835079a2SSascha Wildner          * Note:
786835079a2SSascha Wildner          *
787835079a2SSascha Wildner          * Object references inside of control methods are allowed to
788835079a2SSascha Wildner          * refer to objects declared outside of control methods.
789835079a2SSascha Wildner          *
790835079a2SSascha Wildner          * If the declaration and reference are both contained inside of the
791835079a2SSascha Wildner          * same method or outside of any method, this is a forward reference
792835079a2SSascha Wildner          * and should be reported as a compiler error.
7937bcb6cafSSascha Wildner          */
794ff3cb46dSSascha Wildner         DeclarationParentMethod = UtGetParentMethodNode (Node);
795ff3cb46dSSascha Wildner         ReferenceParentMethod = UtGetParentMethodOp (Op);
796835079a2SSascha Wildner 
797ff3cb46dSSascha Wildner         /* case 1: declaration and reference are both outside of method */
798835079a2SSascha Wildner 
799835079a2SSascha Wildner         if (!ReferenceParentMethod && !DeclarationParentMethod)
800835079a2SSascha Wildner         {
801835079a2SSascha Wildner             AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
802835079a2SSascha Wildner                 Op->Asl.ExternalName);
803835079a2SSascha Wildner         }
804835079a2SSascha Wildner 
805835079a2SSascha Wildner         /* case 2: declaration and reference are both inside of the same method */
806835079a2SSascha Wildner 
807835079a2SSascha Wildner         else if (ReferenceParentMethod && DeclarationParentMethod &&
808835079a2SSascha Wildner             ReferenceParentMethod == DeclarationParentMethod->Op)
8097bcb6cafSSascha Wildner         {
8107bcb6cafSSascha Wildner              AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
8117bcb6cafSSascha Wildner                 Op->Asl.ExternalName);
8127bcb6cafSSascha Wildner         }
8137bcb6cafSSascha Wildner     }
8147bcb6cafSSascha Wildner 
8150d02842fSSascha Wildner     /* Check for a reference vs. name declaration */
8160d02842fSSascha Wildner 
8170d02842fSSascha Wildner     if (!(OpInfo->Flags & AML_NAMED) &&
8180d02842fSSascha Wildner         !(OpInfo->Flags & AML_CREATE))
8190d02842fSSascha Wildner     {
8200d02842fSSascha Wildner         /* This node has been referenced, mark it for reference check */
8210d02842fSSascha Wildner 
8220d02842fSSascha Wildner         Node->Flags |= ANOBJ_IS_REFERENCED;
8230d02842fSSascha Wildner     }
8240d02842fSSascha Wildner 
825d0dff17aSSascha Wildner     /*
826d0dff17aSSascha Wildner      * Attempt to optimize the NamePath
827d0dff17aSSascha Wildner      *
828d0dff17aSSascha Wildner      * One special case: CondRefOf operator - not all AML interpreter
829d0dff17aSSascha Wildner      * implementations expect optimized namepaths as a parameter to this
830d0dff17aSSascha Wildner      * operator. They require relative name paths with prefix operators or
831d0dff17aSSascha Wildner      * namepaths starting with the root scope.
832d0dff17aSSascha Wildner      *
833d0dff17aSSascha Wildner      * Other AML interpreter implementations do not perform the namespace
834d0dff17aSSascha Wildner      * search that starts at the current scope and recursively searching the
835d0dff17aSSascha Wildner      * parent scope until the root scope. The lack of search is only known to
836d0dff17aSSascha Wildner      * occur for the namestring parameter for the CondRefOf operator.
837d0dff17aSSascha Wildner      */
838d0dff17aSSascha Wildner     if ((Op->Asl.Parent) &&
839d0dff17aSSascha Wildner         (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_CONDREFOF))
840d0dff17aSSascha Wildner     {
8410d02842fSSascha Wildner         OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
842d0dff17aSSascha Wildner     }
8430d02842fSSascha Wildner 
8440d02842fSSascha Wildner     /*
8450d02842fSSascha Wildner      * 1) Dereference an alias (A name reference that is an alias)
8460d02842fSSascha Wildner      *    Aliases are not nested, the alias always points to the final object
8470d02842fSSascha Wildner      */
8480d02842fSSascha Wildner     if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
8490d02842fSSascha Wildner         (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
8500d02842fSSascha Wildner     {
8510d02842fSSascha Wildner         /* This node points back to the original PARSEOP_ALIAS */
8520d02842fSSascha Wildner 
8530d02842fSSascha Wildner         NextOp = Node->Op;
8540d02842fSSascha Wildner 
8550d02842fSSascha Wildner         /* The first child is the alias target op */
8560d02842fSSascha Wildner 
8570d02842fSSascha Wildner         NextOp = NextOp->Asl.Child;
8580d02842fSSascha Wildner 
8590d02842fSSascha Wildner         /* That in turn points back to original target alias node */
8600d02842fSSascha Wildner 
8610d02842fSSascha Wildner         if (NextOp->Asl.Node)
8620d02842fSSascha Wildner         {
8630d02842fSSascha Wildner             Node = NextOp->Asl.Node;
8640d02842fSSascha Wildner         }
8650d02842fSSascha Wildner 
8660d02842fSSascha Wildner         /* Else - forward reference to alias, will be resolved later */
8670d02842fSSascha Wildner     }
8680d02842fSSascha Wildner 
8690d02842fSSascha Wildner     /* 2) Check for a reference to a resource descriptor */
8700d02842fSSascha Wildner 
8710d02842fSSascha Wildner     if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
8720d02842fSSascha Wildner         (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
8730d02842fSSascha Wildner     {
8740d02842fSSascha Wildner         /*
8750d02842fSSascha Wildner          * This was a reference to a field within a resource descriptor.
8760d02842fSSascha Wildner          * Extract the associated field offset (either a bit or byte
8770d02842fSSascha Wildner          * offset depending on the field type) and change the named
8780d02842fSSascha Wildner          * reference into an integer for AML code generation
8790d02842fSSascha Wildner          */
8800d02842fSSascha Wildner         Offset = Node->Value;
8810d02842fSSascha Wildner         TagBitLength = Node->Length;
8820d02842fSSascha Wildner 
8830d02842fSSascha Wildner         /*
8840d02842fSSascha Wildner          * If a field is being created, generate the length (in bits) of
8850d02842fSSascha Wildner          * the field. Note: Opcodes other than CreateXxxField and Index
8860d02842fSSascha Wildner          * can come through here. For other opcodes, we just need to
8870d02842fSSascha Wildner          * convert the resource tag reference to an integer offset.
8880d02842fSSascha Wildner          */
8890d02842fSSascha Wildner         switch (Op->Asl.Parent->Asl.AmlOpcode)
8900d02842fSSascha Wildner         {
8910d02842fSSascha Wildner         case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */
8920d02842fSSascha Wildner             /*
8930d02842fSSascha Wildner              * We know the length operand is an integer constant because
8940d02842fSSascha Wildner              * we know that it contains a reference to a resource
8950d02842fSSascha Wildner              * descriptor tag.
8960d02842fSSascha Wildner              */
8970d02842fSSascha Wildner             FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer;
8980d02842fSSascha Wildner             break;
8990d02842fSSascha Wildner 
9000d02842fSSascha Wildner         case AML_CREATE_BIT_FIELD_OP:
9010d02842fSSascha Wildner 
9020d02842fSSascha Wildner             FieldBitLength = 1;
9030d02842fSSascha Wildner             break;
9040d02842fSSascha Wildner 
9050d02842fSSascha Wildner         case AML_CREATE_BYTE_FIELD_OP:
9060d02842fSSascha Wildner         case AML_INDEX_OP:
9070d02842fSSascha Wildner 
9080d02842fSSascha Wildner             FieldBitLength = 8;
9090d02842fSSascha Wildner             break;
9100d02842fSSascha Wildner 
9110d02842fSSascha Wildner         case AML_CREATE_WORD_FIELD_OP:
9120d02842fSSascha Wildner 
9130d02842fSSascha Wildner             FieldBitLength = 16;
9140d02842fSSascha Wildner             break;
9150d02842fSSascha Wildner 
9160d02842fSSascha Wildner         case AML_CREATE_DWORD_FIELD_OP:
9170d02842fSSascha Wildner 
9180d02842fSSascha Wildner             FieldBitLength = 32;
9190d02842fSSascha Wildner             break;
9200d02842fSSascha Wildner 
9210d02842fSSascha Wildner         case AML_CREATE_QWORD_FIELD_OP:
9220d02842fSSascha Wildner 
9230d02842fSSascha Wildner             FieldBitLength = 64;
9240d02842fSSascha Wildner             break;
9250d02842fSSascha Wildner 
9260d02842fSSascha Wildner         default:
9270d02842fSSascha Wildner 
9280d02842fSSascha Wildner             FieldBitLength = 0;
9290d02842fSSascha Wildner             break;
9300d02842fSSascha Wildner         }
9310d02842fSSascha Wildner 
9320d02842fSSascha Wildner         /* Check the field length against the length of the resource tag */
9330d02842fSSascha Wildner 
9340d02842fSSascha Wildner         if (FieldBitLength)
9350d02842fSSascha Wildner         {
9360d02842fSSascha Wildner             if (TagBitLength < FieldBitLength)
9370d02842fSSascha Wildner             {
9380d02842fSSascha Wildner                 Message = ASL_MSG_TAG_SMALLER;
9390d02842fSSascha Wildner             }
9400d02842fSSascha Wildner             else if (TagBitLength > FieldBitLength)
9410d02842fSSascha Wildner             {
9420d02842fSSascha Wildner                 Message = ASL_MSG_TAG_LARGER;
9430d02842fSSascha Wildner             }
9440d02842fSSascha Wildner 
9450d02842fSSascha Wildner             if (Message)
9460d02842fSSascha Wildner             {
947806343b9SSascha Wildner                 sprintf (AslGbl_MsgBuffer,
948820c5b08SSascha Wildner                     "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
9490d02842fSSascha Wildner                     TagBitLength, (TagBitLength > 1) ? "s" : "",
9500d02842fSSascha Wildner                     FieldBitLength, (FieldBitLength > 1) ? "s" : "");
9510d02842fSSascha Wildner 
952806343b9SSascha Wildner                 AslError (ASL_WARNING, Message, Op, AslGbl_MsgBuffer);
9530d02842fSSascha Wildner             }
9540d02842fSSascha Wildner         }
9550d02842fSSascha Wildner 
9560d02842fSSascha Wildner         /* Convert the BitOffset to a ByteOffset for certain opcodes */
9570d02842fSSascha Wildner 
9580d02842fSSascha Wildner         switch (Op->Asl.Parent->Asl.AmlOpcode)
9590d02842fSSascha Wildner         {
9600d02842fSSascha Wildner         case AML_CREATE_BYTE_FIELD_OP:
9610d02842fSSascha Wildner         case AML_CREATE_WORD_FIELD_OP:
9620d02842fSSascha Wildner         case AML_CREATE_DWORD_FIELD_OP:
9630d02842fSSascha Wildner         case AML_CREATE_QWORD_FIELD_OP:
9640d02842fSSascha Wildner         case AML_INDEX_OP:
9650d02842fSSascha Wildner 
9660d02842fSSascha Wildner             Offset = ACPI_DIV_8 (Offset);
9670d02842fSSascha Wildner             break;
9680d02842fSSascha Wildner 
9690d02842fSSascha Wildner         default:
9700d02842fSSascha Wildner 
9710d02842fSSascha Wildner             break;
9720d02842fSSascha Wildner         }
9730d02842fSSascha Wildner 
9740d02842fSSascha Wildner         /* Now convert this node to an integer whose value is the field offset */
9750d02842fSSascha Wildner 
9760d02842fSSascha Wildner         Op->Asl.AmlLength = 0;
9770d02842fSSascha Wildner         Op->Asl.ParseOpcode = PARSEOP_INTEGER;
9780d02842fSSascha Wildner         Op->Asl.Value.Integer = (UINT64) Offset;
9791093ca81SSascha Wildner         Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD;
9800d02842fSSascha Wildner 
9810d02842fSSascha Wildner         OpcGenerateAmlOpcode (Op);
9820d02842fSSascha Wildner     }
9830d02842fSSascha Wildner 
9840d02842fSSascha Wildner     /* 3) Check for a method invocation */
9850d02842fSSascha Wildner 
9860d02842fSSascha Wildner     else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
9870d02842fSSascha Wildner                 (Node->Type == ACPI_TYPE_METHOD) &&
9880d02842fSSascha Wildner                 (Op->Asl.Parent) &&
9890d02842fSSascha Wildner                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
9900d02842fSSascha Wildner 
9910d02842fSSascha Wildner                 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
9920d02842fSSascha Wildner     {
9930d02842fSSascha Wildner         /*
9940d02842fSSascha Wildner          * A reference to a method within one of these opcodes is not an
9950d02842fSSascha Wildner          * invocation of the method, it is simply a reference to the method.
99696f24602SSascha Wildner          *
99796f24602SSascha Wildner          * September 2016: Removed DeRefOf from this list
9984758d649SSascha Wildner          * July 2020: Added Alias to this list
9990d02842fSSascha Wildner          */
10000d02842fSSascha Wildner         if ((Op->Asl.Parent) &&
10010d02842fSSascha Wildner             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)     ||
10022e2672b8SSascha Wildner             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_PACKAGE)    ||
10032e2672b8SSascha Wildner             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)||
10044758d649SSascha Wildner             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE) ||
10054758d649SSascha Wildner             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_ALIAS)))
10060d02842fSSascha Wildner         {
10070d02842fSSascha Wildner             return_ACPI_STATUS (AE_OK);
10080d02842fSSascha Wildner         }
100996f24602SSascha Wildner 
10100d02842fSSascha Wildner         /*
10110d02842fSSascha Wildner          * There are two types of method invocation:
10120d02842fSSascha Wildner          * 1) Invocation with arguments -- the parser recognizes this
10130d02842fSSascha Wildner          *    as a METHODCALL.
10140d02842fSSascha Wildner          * 2) Invocation with no arguments --the parser cannot determine that
10150d02842fSSascha Wildner          *    this is a method invocation, therefore we have to figure it out
10160d02842fSSascha Wildner          *    here.
10170d02842fSSascha Wildner          */
10180d02842fSSascha Wildner         if (Node->Type != ACPI_TYPE_METHOD)
10190d02842fSSascha Wildner         {
1020806343b9SSascha Wildner             sprintf (AslGbl_MsgBuffer, "%s is a %s",
10210d02842fSSascha Wildner                 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
10220d02842fSSascha Wildner 
1023806343b9SSascha Wildner             AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, AslGbl_MsgBuffer);
10240d02842fSSascha Wildner             return_ACPI_STATUS (AE_OK);
10250d02842fSSascha Wildner         }
10260d02842fSSascha Wildner 
10270d02842fSSascha Wildner         /* Save the method node in the caller's op */
10280d02842fSSascha Wildner 
10290d02842fSSascha Wildner         Op->Asl.Node = Node;
10300d02842fSSascha Wildner         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
10310d02842fSSascha Wildner         {
10320d02842fSSascha Wildner             return_ACPI_STATUS (AE_OK);
10330d02842fSSascha Wildner         }
10340d02842fSSascha Wildner 
10350d02842fSSascha Wildner         /*
10360d02842fSSascha Wildner          * This is a method invocation, with or without arguments.
10370d02842fSSascha Wildner          * Count the number of arguments, each appears as a child
10380d02842fSSascha Wildner          * under the parent node
10390d02842fSSascha Wildner          */
10400d02842fSSascha Wildner         Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
10410d02842fSSascha Wildner         UtSetParseOpName (Op);
10420d02842fSSascha Wildner 
10430d02842fSSascha Wildner         PassedArgs = 0;
10440d02842fSSascha Wildner         NextOp = Op->Asl.Child;
10450d02842fSSascha Wildner 
10460d02842fSSascha Wildner         while (NextOp)
10470d02842fSSascha Wildner         {
10480d02842fSSascha Wildner             PassedArgs++;
10490d02842fSSascha Wildner             NextOp = NextOp->Asl.Next;
10500d02842fSSascha Wildner         }
10510d02842fSSascha Wildner 
1052e5412f1eSSascha Wildner         if (Node->Value != ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS &&
10537c9678bcSSascha Wildner             Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL)
10540d02842fSSascha Wildner         {
10550d02842fSSascha Wildner             /*
10560d02842fSSascha Wildner              * Check the parsed arguments with the number expected by the
10570d02842fSSascha Wildner              * method declaration itself
10580d02842fSSascha Wildner              */
10590d02842fSSascha Wildner             if (PassedArgs != Node->Value)
10600d02842fSSascha Wildner             {
1061e5412f1eSSascha Wildner                 if (Node->Flags & ANOBJ_IS_EXTERNAL)
1062e5412f1eSSascha Wildner                 {
1063e5412f1eSSascha Wildner                     sprintf (AslGbl_MsgBuffer,
1064e5412f1eSSascha Wildner                         "according to previous use, %s requires %u",
1065e5412f1eSSascha Wildner                         Op->Asl.ExternalName, Node->Value);
1066e5412f1eSSascha Wildner                 }
1067e5412f1eSSascha Wildner                 else
1068e5412f1eSSascha Wildner                 {
1069806343b9SSascha Wildner                     sprintf (AslGbl_MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
10700d02842fSSascha Wildner                         Node->Value);
1071e5412f1eSSascha Wildner                 }
10720d02842fSSascha Wildner 
10730d02842fSSascha Wildner                 if (PassedArgs < Node->Value)
10740d02842fSSascha Wildner                 {
1075806343b9SSascha Wildner                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, AslGbl_MsgBuffer);
10760d02842fSSascha Wildner                 }
10770d02842fSSascha Wildner                 else
10780d02842fSSascha Wildner                 {
1079806343b9SSascha Wildner                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, AslGbl_MsgBuffer);
10800d02842fSSascha Wildner                 }
10810d02842fSSascha Wildner             }
10820d02842fSSascha Wildner         }
1083e5412f1eSSascha Wildner 
1084e5412f1eSSascha Wildner         /*
1085e5412f1eSSascha Wildner          * At this point, a method call to an external method has been
1086e5412f1eSSascha Wildner          * detected. As of 11/19/2019, iASL does not support parameter counts
1087e5412f1eSSascha Wildner          * for methods declared as external. Therefore, save the parameter
1088e5412f1eSSascha Wildner          * count of the first method call and use this count check other
1089e5412f1eSSascha Wildner          * method calls to ensure that the methods are being called with the
1090e5412f1eSSascha Wildner          * same amount of parameters.
1091e5412f1eSSascha Wildner          */
1092e5412f1eSSascha Wildner         else if (Node->Type == ACPI_TYPE_METHOD &&
1093e5412f1eSSascha Wildner             (Node->Flags & ANOBJ_IS_EXTERNAL) &&
1094e5412f1eSSascha Wildner             Node->Value == ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS &&
1095e5412f1eSSascha Wildner             Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL)
1096e5412f1eSSascha Wildner         {
1097e5412f1eSSascha Wildner             Node->Value = PassedArgs;
1098e5412f1eSSascha Wildner         }
10990d02842fSSascha Wildner     }
11000d02842fSSascha Wildner 
11010d02842fSSascha Wildner     /* 4) Check for an ASL Field definition */
11020d02842fSSascha Wildner 
11030d02842fSSascha Wildner     else if ((Op->Asl.Parent) &&
11040d02842fSSascha Wildner             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
11050d02842fSSascha Wildner              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
11060d02842fSSascha Wildner     {
11070d02842fSSascha Wildner         /*
11080d02842fSSascha Wildner          * Offset checking for fields. If the parent operation region has a
11090d02842fSSascha Wildner          * constant length (known at compile time), we can check fields
11100d02842fSSascha Wildner          * defined in that region against the region length. This will catch
11110d02842fSSascha Wildner          * fields and field units that cannot possibly fit within the region.
11120d02842fSSascha Wildner          *
11130d02842fSSascha Wildner          * Note: Index fields do not directly reference an operation region,
11140d02842fSSascha Wildner          * thus they are not included in this check.
11150d02842fSSascha Wildner          */
11160d02842fSSascha Wildner         if (Op == Op->Asl.Parent->Asl.Child)
11170d02842fSSascha Wildner         {
11180d02842fSSascha Wildner             /*
11190d02842fSSascha Wildner              * This is the first child of the field node, which is
11200d02842fSSascha Wildner              * the name of the region. Get the parse node for the
11210d02842fSSascha Wildner              * region -- which contains the length of the region.
11220d02842fSSascha Wildner              */
11230d02842fSSascha Wildner             OwningOp = Node->Op;
11240d02842fSSascha Wildner             Op->Asl.Parent->Asl.ExtraValue =
11250d02842fSSascha Wildner                 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
11260d02842fSSascha Wildner 
11270d02842fSSascha Wildner             /* Examine the field access width */
11280d02842fSSascha Wildner 
11290d02842fSSascha Wildner             switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
11300d02842fSSascha Wildner             {
11310d02842fSSascha Wildner             case AML_FIELD_ACCESS_ANY:
11320d02842fSSascha Wildner             case AML_FIELD_ACCESS_BYTE:
11330d02842fSSascha Wildner             case AML_FIELD_ACCESS_BUFFER:
11340d02842fSSascha Wildner             default:
11350d02842fSSascha Wildner 
11360d02842fSSascha Wildner                 MinimumLength = 1;
11370d02842fSSascha Wildner                 break;
11380d02842fSSascha Wildner 
11390d02842fSSascha Wildner             case AML_FIELD_ACCESS_WORD:
11400d02842fSSascha Wildner 
11410d02842fSSascha Wildner                 MinimumLength = 2;
11420d02842fSSascha Wildner                 break;
11430d02842fSSascha Wildner 
11440d02842fSSascha Wildner             case AML_FIELD_ACCESS_DWORD:
11450d02842fSSascha Wildner 
11460d02842fSSascha Wildner                 MinimumLength = 4;
11470d02842fSSascha Wildner                 break;
11480d02842fSSascha Wildner 
11490d02842fSSascha Wildner             case AML_FIELD_ACCESS_QWORD:
11500d02842fSSascha Wildner 
11510d02842fSSascha Wildner                 MinimumLength = 8;
11520d02842fSSascha Wildner                 break;
11530d02842fSSascha Wildner             }
11540d02842fSSascha Wildner 
11550d02842fSSascha Wildner             /*
11560d02842fSSascha Wildner              * Is the region at least as big as the access width?
11570d02842fSSascha Wildner              * Note: DataTableRegions have 0 length
11580d02842fSSascha Wildner              */
11590d02842fSSascha Wildner             if (((UINT32) OwningOp->Asl.Value.Integer) &&
11600d02842fSSascha Wildner                 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
11610d02842fSSascha Wildner             {
11620d02842fSSascha Wildner                 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
11630d02842fSSascha Wildner             }
11640d02842fSSascha Wildner 
11650d02842fSSascha Wildner             /*
11660d02842fSSascha Wildner              * Check EC/CMOS/SMBUS fields to make sure that the correct
11670d02842fSSascha Wildner              * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
11680d02842fSSascha Wildner              */
11690d02842fSSascha Wildner             SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
11700d02842fSSascha Wildner             switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
11710d02842fSSascha Wildner             {
11720d02842fSSascha Wildner             case ACPI_ADR_SPACE_EC:
11730d02842fSSascha Wildner             case ACPI_ADR_SPACE_CMOS:
11740d02842fSSascha Wildner             case ACPI_ADR_SPACE_GPIO:
11750d02842fSSascha Wildner 
1176820c5b08SSascha Wildner                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
1177820c5b08SSascha Wildner                     AML_FIELD_ACCESS_BYTE)
11780d02842fSSascha Wildner                 {
11790d02842fSSascha Wildner                     AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
11800d02842fSSascha Wildner                 }
11810d02842fSSascha Wildner                 break;
11820d02842fSSascha Wildner 
11830d02842fSSascha Wildner             case ACPI_ADR_SPACE_SMBUS:
11840d02842fSSascha Wildner             case ACPI_ADR_SPACE_IPMI:
11850d02842fSSascha Wildner             case ACPI_ADR_SPACE_GSBUS:
11860d02842fSSascha Wildner 
1187820c5b08SSascha Wildner                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
1188820c5b08SSascha Wildner                     AML_FIELD_ACCESS_BUFFER)
11890d02842fSSascha Wildner                 {
11900d02842fSSascha Wildner                     AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
11910d02842fSSascha Wildner                 }
11920d02842fSSascha Wildner                 break;
11930d02842fSSascha Wildner 
11940d02842fSSascha Wildner             default:
11950d02842fSSascha Wildner 
11960d02842fSSascha Wildner                 /* Nothing to do for other address spaces */
11970d02842fSSascha Wildner 
11980d02842fSSascha Wildner                 break;
11990d02842fSSascha Wildner             }
12000d02842fSSascha Wildner         }
12010d02842fSSascha Wildner         else
12020d02842fSSascha Wildner         {
12030d02842fSSascha Wildner             /*
12040d02842fSSascha Wildner              * This is one element of the field list. Check to make sure
12050d02842fSSascha Wildner              * that it does not go beyond the end of the parent operation region.
12060d02842fSSascha Wildner              *
12070d02842fSSascha Wildner              * In the code below:
12080d02842fSSascha Wildner              *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
12090d02842fSSascha Wildner              *    Op->Asl.ExtraValue                  - Field start offset (bits)
12100d02842fSSascha Wildner              *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
12110d02842fSSascha Wildner              *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
12120d02842fSSascha Wildner              */
12130d02842fSSascha Wildner             if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
12140d02842fSSascha Wildner             {
12150d02842fSSascha Wildner                 XfCheckFieldRange (Op,
12160d02842fSSascha Wildner                     Op->Asl.Parent->Asl.ExtraValue,
12170d02842fSSascha Wildner                     Op->Asl.ExtraValue,
12180d02842fSSascha Wildner                     (UINT32) Op->Asl.Child->Asl.Value.Integer,
12190d02842fSSascha Wildner                     Op->Asl.Child->Asl.ExtraValue);
12200d02842fSSascha Wildner             }
12210d02842fSSascha Wildner         }
12220d02842fSSascha Wildner     }
12230d02842fSSascha Wildner 
1224a4b9c0c9SSascha Wildner     /*
1225a4b9c0c9SSascha Wildner      * 5) Check for external resolution
12260f79e681SSascha Wildner      *
1227a4b9c0c9SSascha Wildner      * By this point, everything should be loaded in the namespace. If a
1228a4b9c0c9SSascha Wildner      * namespace lookup results in a namespace node that is an external, it
1229a4b9c0c9SSascha Wildner      * means that this named object was not defined in the input ASL. This
1230a4b9c0c9SSascha Wildner      * causes issues because there are plenty of incidents where developers
1231a4b9c0c9SSascha Wildner      * use the external keyword to suppress compiler errors about undefined
1232a4b9c0c9SSascha Wildner      * objects. Note: this only applies when compiling multiple definition
1233a4b9c0c9SSascha Wildner      * blocks.
12340f79e681SSascha Wildner      *
12350f79e681SSascha Wildner      * Do not check for external resolution in the following cases:
12360f79e681SSascha Wildner      *
12370f79e681SSascha Wildner      * case 1) External (ABCD)
12380f79e681SSascha Wildner      *
12390f79e681SSascha Wildner      *         This declares ABCD as an external so there is no requirement for
12400f79e681SSascha Wildner      *         ABCD to be loaded in the namespace when analyzing the actual
12410f79e681SSascha Wildner      *         External() statement.
12420f79e681SSascha Wildner      *
12430f79e681SSascha Wildner      * case 2) CondRefOf (ABCD)
12440f79e681SSascha Wildner      *
12450f79e681SSascha Wildner      *         This operator will query the ACPI namespace on the existence of
12460f79e681SSascha Wildner      *         ABCD. If ABCD does not exist, this operator will return a 0
12470f79e681SSascha Wildner      *         without incurring AML runtime errors. Therefore, ABCD is allowed
12480f79e681SSascha Wildner      *         to not exist when analyzing the CondRefOf operator.
12490f79e681SSascha Wildner      *
12500f79e681SSascha Wildner      * case 3) External (ABCD)
12510f79e681SSascha Wildner      *         if (CondRefOf (ABCD))
12520f79e681SSascha Wildner      *         {
12530f79e681SSascha Wildner      *             Store (0, ABCD)
12540f79e681SSascha Wildner      *         }
12550f79e681SSascha Wildner      *
12560f79e681SSascha Wildner      *         In this case, ABCD is accessed only if it exists due to the if
12570f79e681SSascha Wildner      *         statement so there is no need to flag the ABCD nested in the
12580f79e681SSascha Wildner      *         store operator.
1259a4b9c0c9SSascha Wildner      */
1260a4b9c0c9SSascha Wildner     if (AslGbl_ParseTreeRoot->Asl.Child && AslGbl_ParseTreeRoot->Asl.Child->Asl.Next &&
12610f79e681SSascha Wildner         (Node->Flags & ANOBJ_IS_EXTERNAL) &&
12620f79e681SSascha Wildner         Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL &&
12630f79e681SSascha Wildner         Op->Asl.ParseOpcode != PARSEOP_EXTERNAL &&
12640f79e681SSascha Wildner         Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_CONDREFOF &&
12650f79e681SSascha Wildner         !XfRefIsGuardedByIfCondRefOf (Node, Op))
1266a4b9c0c9SSascha Wildner     {
1267c5a52fd3SSascha Wildner         ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
1268c5a52fd3SSascha Wildner         sprintf (AslGbl_MsgBuffer, "full path of external object: %s",
1269c5a52fd3SSascha Wildner             ExternalPath);
1270c5a52fd3SSascha Wildner         AslDualParseOpError (ASL_ERROR, ASL_MSG_UNDEFINED_EXTERNAL, Op, NULL,
1271c5a52fd3SSascha Wildner             ASL_MSG_EXTERNAL_FOUND_HERE, Node->Op, AslGbl_MsgBuffer);
1272c5a52fd3SSascha Wildner         if (ExternalPath)
1273c5a52fd3SSascha Wildner         {
1274c5a52fd3SSascha Wildner             ACPI_FREE (ExternalPath);
1275c5a52fd3SSascha Wildner         }
1276a4b9c0c9SSascha Wildner     }
1277a4b9c0c9SSascha Wildner 
12782e2672b8SSascha Wildner     /* 5) Check for a connection object */
12792e2672b8SSascha Wildner #if 0
12802e2672b8SSascha Wildner     else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
12812e2672b8SSascha Wildner     {
12822e2672b8SSascha Wildner         return_ACPI_STATUS (Status);
12832e2672b8SSascha Wildner     }
12842e2672b8SSascha Wildner #endif
12852e2672b8SSascha Wildner 
12860d02842fSSascha Wildner     Op->Asl.Node = Node;
12870d02842fSSascha Wildner     return_ACPI_STATUS (Status);
12880d02842fSSascha Wildner }
12890d02842fSSascha Wildner 
12900d02842fSSascha Wildner 
12910d02842fSSascha Wildner /*******************************************************************************
12920d02842fSSascha Wildner  *
12930f79e681SSascha Wildner  * FUNCTION:    XfRefIsGuardedByIfCondRefOf
12940f79e681SSascha Wildner  *
12950f79e681SSascha Wildner  * PARAMETERS:  Node        - Named object reference node
12960f79e681SSascha Wildner  *              Op          - Named object reference parse node
12970f79e681SSascha Wildner  *
12980f79e681SSascha Wildner  * RETURN:      BOOLEAN
12990f79e681SSascha Wildner  *
13000f79e681SSascha Wildner  * DESCRIPTION: returns true if Op checked inside if (CondRefOf (...))
13010f79e681SSascha Wildner  *              refers to Node.
13020f79e681SSascha Wildner  *
13030f79e681SSascha Wildner  ******************************************************************************/
13040f79e681SSascha Wildner 
13050f79e681SSascha Wildner static BOOLEAN
XfRefIsGuardedByIfCondRefOf(ACPI_NAMESPACE_NODE * Node,ACPI_PARSE_OBJECT * Op)13060f79e681SSascha Wildner XfRefIsGuardedByIfCondRefOf (
13070f79e681SSascha Wildner     ACPI_NAMESPACE_NODE     *Node,
13080f79e681SSascha Wildner     ACPI_PARSE_OBJECT       *Op)
13090f79e681SSascha Wildner {
13100f79e681SSascha Wildner     ACPI_PARSE_OBJECT       *Parent = Op->Asl.Parent;
13110f79e681SSascha Wildner 
13120f79e681SSascha Wildner 
13130f79e681SSascha Wildner     while (Parent)
13140f79e681SSascha Wildner     {
13150f79e681SSascha Wildner         if (Parent->Asl.ParseOpcode == PARSEOP_IF &&
13160f79e681SSascha Wildner             XfFindCondRefOfName (Node, Parent->Asl.Child))
13170f79e681SSascha Wildner         {
13180f79e681SSascha Wildner             return (TRUE);
13190f79e681SSascha Wildner         }
13200f79e681SSascha Wildner 
13210f79e681SSascha Wildner         Parent = Parent->Asl.Parent;
13220f79e681SSascha Wildner     }
13230f79e681SSascha Wildner 
13240f79e681SSascha Wildner     return (FALSE);
13250f79e681SSascha Wildner }
13260f79e681SSascha Wildner 
13270f79e681SSascha Wildner 
13280f79e681SSascha Wildner /*******************************************************************************
13290f79e681SSascha Wildner  *
13300f79e681SSascha Wildner  * FUNCTION:    XfRefIsGuardedByIfCondRefOf
13310f79e681SSascha Wildner  *
13320f79e681SSascha Wildner  * PARAMETERS:  Node        - Named object reference node
13330f79e681SSascha Wildner  *              Op          - Named object reference parse node
13340f79e681SSascha Wildner  *
13350f79e681SSascha Wildner  * RETURN:      BOOLEAN
13360f79e681SSascha Wildner  *
13370f79e681SSascha Wildner  * DESCRIPTION: returns true if Op checked inside if (CondRefOf (...))
13380f79e681SSascha Wildner  *              refers to Node.
13390f79e681SSascha Wildner  *
13400f79e681SSascha Wildner  ******************************************************************************/
13410f79e681SSascha Wildner 
13420f79e681SSascha Wildner static BOOLEAN
XfFindCondRefOfName(ACPI_NAMESPACE_NODE * Node,ACPI_PARSE_OBJECT * Op)13430f79e681SSascha Wildner XfFindCondRefOfName (
13440f79e681SSascha Wildner     ACPI_NAMESPACE_NODE     *Node,
13450f79e681SSascha Wildner     ACPI_PARSE_OBJECT       *Op)
13460f79e681SSascha Wildner {
13470f79e681SSascha Wildner     BOOLEAN                 CondRefOfFound = FALSE;
13480f79e681SSascha Wildner 
13490f79e681SSascha Wildner 
13500f79e681SSascha Wildner     if (!Op)
13510f79e681SSascha Wildner     {
13520f79e681SSascha Wildner         return (FALSE);
13530f79e681SSascha Wildner     }
13540f79e681SSascha Wildner 
13550f79e681SSascha Wildner     switch (Op->Asl.ParseOpcode)
13560f79e681SSascha Wildner     {
13570f79e681SSascha Wildner     case PARSEOP_CONDREFOF:
13580f79e681SSascha Wildner 
13590f79e681SSascha Wildner         return (Op->Asl.Child->Common.Node == Node);
13600f79e681SSascha Wildner         break;
13610f79e681SSascha Wildner 
13620f79e681SSascha Wildner     case PARSEOP_LAND:
13630f79e681SSascha Wildner 
13640f79e681SSascha Wildner         CondRefOfFound = XfFindCondRefOfName (Node, Op->Asl.Child);
13650f79e681SSascha Wildner         if (CondRefOfFound)
13660f79e681SSascha Wildner         {
13670f79e681SSascha Wildner             return (TRUE);
13680f79e681SSascha Wildner         }
13690f79e681SSascha Wildner 
13700f79e681SSascha Wildner         return (XfFindCondRefOfName (Node, Op->Asl.Child->Asl.Next));
13710f79e681SSascha Wildner         break;
13720f79e681SSascha Wildner 
13730f79e681SSascha Wildner     default:
13740f79e681SSascha Wildner 
13750f79e681SSascha Wildner         return (FALSE);
13760f79e681SSascha Wildner         break;
13770f79e681SSascha Wildner     }
13780f79e681SSascha Wildner }
13790f79e681SSascha Wildner 
13800f79e681SSascha Wildner 
13810f79e681SSascha Wildner /*******************************************************************************
13820f79e681SSascha Wildner  *
13830d02842fSSascha Wildner  * FUNCTION:    XfNamespaceLocateEnd
13840d02842fSSascha Wildner  *
13850d02842fSSascha Wildner  * PARAMETERS:  ASL_WALK_CALLBACK
13860d02842fSSascha Wildner  *
13870d02842fSSascha Wildner  * RETURN:      Status
13880d02842fSSascha Wildner  *
13890d02842fSSascha Wildner  * DESCRIPTION: Ascending callback used during cross reference. We only
13900d02842fSSascha Wildner  *              need to worry about scope management here.
13910d02842fSSascha Wildner  *
13920d02842fSSascha Wildner  ******************************************************************************/
13930d02842fSSascha Wildner 
13940d02842fSSascha Wildner static ACPI_STATUS
XfNamespaceLocateEnd(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)13950d02842fSSascha Wildner XfNamespaceLocateEnd (
13960d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
13970d02842fSSascha Wildner     UINT32                  Level,
13980d02842fSSascha Wildner     void                    *Context)
13990d02842fSSascha Wildner {
14000d02842fSSascha Wildner     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
14010d02842fSSascha Wildner     const ACPI_OPCODE_INFO  *OpInfo;
14020d02842fSSascha Wildner 
14030d02842fSSascha Wildner 
14040d02842fSSascha Wildner     ACPI_FUNCTION_TRACE (XfNamespaceLocateEnd);
14050d02842fSSascha Wildner 
14060d02842fSSascha Wildner 
14070d02842fSSascha Wildner     /* We are only interested in opcodes that have an associated name */
14080d02842fSSascha Wildner 
14090d02842fSSascha Wildner     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
14100d02842fSSascha Wildner     if (!(OpInfo->Flags & AML_NAMED))
14110d02842fSSascha Wildner     {
14120d02842fSSascha Wildner         return_ACPI_STATUS (AE_OK);
14130d02842fSSascha Wildner     }
14140d02842fSSascha Wildner 
14150d02842fSSascha Wildner     /* Not interested in name references, we did not open a scope for them */
14160d02842fSSascha Wildner 
14170d02842fSSascha Wildner     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
14180d02842fSSascha Wildner         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
14191093ca81SSascha Wildner         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
14201093ca81SSascha Wildner         (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
14210d02842fSSascha Wildner     {
14220d02842fSSascha Wildner         return_ACPI_STATUS (AE_OK);
14230d02842fSSascha Wildner     }
14240d02842fSSascha Wildner 
14250d02842fSSascha Wildner     /* Pop the scope stack if necessary */
14260d02842fSSascha Wildner 
14270d02842fSSascha Wildner     if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
14280d02842fSSascha Wildner     {
14290d02842fSSascha Wildner 
14300d02842fSSascha Wildner         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
14310d02842fSSascha Wildner             "%s: Popping scope for Op %p\n",
14320d02842fSSascha Wildner             AcpiUtGetTypeName (OpInfo->ObjectType), Op));
14330d02842fSSascha Wildner 
14340d02842fSSascha Wildner         (void) AcpiDsScopeStackPop (WalkState);
14350d02842fSSascha Wildner     }
14360d02842fSSascha Wildner 
14370d02842fSSascha Wildner     return_ACPI_STATUS (AE_OK);
14380d02842fSSascha Wildner }
143900ffa116SSascha Wildner 
144000ffa116SSascha Wildner 
144100ffa116SSascha Wildner /*******************************************************************************
144200ffa116SSascha Wildner  *
144300ffa116SSascha Wildner  * FUNCTION:    XfValidateCrossReference
144400ffa116SSascha Wildner  *
144500ffa116SSascha Wildner  * PARAMETERS:  Op                      - Parse Op that references the object
144600ffa116SSascha Wildner  *              OpInfo                  - Parse Op info struct
144700ffa116SSascha Wildner  *              Node                    - Node for the referenced object
144800ffa116SSascha Wildner  *
144900ffa116SSascha Wildner  * RETURN:      TRUE if the reference is legal, FALSE otherwise
145000ffa116SSascha Wildner  *
145100ffa116SSascha Wildner  * DESCRIPTION: Determine if a reference to another object is allowed.
145200ffa116SSascha Wildner  *
145300ffa116SSascha Wildner  * EXAMPLE:
145400ffa116SSascha Wildner  *      Method (A) {Name (INT1, 1)}     Declaration of object INT1
145500ffa116SSascha Wildner  *      Method (B) (Store (2, \A.INT1)} Illegal reference to object INT1
145600ffa116SSascha Wildner  *                                      (INT1 is temporary, valid only during
145700ffa116SSascha Wildner  *                                      execution of A)
145800ffa116SSascha Wildner  *
145900ffa116SSascha Wildner  * NOTES:
1460ff3cb46dSSascha Wildner  *      A null pointer returned by either UtGetParentMethodOp or
1461ff3cb46dSSascha Wildner  *      UtGetParentMethodNode indicates that the parameter object is not
146200ffa116SSascha Wildner  *      within a control method.
146300ffa116SSascha Wildner  *
146400ffa116SSascha Wildner  *      Five cases are handled: Case(Op, Node)
146500ffa116SSascha Wildner  *      1) Case(0,0): Op is not within a method, Node is not    --> OK
146600ffa116SSascha Wildner  *      2) Case(0,1): Op is not within a method, but Node is    --> Illegal
146700ffa116SSascha Wildner  *      3) Case(1,0): Op is within a method, Node is not        --> OK
146800ffa116SSascha Wildner  *      4) Case(1,1): Both are within the same method           --> OK
146900ffa116SSascha Wildner  *      5) Case(1,1): Both are in methods, but not same method  --> Illegal
147000ffa116SSascha Wildner  *
147100ffa116SSascha Wildner  ******************************************************************************/
147200ffa116SSascha Wildner 
147300ffa116SSascha Wildner static BOOLEAN
XfValidateCrossReference(ACPI_PARSE_OBJECT * Op,const ACPI_OPCODE_INFO * OpInfo,ACPI_NAMESPACE_NODE * Node)147400ffa116SSascha Wildner XfValidateCrossReference (
147500ffa116SSascha Wildner     ACPI_PARSE_OBJECT       *Op,
147600ffa116SSascha Wildner     const ACPI_OPCODE_INFO  *OpInfo,
147700ffa116SSascha Wildner     ACPI_NAMESPACE_NODE     *Node)
147800ffa116SSascha Wildner {
147900ffa116SSascha Wildner     ACPI_PARSE_OBJECT       *ReferencingMethodOp;
148000ffa116SSascha Wildner     ACPI_NAMESPACE_NODE     *ReferencedMethodNode;
148100ffa116SSascha Wildner 
148200ffa116SSascha Wildner 
148300ffa116SSascha Wildner     /* Ignore actual named (and related) object declarations */
148400ffa116SSascha Wildner 
148500ffa116SSascha Wildner     if (OpInfo->Flags & (AML_NAMED | AML_CREATE | AML_DEFER | AML_HAS_ARGS))
148600ffa116SSascha Wildner     {
148700ffa116SSascha Wildner         return (TRUE);
148800ffa116SSascha Wildner     }
148900ffa116SSascha Wildner 
149000ffa116SSascha Wildner     /*
149100ffa116SSascha Wildner      * 1) Search upwards in parse tree for owner of the referencing object
149200ffa116SSascha Wildner      * 2) Search upwards in namespace to find the owner of the referenced object
149300ffa116SSascha Wildner      */
1494ff3cb46dSSascha Wildner     ReferencingMethodOp = UtGetParentMethodOp (Op);
1495ff3cb46dSSascha Wildner     ReferencedMethodNode = UtGetParentMethodNode (Node);
149600ffa116SSascha Wildner 
149700ffa116SSascha Wildner     if (!ReferencingMethodOp && !ReferencedMethodNode)
149800ffa116SSascha Wildner     {
149900ffa116SSascha Wildner         /*
150000ffa116SSascha Wildner          * 1) Case (0,0): Both Op and Node are not within methods
150100ffa116SSascha Wildner          * --> OK
150200ffa116SSascha Wildner          */
150300ffa116SSascha Wildner         return (TRUE);
150400ffa116SSascha Wildner     }
150500ffa116SSascha Wildner 
150600ffa116SSascha Wildner     if (!ReferencingMethodOp && ReferencedMethodNode)
150700ffa116SSascha Wildner     {
150800ffa116SSascha Wildner         /*
150900ffa116SSascha Wildner          * 2) Case (0,1): Op is not in a method, but Node is within a
151000ffa116SSascha Wildner          * method --> illegal
151100ffa116SSascha Wildner          */
151200ffa116SSascha Wildner         return (FALSE);
151300ffa116SSascha Wildner     }
151400ffa116SSascha Wildner     else if (ReferencingMethodOp && !ReferencedMethodNode)
151500ffa116SSascha Wildner     {
151600ffa116SSascha Wildner         /*
151700ffa116SSascha Wildner          * 3) Case (1,0): Op is within a method, but Node is not
151800ffa116SSascha Wildner          * --> OK
151900ffa116SSascha Wildner          */
152000ffa116SSascha Wildner         return (TRUE);
152100ffa116SSascha Wildner     }
152200ffa116SSascha Wildner     else if (ReferencingMethodOp->Asl.Node == ReferencedMethodNode)
152300ffa116SSascha Wildner     {
152400ffa116SSascha Wildner         /*
152500ffa116SSascha Wildner          * 4) Case (1,1): Both Op and Node are within the same method
152600ffa116SSascha Wildner          * --> OK
152700ffa116SSascha Wildner          */
152800ffa116SSascha Wildner         return (TRUE);
152900ffa116SSascha Wildner     }
153000ffa116SSascha Wildner     else
153100ffa116SSascha Wildner     {
153200ffa116SSascha Wildner         /*
153300ffa116SSascha Wildner          * 5) Case (1,1), Op and Node are in different methods
153400ffa116SSascha Wildner          * --> Illegal
153500ffa116SSascha Wildner          */
153600ffa116SSascha Wildner         return (FALSE);
153700ffa116SSascha Wildner     }
153800ffa116SSascha Wildner }
1539