1efcc2a30SJung-uk Kim /******************************************************************************
2efcc2a30SJung-uk Kim *
3efcc2a30SJung-uk Kim * Module Name: aslxref - Namespace cross-reference
4efcc2a30SJung-uk Kim *
5efcc2a30SJung-uk Kim *****************************************************************************/
6efcc2a30SJung-uk Kim
70d84335fSJung-uk Kim /******************************************************************************
80d84335fSJung-uk Kim *
90d84335fSJung-uk Kim * 1. Copyright Notice
100d84335fSJung-uk Kim *
11*804fe266SJung-uk Kim * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
12efcc2a30SJung-uk Kim * All rights reserved.
13efcc2a30SJung-uk Kim *
140d84335fSJung-uk Kim * 2. License
150d84335fSJung-uk Kim *
160d84335fSJung-uk Kim * 2.1. This is your license from Intel Corp. under its intellectual property
170d84335fSJung-uk Kim * rights. You may have additional license terms from the party that provided
180d84335fSJung-uk Kim * you this software, covering your right to use that party's intellectual
190d84335fSJung-uk Kim * property rights.
200d84335fSJung-uk Kim *
210d84335fSJung-uk Kim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
220d84335fSJung-uk Kim * copy of the source code appearing in this file ("Covered Code") an
230d84335fSJung-uk Kim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
240d84335fSJung-uk Kim * base code distributed originally by Intel ("Original Intel Code") to copy,
250d84335fSJung-uk Kim * make derivatives, distribute, use and display any portion of the Covered
260d84335fSJung-uk Kim * Code in any form, with the right to sublicense such rights; and
270d84335fSJung-uk Kim *
280d84335fSJung-uk Kim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
290d84335fSJung-uk Kim * license (with the right to sublicense), under only those claims of Intel
300d84335fSJung-uk Kim * patents that are infringed by the Original Intel Code, to make, use, sell,
310d84335fSJung-uk Kim * offer to sell, and import the Covered Code and derivative works thereof
320d84335fSJung-uk Kim * solely to the minimum extent necessary to exercise the above copyright
330d84335fSJung-uk Kim * license, and in no event shall the patent license extend to any additions
340d84335fSJung-uk Kim * to or modifications of the Original Intel Code. No other license or right
350d84335fSJung-uk Kim * is granted directly or by implication, estoppel or otherwise;
360d84335fSJung-uk Kim *
370d84335fSJung-uk Kim * The above copyright and patent license is granted only if the following
380d84335fSJung-uk Kim * conditions are met:
390d84335fSJung-uk Kim *
400d84335fSJung-uk Kim * 3. Conditions
410d84335fSJung-uk Kim *
420d84335fSJung-uk Kim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
430d84335fSJung-uk Kim * Redistribution of source code of any substantial portion of the Covered
440d84335fSJung-uk Kim * Code or modification with rights to further distribute source must include
450d84335fSJung-uk Kim * the above Copyright Notice, the above License, this list of Conditions,
460d84335fSJung-uk Kim * and the following Disclaimer and Export Compliance provision. In addition,
470d84335fSJung-uk Kim * Licensee must cause all Covered Code to which Licensee contributes to
480d84335fSJung-uk Kim * contain a file documenting the changes Licensee made to create that Covered
490d84335fSJung-uk Kim * Code and the date of any change. Licensee must include in that file the
500d84335fSJung-uk Kim * documentation of any changes made by any predecessor Licensee. Licensee
510d84335fSJung-uk Kim * must include a prominent statement that the modification is derived,
520d84335fSJung-uk Kim * directly or indirectly, from Original Intel Code.
530d84335fSJung-uk Kim *
540d84335fSJung-uk Kim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
550d84335fSJung-uk Kim * Redistribution of source code of any substantial portion of the Covered
560d84335fSJung-uk Kim * Code or modification without rights to further distribute source must
570d84335fSJung-uk Kim * include the following Disclaimer and Export Compliance provision in the
580d84335fSJung-uk Kim * documentation and/or other materials provided with distribution. In
590d84335fSJung-uk Kim * addition, Licensee may not authorize further sublicense of source of any
600d84335fSJung-uk Kim * portion of the Covered Code, and must include terms to the effect that the
610d84335fSJung-uk Kim * license from Licensee to its licensee is limited to the intellectual
620d84335fSJung-uk Kim * property embodied in the software Licensee provides to its licensee, and
630d84335fSJung-uk Kim * not to intellectual property embodied in modifications its licensee may
640d84335fSJung-uk Kim * make.
650d84335fSJung-uk Kim *
660d84335fSJung-uk Kim * 3.3. Redistribution of Executable. Redistribution in executable form of any
670d84335fSJung-uk Kim * substantial portion of the Covered Code or modification must reproduce the
680d84335fSJung-uk Kim * above Copyright Notice, and the following Disclaimer and Export Compliance
690d84335fSJung-uk Kim * provision in the documentation and/or other materials provided with the
700d84335fSJung-uk Kim * distribution.
710d84335fSJung-uk Kim *
720d84335fSJung-uk Kim * 3.4. Intel retains all right, title, and interest in and to the Original
730d84335fSJung-uk Kim * Intel Code.
740d84335fSJung-uk Kim *
750d84335fSJung-uk Kim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
760d84335fSJung-uk Kim * Intel shall be used in advertising or otherwise to promote the sale, use or
770d84335fSJung-uk Kim * other dealings in products derived from or relating to the Covered Code
780d84335fSJung-uk Kim * without prior written authorization from Intel.
790d84335fSJung-uk Kim *
800d84335fSJung-uk Kim * 4. Disclaimer and Export Compliance
810d84335fSJung-uk Kim *
820d84335fSJung-uk Kim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
830d84335fSJung-uk Kim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
840d84335fSJung-uk Kim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
850d84335fSJung-uk Kim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
860d84335fSJung-uk Kim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
870d84335fSJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
880d84335fSJung-uk Kim * PARTICULAR PURPOSE.
890d84335fSJung-uk Kim *
900d84335fSJung-uk Kim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
910d84335fSJung-uk Kim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
920d84335fSJung-uk Kim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
930d84335fSJung-uk Kim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
940d84335fSJung-uk Kim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
950d84335fSJung-uk Kim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
960d84335fSJung-uk Kim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
970d84335fSJung-uk Kim * LIMITED REMEDY.
980d84335fSJung-uk Kim *
990d84335fSJung-uk Kim * 4.3. Licensee shall not export, either directly or indirectly, any of this
1000d84335fSJung-uk Kim * software or system incorporating such software without first obtaining any
1010d84335fSJung-uk Kim * required license or other approval from the U. S. Department of Commerce or
1020d84335fSJung-uk Kim * any other agency or department of the United States Government. In the
1030d84335fSJung-uk Kim * event Licensee exports any such software from the United States or
1040d84335fSJung-uk Kim * re-exports any such software from a foreign destination, Licensee shall
1050d84335fSJung-uk Kim * ensure that the distribution and export/re-export of the software is in
1060d84335fSJung-uk Kim * compliance with all laws, regulations, orders, or other restrictions of the
1070d84335fSJung-uk Kim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1080d84335fSJung-uk Kim * any of its subsidiaries will export/re-export any technical data, process,
1090d84335fSJung-uk Kim * software, or service, directly or indirectly, to any country for which the
1100d84335fSJung-uk Kim * United States government or any agency thereof requires an export license,
1110d84335fSJung-uk Kim * other governmental approval, or letter of assurance, without first obtaining
1120d84335fSJung-uk Kim * such license, approval or letter.
1130d84335fSJung-uk Kim *
1140d84335fSJung-uk Kim *****************************************************************************
1150d84335fSJung-uk Kim *
1160d84335fSJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the
1170d84335fSJung-uk Kim * following license:
1180d84335fSJung-uk Kim *
119efcc2a30SJung-uk Kim * Redistribution and use in source and binary forms, with or without
120efcc2a30SJung-uk Kim * modification, are permitted provided that the following conditions
121efcc2a30SJung-uk Kim * are met:
122efcc2a30SJung-uk Kim * 1. Redistributions of source code must retain the above copyright
123efcc2a30SJung-uk Kim * notice, this list of conditions, and the following disclaimer,
124efcc2a30SJung-uk Kim * without modification.
125efcc2a30SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126efcc2a30SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below
127efcc2a30SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon
128efcc2a30SJung-uk Kim * including a substantially similar Disclaimer requirement for further
129efcc2a30SJung-uk Kim * binary redistribution.
130efcc2a30SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names
131efcc2a30SJung-uk Kim * of any contributors may be used to endorse or promote products derived
132efcc2a30SJung-uk Kim * from this software without specific prior written permission.
133efcc2a30SJung-uk Kim *
1340d84335fSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1350d84335fSJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1360d84335fSJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1370d84335fSJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1380d84335fSJung-uk Kim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1390d84335fSJung-uk Kim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1400d84335fSJung-uk Kim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1410d84335fSJung-uk Kim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1420d84335fSJung-uk Kim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1430d84335fSJung-uk Kim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1440d84335fSJung-uk Kim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1450d84335fSJung-uk Kim *
1460d84335fSJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the
147efcc2a30SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free
148efcc2a30SJung-uk Kim * Software Foundation.
149efcc2a30SJung-uk Kim *
1500d84335fSJung-uk Kim *****************************************************************************/
151efcc2a30SJung-uk Kim
152efcc2a30SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
153efcc2a30SJung-uk Kim #include "aslcompiler.y.h"
154efcc2a30SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
155efcc2a30SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
156efcc2a30SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
157efcc2a30SJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h>
158efcc2a30SJung-uk Kim
159efcc2a30SJung-uk Kim
160efcc2a30SJung-uk Kim #define _COMPONENT ACPI_COMPILER
161efcc2a30SJung-uk Kim ACPI_MODULE_NAME ("aslxref")
162efcc2a30SJung-uk Kim
163efcc2a30SJung-uk Kim /* Local prototypes */
164efcc2a30SJung-uk Kim
165efcc2a30SJung-uk Kim static ACPI_STATUS
166efcc2a30SJung-uk Kim XfNamespaceLocateBegin (
167efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op,
168efcc2a30SJung-uk Kim UINT32 Level,
169efcc2a30SJung-uk Kim void *Context);
170efcc2a30SJung-uk Kim
171efcc2a30SJung-uk Kim static ACPI_STATUS
172efcc2a30SJung-uk Kim XfNamespaceLocateEnd (
173efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op,
174efcc2a30SJung-uk Kim UINT32 Level,
175efcc2a30SJung-uk Kim void *Context);
176efcc2a30SJung-uk Kim
177cd6518c7SJung-uk Kim static BOOLEAN
178cd6518c7SJung-uk Kim XfValidateCrossReference (
179cd6518c7SJung-uk Kim ACPI_PARSE_OBJECT *Op,
180cd6518c7SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo,
181cd6518c7SJung-uk Kim ACPI_NAMESPACE_NODE *Node);
182cd6518c7SJung-uk Kim
183efcc2a30SJung-uk Kim static BOOLEAN
184efcc2a30SJung-uk Kim XfObjectExists (
185efcc2a30SJung-uk Kim char *Name);
186efcc2a30SJung-uk Kim
187efcc2a30SJung-uk Kim static ACPI_STATUS
188efcc2a30SJung-uk Kim XfCompareOneNamespaceObject (
189efcc2a30SJung-uk Kim ACPI_HANDLE ObjHandle,
190efcc2a30SJung-uk Kim UINT32 Level,
191efcc2a30SJung-uk Kim void *Context,
192efcc2a30SJung-uk Kim void **ReturnValue);
193efcc2a30SJung-uk Kim
194efcc2a30SJung-uk Kim static void
195efcc2a30SJung-uk Kim XfCheckFieldRange (
196efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op,
197efcc2a30SJung-uk Kim UINT32 RegionBitLength,
198efcc2a30SJung-uk Kim UINT32 FieldBitOffset,
199efcc2a30SJung-uk Kim UINT32 FieldBitLength,
200efcc2a30SJung-uk Kim UINT32 AccessBitWidth);
201efcc2a30SJung-uk Kim
20208ddfe86SJung-uk Kim static BOOLEAN
20308ddfe86SJung-uk Kim XfFindCondRefOfName (
20408ddfe86SJung-uk Kim ACPI_NAMESPACE_NODE *Node,
20508ddfe86SJung-uk Kim ACPI_PARSE_OBJECT *Op);
20608ddfe86SJung-uk Kim
20708ddfe86SJung-uk Kim static BOOLEAN
20808ddfe86SJung-uk Kim XfRefIsGuardedByIfCondRefOf (
20908ddfe86SJung-uk Kim ACPI_NAMESPACE_NODE *Node,
21008ddfe86SJung-uk Kim ACPI_PARSE_OBJECT *Op);
21108ddfe86SJung-uk Kim
212efcc2a30SJung-uk Kim
213efcc2a30SJung-uk Kim /*******************************************************************************
214efcc2a30SJung-uk Kim *
215efcc2a30SJung-uk Kim * FUNCTION: XfCrossReferenceNamespace
216efcc2a30SJung-uk Kim *
217efcc2a30SJung-uk Kim * PARAMETERS: None
218efcc2a30SJung-uk Kim *
219efcc2a30SJung-uk Kim * RETURN: Status
220efcc2a30SJung-uk Kim *
221efcc2a30SJung-uk Kim * DESCRIPTION: Perform a cross reference check of the parse tree against the
222efcc2a30SJung-uk Kim * namespace. Every named referenced within the parse tree
223efcc2a30SJung-uk Kim * should be get resolved with a namespace lookup. If not, the
224efcc2a30SJung-uk Kim * original reference in the ASL code is invalid -- i.e., refers
225efcc2a30SJung-uk Kim * to a non-existent object.
226efcc2a30SJung-uk Kim *
227efcc2a30SJung-uk Kim * NOTE: The ASL "External" operator causes the name to be inserted into the
228efcc2a30SJung-uk Kim * namespace so that references to the external name will be resolved
229efcc2a30SJung-uk Kim * correctly here.
230efcc2a30SJung-uk Kim *
231efcc2a30SJung-uk Kim ******************************************************************************/
232efcc2a30SJung-uk Kim
233efcc2a30SJung-uk Kim ACPI_STATUS
XfCrossReferenceNamespace(void)234efcc2a30SJung-uk Kim XfCrossReferenceNamespace (
235efcc2a30SJung-uk Kim void)
236efcc2a30SJung-uk Kim {
237efcc2a30SJung-uk Kim ACPI_WALK_STATE *WalkState;
238efcc2a30SJung-uk Kim
239efcc2a30SJung-uk Kim
240efcc2a30SJung-uk Kim /*
241efcc2a30SJung-uk Kim * Create a new walk state for use when looking up names
242efcc2a30SJung-uk Kim * within the namespace (Passed as context to the callbacks)
243efcc2a30SJung-uk Kim */
244efcc2a30SJung-uk Kim WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
245efcc2a30SJung-uk Kim if (!WalkState)
246efcc2a30SJung-uk Kim {
247efcc2a30SJung-uk Kim return (AE_NO_MEMORY);
248efcc2a30SJung-uk Kim }
249efcc2a30SJung-uk Kim
250efcc2a30SJung-uk Kim /* Walk the entire parse tree */
251efcc2a30SJung-uk Kim
2526f1f1a63SJung-uk Kim TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
253f8146b88SJung-uk Kim XfNamespaceLocateBegin, XfNamespaceLocateEnd, WalkState);
254313a0c13SJung-uk Kim
255313a0c13SJung-uk Kim ACPI_FREE (WalkState);
256efcc2a30SJung-uk Kim return (AE_OK);
257efcc2a30SJung-uk Kim }
258efcc2a30SJung-uk Kim
259efcc2a30SJung-uk Kim
260efcc2a30SJung-uk Kim /*******************************************************************************
261efcc2a30SJung-uk Kim *
262efcc2a30SJung-uk Kim * FUNCTION: XfObjectExists
263efcc2a30SJung-uk Kim *
264efcc2a30SJung-uk Kim * PARAMETERS: Name - 4 char ACPI name
265efcc2a30SJung-uk Kim *
266efcc2a30SJung-uk Kim * RETURN: TRUE if name exists in namespace
267efcc2a30SJung-uk Kim *
268efcc2a30SJung-uk Kim * DESCRIPTION: Walk the namespace to find an object
269efcc2a30SJung-uk Kim *
270efcc2a30SJung-uk Kim ******************************************************************************/
271efcc2a30SJung-uk Kim
272efcc2a30SJung-uk Kim static BOOLEAN
XfObjectExists(char * Name)273efcc2a30SJung-uk Kim XfObjectExists (
274efcc2a30SJung-uk Kim char *Name)
275efcc2a30SJung-uk Kim {
276efcc2a30SJung-uk Kim ACPI_STATUS Status;
277efcc2a30SJung-uk Kim
278efcc2a30SJung-uk Kim
279efcc2a30SJung-uk Kim /* Walk entire namespace from the supplied root */
280efcc2a30SJung-uk Kim
281efcc2a30SJung-uk Kim Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
282efcc2a30SJung-uk Kim ACPI_UINT32_MAX, FALSE, XfCompareOneNamespaceObject, NULL,
283efcc2a30SJung-uk Kim Name, NULL);
284efcc2a30SJung-uk Kim if (Status == AE_CTRL_TRUE)
285efcc2a30SJung-uk Kim {
286efcc2a30SJung-uk Kim /* At least one instance of the name was found */
287efcc2a30SJung-uk Kim
288efcc2a30SJung-uk Kim return (TRUE);
289efcc2a30SJung-uk Kim }
290efcc2a30SJung-uk Kim
291efcc2a30SJung-uk Kim return (FALSE);
292efcc2a30SJung-uk Kim }
293efcc2a30SJung-uk Kim
294efcc2a30SJung-uk Kim
295efcc2a30SJung-uk Kim /*******************************************************************************
296efcc2a30SJung-uk Kim *
297efcc2a30SJung-uk Kim * FUNCTION: XfCompareOneNamespaceObject
298efcc2a30SJung-uk Kim *
299efcc2a30SJung-uk Kim * PARAMETERS: ACPI_WALK_CALLBACK
300efcc2a30SJung-uk Kim *
301efcc2a30SJung-uk Kim * RETURN: Status
302efcc2a30SJung-uk Kim *
303efcc2a30SJung-uk Kim * DESCRIPTION: Compare name of one object.
304efcc2a30SJung-uk Kim *
305efcc2a30SJung-uk Kim ******************************************************************************/
306efcc2a30SJung-uk Kim
307efcc2a30SJung-uk Kim static ACPI_STATUS
XfCompareOneNamespaceObject(ACPI_HANDLE ObjHandle,UINT32 Level,void * Context,void ** ReturnValue)308efcc2a30SJung-uk Kim XfCompareOneNamespaceObject (
309efcc2a30SJung-uk Kim ACPI_HANDLE ObjHandle,
310efcc2a30SJung-uk Kim UINT32 Level,
311efcc2a30SJung-uk Kim void *Context,
312efcc2a30SJung-uk Kim void **ReturnValue)
313efcc2a30SJung-uk Kim {
314efcc2a30SJung-uk Kim ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
315efcc2a30SJung-uk Kim
316efcc2a30SJung-uk Kim
317efcc2a30SJung-uk Kim /* Simply check the name */
318efcc2a30SJung-uk Kim
319efcc2a30SJung-uk Kim if (*((UINT32 *) (Context)) == Node->Name.Integer)
320efcc2a30SJung-uk Kim {
321efcc2a30SJung-uk Kim /* Abort walk if we found one instance */
322efcc2a30SJung-uk Kim
323efcc2a30SJung-uk Kim return (AE_CTRL_TRUE);
324efcc2a30SJung-uk Kim }
325efcc2a30SJung-uk Kim
326efcc2a30SJung-uk Kim return (AE_OK);
327efcc2a30SJung-uk Kim }
328efcc2a30SJung-uk Kim
329efcc2a30SJung-uk Kim
330efcc2a30SJung-uk Kim /*******************************************************************************
331efcc2a30SJung-uk Kim *
332efcc2a30SJung-uk Kim * FUNCTION: XfCheckFieldRange
333efcc2a30SJung-uk Kim *
334efcc2a30SJung-uk Kim * PARAMETERS: RegionBitLength - Length of entire parent region
335efcc2a30SJung-uk Kim * FieldBitOffset - Start of the field unit (within region)
336efcc2a30SJung-uk Kim * FieldBitLength - Entire length of field unit
337efcc2a30SJung-uk Kim * AccessBitWidth - Access width of the field unit
338efcc2a30SJung-uk Kim *
339efcc2a30SJung-uk Kim * RETURN: None
340efcc2a30SJung-uk Kim *
341efcc2a30SJung-uk Kim * DESCRIPTION: Check one field unit to make sure it fits in the parent
342efcc2a30SJung-uk Kim * op region.
343efcc2a30SJung-uk Kim *
344efcc2a30SJung-uk Kim * Note: AccessBitWidth must be either 8,16,32, or 64
345efcc2a30SJung-uk Kim *
346efcc2a30SJung-uk Kim ******************************************************************************/
347efcc2a30SJung-uk Kim
348efcc2a30SJung-uk Kim static void
XfCheckFieldRange(ACPI_PARSE_OBJECT * Op,UINT32 RegionBitLength,UINT32 FieldBitOffset,UINT32 FieldBitLength,UINT32 AccessBitWidth)349efcc2a30SJung-uk Kim XfCheckFieldRange (
350efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op,
351efcc2a30SJung-uk Kim UINT32 RegionBitLength,
352efcc2a30SJung-uk Kim UINT32 FieldBitOffset,
353efcc2a30SJung-uk Kim UINT32 FieldBitLength,
354efcc2a30SJung-uk Kim UINT32 AccessBitWidth)
355efcc2a30SJung-uk Kim {
356efcc2a30SJung-uk Kim UINT32 FieldEndBitOffset;
357efcc2a30SJung-uk Kim
358efcc2a30SJung-uk Kim
359efcc2a30SJung-uk Kim /*
360efcc2a30SJung-uk Kim * Check each field unit against the region size. The entire
361efcc2a30SJung-uk Kim * field unit (start offset plus length) must fit within the
362efcc2a30SJung-uk Kim * region.
363efcc2a30SJung-uk Kim */
364efcc2a30SJung-uk Kim FieldEndBitOffset = FieldBitOffset + FieldBitLength;
365efcc2a30SJung-uk Kim
366efcc2a30SJung-uk Kim if (FieldEndBitOffset > RegionBitLength)
367efcc2a30SJung-uk Kim {
368efcc2a30SJung-uk Kim /* Field definition itself is beyond the end-of-region */
369efcc2a30SJung-uk Kim
370efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
371efcc2a30SJung-uk Kim return;
372efcc2a30SJung-uk Kim }
373efcc2a30SJung-uk Kim
374efcc2a30SJung-uk Kim /*
375efcc2a30SJung-uk Kim * Now check that the field plus AccessWidth doesn't go beyond
376efcc2a30SJung-uk Kim * the end-of-region. Assumes AccessBitWidth is a power of 2
377efcc2a30SJung-uk Kim */
378efcc2a30SJung-uk Kim FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
379efcc2a30SJung-uk Kim
380efcc2a30SJung-uk Kim if (FieldEndBitOffset > RegionBitLength)
381efcc2a30SJung-uk Kim {
382efcc2a30SJung-uk Kim /* Field definition combined with the access is beyond EOR */
383efcc2a30SJung-uk Kim
384efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
385efcc2a30SJung-uk Kim }
386efcc2a30SJung-uk Kim }
387efcc2a30SJung-uk Kim
388313a0c13SJung-uk Kim
389313a0c13SJung-uk Kim /*******************************************************************************
390313a0c13SJung-uk Kim *
391efcc2a30SJung-uk Kim * FUNCTION: XfNamespaceLocateBegin
392efcc2a30SJung-uk Kim *
393efcc2a30SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK
394efcc2a30SJung-uk Kim *
395efcc2a30SJung-uk Kim * RETURN: Status
396efcc2a30SJung-uk Kim *
397efcc2a30SJung-uk Kim * DESCRIPTION: Descending callback used during cross-reference. For named
398efcc2a30SJung-uk Kim * object references, attempt to locate the name in the
399efcc2a30SJung-uk Kim * namespace.
400efcc2a30SJung-uk Kim *
401efcc2a30SJung-uk Kim * NOTE: ASL references to named fields within resource descriptors are
402efcc2a30SJung-uk Kim * resolved to integer values here. Therefore, this step is an
403efcc2a30SJung-uk Kim * important part of the code generation. We don't know that the
404efcc2a30SJung-uk Kim * name refers to a resource descriptor until now.
405efcc2a30SJung-uk Kim *
406efcc2a30SJung-uk Kim ******************************************************************************/
407efcc2a30SJung-uk Kim
408efcc2a30SJung-uk Kim static ACPI_STATUS
XfNamespaceLocateBegin(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)409efcc2a30SJung-uk Kim XfNamespaceLocateBegin (
410efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op,
411efcc2a30SJung-uk Kim UINT32 Level,
412efcc2a30SJung-uk Kim void *Context)
413efcc2a30SJung-uk Kim {
414efcc2a30SJung-uk Kim ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
415efcc2a30SJung-uk Kim ACPI_NAMESPACE_NODE *Node;
416efcc2a30SJung-uk Kim ACPI_STATUS Status;
417efcc2a30SJung-uk Kim ACPI_OBJECT_TYPE ObjectType;
418efcc2a30SJung-uk Kim char *Path;
419efcc2a30SJung-uk Kim UINT8 PassedArgs;
420efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *NextOp;
421efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *OwningOp;
422efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *SpaceIdOp;
423efcc2a30SJung-uk Kim UINT32 MinimumLength;
424efcc2a30SJung-uk Kim UINT32 Offset;
425efcc2a30SJung-uk Kim UINT32 FieldBitLength;
426efcc2a30SJung-uk Kim UINT32 TagBitLength;
427efcc2a30SJung-uk Kim UINT8 Message = 0;
428efcc2a30SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo;
429efcc2a30SJung-uk Kim UINT32 Flags;
430fe0f0bbbSJung-uk Kim ASL_METHOD_LOCAL *MethodLocals = NULL;
431fe0f0bbbSJung-uk Kim ASL_METHOD_LOCAL *MethodArgs = NULL;
432fe0f0bbbSJung-uk Kim int RegisterNumber;
433fe0f0bbbSJung-uk Kim UINT32 i;
4349ad8b64eSJung-uk Kim ACPI_NAMESPACE_NODE *DeclarationParentMethod;
4359ad8b64eSJung-uk Kim ACPI_PARSE_OBJECT *ReferenceParentMethod;
436f15e9afbSJung-uk Kim char *ExternalPath;
437efcc2a30SJung-uk Kim
438efcc2a30SJung-uk Kim
439efcc2a30SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (XfNamespaceLocateBegin, Op);
440efcc2a30SJung-uk Kim
441fe0f0bbbSJung-uk Kim
442fe0f0bbbSJung-uk Kim if ((Op->Asl.AmlOpcode == AML_METHOD_OP) && Op->Asl.Node)
443fe0f0bbbSJung-uk Kim {
444fe0f0bbbSJung-uk Kim Node = Op->Asl.Node;
445fe0f0bbbSJung-uk Kim
446fe0f0bbbSJung-uk Kim /* Support for method LocalX/ArgX analysis */
447fe0f0bbbSJung-uk Kim
448fe0f0bbbSJung-uk Kim if (!Node->MethodLocals)
449fe0f0bbbSJung-uk Kim {
450fe0f0bbbSJung-uk Kim /* Create local/arg info blocks */
451fe0f0bbbSJung-uk Kim
452fe0f0bbbSJung-uk Kim MethodLocals = UtLocalCalloc (
453fe0f0bbbSJung-uk Kim sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_LOCALS);
454fe0f0bbbSJung-uk Kim Node->MethodLocals = MethodLocals;
455fe0f0bbbSJung-uk Kim
456fe0f0bbbSJung-uk Kim MethodArgs = UtLocalCalloc (
457fe0f0bbbSJung-uk Kim sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_ARGS);
458fe0f0bbbSJung-uk Kim Node->MethodArgs = MethodArgs;
459fe0f0bbbSJung-uk Kim
460fe0f0bbbSJung-uk Kim /*
461fe0f0bbbSJung-uk Kim * Get the method argument count
462fe0f0bbbSJung-uk Kim * First, get the name node
463fe0f0bbbSJung-uk Kim */
464fe0f0bbbSJung-uk Kim NextOp = Op->Asl.Child;
465fe0f0bbbSJung-uk Kim
466fe0f0bbbSJung-uk Kim /* Get the NumArguments node */
467fe0f0bbbSJung-uk Kim
468fe0f0bbbSJung-uk Kim NextOp = NextOp->Asl.Next;
469fe0f0bbbSJung-uk Kim Node->ArgCount = (UINT8)
470fe0f0bbbSJung-uk Kim (((UINT8) NextOp->Asl.Value.Integer) & 0x07);
471fe0f0bbbSJung-uk Kim
472cd6518c7SJung-uk Kim /* We will track all possible ArgXs */
473fe0f0bbbSJung-uk Kim
474fe0f0bbbSJung-uk Kim for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
475fe0f0bbbSJung-uk Kim {
476fe0f0bbbSJung-uk Kim if (i < Node->ArgCount)
477fe0f0bbbSJung-uk Kim {
478fe0f0bbbSJung-uk Kim /* Real Args are always "initialized" */
479fe0f0bbbSJung-uk Kim
480fe0f0bbbSJung-uk Kim MethodArgs[i].Flags = ASL_ARG_INITIALIZED;
481fe0f0bbbSJung-uk Kim }
482fe0f0bbbSJung-uk Kim else
483fe0f0bbbSJung-uk Kim {
484fe0f0bbbSJung-uk Kim /* Other ArgXs can be used as locals */
485fe0f0bbbSJung-uk Kim
486fe0f0bbbSJung-uk Kim MethodArgs[i].Flags = ASL_ARG_IS_LOCAL;
487fe0f0bbbSJung-uk Kim }
488fe0f0bbbSJung-uk Kim
489fe0f0bbbSJung-uk Kim MethodArgs[i].Op = Op;
490fe0f0bbbSJung-uk Kim }
491fe0f0bbbSJung-uk Kim }
492fe0f0bbbSJung-uk Kim }
493fe0f0bbbSJung-uk Kim
494efcc2a30SJung-uk Kim /*
495efcc2a30SJung-uk Kim * If this node is the actual declaration of a name
496efcc2a30SJung-uk Kim * [such as the XXXX name in "Method (XXXX)"],
497efcc2a30SJung-uk Kim * we are not interested in it here. We only care about names that are
498efcc2a30SJung-uk Kim * references to other objects within the namespace and the parent objects
499efcc2a30SJung-uk Kim * of name declarations
500efcc2a30SJung-uk Kim */
5015f9b24faSJung-uk Kim if (Op->Asl.CompileFlags & OP_IS_NAME_DECLARATION)
502efcc2a30SJung-uk Kim {
503313a0c13SJung-uk Kim return_ACPI_STATUS (AE_OK);
504efcc2a30SJung-uk Kim }
505efcc2a30SJung-uk Kim
506efcc2a30SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
507efcc2a30SJung-uk Kim
508fe0f0bbbSJung-uk Kim /* Check method LocalX variables */
509fe0f0bbbSJung-uk Kim
510fe0f0bbbSJung-uk Kim if (OpInfo->Type == AML_TYPE_LOCAL_VARIABLE)
511fe0f0bbbSJung-uk Kim {
512fe0f0bbbSJung-uk Kim /* Find parent method Op */
513fe0f0bbbSJung-uk Kim
514ec0234b4SJung-uk Kim NextOp = UtGetParentMethodOp (Op);
515fe0f0bbbSJung-uk Kim if (!NextOp)
516fe0f0bbbSJung-uk Kim {
517fe0f0bbbSJung-uk Kim return_ACPI_STATUS (AE_OK);
518fe0f0bbbSJung-uk Kim }
519fe0f0bbbSJung-uk Kim
520fe0f0bbbSJung-uk Kim /* Get method node */
521fe0f0bbbSJung-uk Kim
522fe0f0bbbSJung-uk Kim Node = NextOp->Asl.Node;
523fe0f0bbbSJung-uk Kim
524fe0f0bbbSJung-uk Kim RegisterNumber = Op->Asl.AmlOpcode & 0x0007; /* 0x60 through 0x67 */
525fe0f0bbbSJung-uk Kim MethodLocals = Node->MethodLocals;
526fe0f0bbbSJung-uk Kim
5275f9b24faSJung-uk Kim if (Op->Asl.CompileFlags & OP_IS_TARGET)
528fe0f0bbbSJung-uk Kim {
529fe0f0bbbSJung-uk Kim /* Local is being initialized */
530fe0f0bbbSJung-uk Kim
531fe0f0bbbSJung-uk Kim MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_INITIALIZED;
532fe0f0bbbSJung-uk Kim MethodLocals[RegisterNumber].Op = Op;
533fe0f0bbbSJung-uk Kim
534fe0f0bbbSJung-uk Kim return_ACPI_STATUS (AE_OK);
535fe0f0bbbSJung-uk Kim }
536fe0f0bbbSJung-uk Kim
537fe0f0bbbSJung-uk Kim /* Mark this Local as referenced */
538fe0f0bbbSJung-uk Kim
539fe0f0bbbSJung-uk Kim MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_REFERENCED;
540fe0f0bbbSJung-uk Kim MethodLocals[RegisterNumber].Op = Op;
541fe0f0bbbSJung-uk Kim
542fe0f0bbbSJung-uk Kim return_ACPI_STATUS (AE_OK);
543fe0f0bbbSJung-uk Kim }
544fe0f0bbbSJung-uk Kim
545fe0f0bbbSJung-uk Kim /* Check method ArgX variables */
546fe0f0bbbSJung-uk Kim
547fe0f0bbbSJung-uk Kim if (OpInfo->Type == AML_TYPE_METHOD_ARGUMENT)
548fe0f0bbbSJung-uk Kim {
549fe0f0bbbSJung-uk Kim /* Find parent method Op */
550fe0f0bbbSJung-uk Kim
551ec0234b4SJung-uk Kim NextOp = UtGetParentMethodOp (Op);
552fe0f0bbbSJung-uk Kim if (!NextOp)
553fe0f0bbbSJung-uk Kim {
554fe0f0bbbSJung-uk Kim return_ACPI_STATUS (AE_OK);
555fe0f0bbbSJung-uk Kim }
556fe0f0bbbSJung-uk Kim
557fe0f0bbbSJung-uk Kim /* Get method node */
558fe0f0bbbSJung-uk Kim
559fe0f0bbbSJung-uk Kim Node = NextOp->Asl.Node;
560fe0f0bbbSJung-uk Kim
561fe0f0bbbSJung-uk Kim /* Get Arg # */
562fe0f0bbbSJung-uk Kim
563fe0f0bbbSJung-uk Kim RegisterNumber = Op->Asl.AmlOpcode - AML_ARG0; /* 0x68 through 0x6F */
564fe0f0bbbSJung-uk Kim MethodArgs = Node->MethodArgs;
565fe0f0bbbSJung-uk Kim
56661673a1fSJung-uk Kim /* Mark this Arg as referenced */
56761673a1fSJung-uk Kim
56861673a1fSJung-uk Kim MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED;
56961673a1fSJung-uk Kim MethodArgs[RegisterNumber].Op = Op;
57061673a1fSJung-uk Kim
5715f9b24faSJung-uk Kim if (Op->Asl.CompileFlags & OP_IS_TARGET)
572fe0f0bbbSJung-uk Kim {
573fe0f0bbbSJung-uk Kim /* Arg is being initialized */
574fe0f0bbbSJung-uk Kim
575fe0f0bbbSJung-uk Kim MethodArgs[RegisterNumber].Flags |= ASL_ARG_INITIALIZED;
576fe0f0bbbSJung-uk Kim }
577fe0f0bbbSJung-uk Kim
578fe0f0bbbSJung-uk Kim return_ACPI_STATUS (AE_OK);
579fe0f0bbbSJung-uk Kim }
580fe0f0bbbSJung-uk Kim
581fe0f0bbbSJung-uk Kim /*
582fe0f0bbbSJung-uk Kim * After method ArgX and LocalX, we are only interested in opcodes
583fe0f0bbbSJung-uk Kim * that have an associated name
584fe0f0bbbSJung-uk Kim */
585efcc2a30SJung-uk Kim if ((!(OpInfo->Flags & AML_NAMED)) &&
586efcc2a30SJung-uk Kim (!(OpInfo->Flags & AML_CREATE)) &&
587efcc2a30SJung-uk Kim (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
588efcc2a30SJung-uk Kim (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
589af051161SJung-uk Kim (Op->Asl.ParseOpcode != PARSEOP_METHODCALL) &&
5909ad8b64eSJung-uk Kim (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
591efcc2a30SJung-uk Kim {
592313a0c13SJung-uk Kim return_ACPI_STATUS (AE_OK);
593efcc2a30SJung-uk Kim }
594efcc2a30SJung-uk Kim
595efcc2a30SJung-uk Kim /*
596efcc2a30SJung-uk Kim * We must enable the "search-to-root" for single NameSegs, but
597efcc2a30SJung-uk Kim * we have to be very careful about opening up scopes
598efcc2a30SJung-uk Kim */
599efcc2a30SJung-uk Kim Flags = ACPI_NS_SEARCH_PARENT;
600efcc2a30SJung-uk Kim if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
601efcc2a30SJung-uk Kim (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
602af051161SJung-uk Kim (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
60308ddfe86SJung-uk Kim (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) ||
60408ddfe86SJung-uk Kim (Op->Asl.ParseOpcode == PARSEOP_CONDREFOF))
605efcc2a30SJung-uk Kim {
606efcc2a30SJung-uk Kim /*
607efcc2a30SJung-uk Kim * These are name references, do not push the scope stack
608efcc2a30SJung-uk Kim * for them.
609efcc2a30SJung-uk Kim */
610efcc2a30SJung-uk Kim Flags |= ACPI_NS_DONT_OPEN_SCOPE;
611efcc2a30SJung-uk Kim }
612efcc2a30SJung-uk Kim
613efcc2a30SJung-uk Kim /* Get the NamePath from the appropriate place */
614efcc2a30SJung-uk Kim
615efcc2a30SJung-uk Kim if (OpInfo->Flags & AML_NAMED)
616efcc2a30SJung-uk Kim {
617efcc2a30SJung-uk Kim /* For nearly all NAMED operators, the name reference is the first child */
618efcc2a30SJung-uk Kim
619efcc2a30SJung-uk Kim Path = Op->Asl.Child->Asl.Value.String;
620efcc2a30SJung-uk Kim if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
621efcc2a30SJung-uk Kim {
622efcc2a30SJung-uk Kim /*
623efcc2a30SJung-uk Kim * ALIAS is the only oddball opcode, the name declaration
624efcc2a30SJung-uk Kim * (alias name) is the second operand
625efcc2a30SJung-uk Kim */
626efcc2a30SJung-uk Kim Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
627efcc2a30SJung-uk Kim }
628efcc2a30SJung-uk Kim }
629efcc2a30SJung-uk Kim else if (OpInfo->Flags & AML_CREATE)
630efcc2a30SJung-uk Kim {
631efcc2a30SJung-uk Kim /* Name must appear as the last parameter */
632efcc2a30SJung-uk Kim
633efcc2a30SJung-uk Kim NextOp = Op->Asl.Child;
6345f9b24faSJung-uk Kim while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION))
635efcc2a30SJung-uk Kim {
636efcc2a30SJung-uk Kim NextOp = NextOp->Asl.Next;
637efcc2a30SJung-uk Kim }
638f8146b88SJung-uk Kim
639efcc2a30SJung-uk Kim Path = NextOp->Asl.Value.String;
640efcc2a30SJung-uk Kim }
641efcc2a30SJung-uk Kim else
642efcc2a30SJung-uk Kim {
643efcc2a30SJung-uk Kim Path = Op->Asl.Value.String;
644efcc2a30SJung-uk Kim }
645efcc2a30SJung-uk Kim
646efcc2a30SJung-uk Kim ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
647efcc2a30SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
648efcc2a30SJung-uk Kim "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
649efcc2a30SJung-uk Kim
650efcc2a30SJung-uk Kim /*
651efcc2a30SJung-uk Kim * Lookup the name in the namespace. Name must exist at this point, or it
652efcc2a30SJung-uk Kim * is an invalid reference.
653efcc2a30SJung-uk Kim *
654efcc2a30SJung-uk Kim * The namespace is also used as a lookup table for references to resource
655efcc2a30SJung-uk Kim * descriptors and the fields within them.
656efcc2a30SJung-uk Kim */
6576f1f1a63SJung-uk Kim AslGbl_NsLookupCount++;
658efcc2a30SJung-uk Kim
659efcc2a30SJung-uk Kim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
660835b56bfSJung-uk Kim ACPI_IMODE_EXECUTE, Flags, WalkState, &Node);
661efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status))
662efcc2a30SJung-uk Kim {
663efcc2a30SJung-uk Kim if (Status == AE_NOT_FOUND)
664efcc2a30SJung-uk Kim {
665efcc2a30SJung-uk Kim /*
666efcc2a30SJung-uk Kim * We didn't find the name reference by path -- we can qualify this
667efcc2a30SJung-uk Kim * a little better before we print an error message
668efcc2a30SJung-uk Kim */
66908ddfe86SJung-uk Kim
67008ddfe86SJung-uk Kim if ((Op->Asl.Parent) &&
67108ddfe86SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
67208ddfe86SJung-uk Kim {
67308ddfe86SJung-uk Kim /*
67408ddfe86SJung-uk Kim * One special case: CondRefOf operator - if the name doesn't
67508ddfe86SJung-uk Kim * exist at this point, it means that there's no actual or
67608ddfe86SJung-uk Kim * external declaration. If the name is not found, just ignore
67708ddfe86SJung-uk Kim * it, the point of the operator is to determine if the name
67808ddfe86SJung-uk Kim * exists at runtime. We wanted to see if this named object
67908ddfe86SJung-uk Kim * exists to facilitate analysis to allow protected usage of
68008ddfe86SJung-uk Kim * undeclared externals.
68108ddfe86SJung-uk Kim */
68208ddfe86SJung-uk Kim return_ACPI_STATUS (AE_OK);
68308ddfe86SJung-uk Kim }
68408ddfe86SJung-uk Kim else if (strlen (Path) == ACPI_NAMESEG_SIZE)
685efcc2a30SJung-uk Kim {
686efcc2a30SJung-uk Kim /* A simple, one-segment ACPI name */
687efcc2a30SJung-uk Kim
688efcc2a30SJung-uk Kim if (XfObjectExists (Path))
689efcc2a30SJung-uk Kim {
690efcc2a30SJung-uk Kim /*
691efcc2a30SJung-uk Kim * There exists such a name, but we couldn't get to it
692efcc2a30SJung-uk Kim * from this scope
693efcc2a30SJung-uk Kim */
694efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
695efcc2a30SJung-uk Kim Op->Asl.ExternalName);
696efcc2a30SJung-uk Kim }
697efcc2a30SJung-uk Kim else
698efcc2a30SJung-uk Kim {
699efcc2a30SJung-uk Kim /* The name doesn't exist, period */
700efcc2a30SJung-uk Kim
701efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
702efcc2a30SJung-uk Kim Op, Op->Asl.ExternalName);
703efcc2a30SJung-uk Kim }
704efcc2a30SJung-uk Kim }
705efcc2a30SJung-uk Kim else
706efcc2a30SJung-uk Kim {
7074a38ee6dSJung-uk Kim /* The NamePath contains multiple NameSegs */
708efcc2a30SJung-uk Kim
7094a38ee6dSJung-uk Kim if ((OpInfo->Flags & AML_CREATE) ||
7104a38ee6dSJung-uk Kim (OpInfo->ObjectType == ACPI_TYPE_LOCAL_ALIAS))
711efcc2a30SJung-uk Kim {
7124a38ee6dSJung-uk Kim /*
7134a38ee6dSJung-uk Kim * The new name is the last parameter. For the
7144a38ee6dSJung-uk Kim * CreateXXXXField and Alias operators
7154a38ee6dSJung-uk Kim */
7164a38ee6dSJung-uk Kim NextOp = Op->Asl.Child;
7174a38ee6dSJung-uk Kim while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION))
7184a38ee6dSJung-uk Kim {
7194a38ee6dSJung-uk Kim NextOp = NextOp->Asl.Next;
7204a38ee6dSJung-uk Kim }
7214a38ee6dSJung-uk Kim
7224a38ee6dSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, NextOp,
7234a38ee6dSJung-uk Kim NextOp->Asl.ExternalName);
7244a38ee6dSJung-uk Kim }
7254a38ee6dSJung-uk Kim else if (OpInfo->Flags & AML_NAMED)
7264a38ee6dSJung-uk Kim {
7274a38ee6dSJung-uk Kim /* The new name is the first parameter */
7284a38ee6dSJung-uk Kim
7294a38ee6dSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, Op,
7304a38ee6dSJung-uk Kim Op->Asl.ExternalName);
7314a38ee6dSJung-uk Kim }
7324a38ee6dSJung-uk Kim else if (Path[0] == AML_ROOT_PREFIX)
7334a38ee6dSJung-uk Kim {
7344a38ee6dSJung-uk Kim /* Full namepath from root, the object does not exist */
735efcc2a30SJung-uk Kim
736efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
737efcc2a30SJung-uk Kim Op->Asl.ExternalName);
738efcc2a30SJung-uk Kim }
739efcc2a30SJung-uk Kim else
740efcc2a30SJung-uk Kim {
741efcc2a30SJung-uk Kim /*
7424a38ee6dSJung-uk Kim * Generic "not found" error. Cannot determine whether it
7434a38ee6dSJung-uk Kim * doesn't exist or just can't be reached. However, we
7444a38ee6dSJung-uk Kim * can differentiate between a NameSeg vs. NamePath.
745efcc2a30SJung-uk Kim */
746278f0de6SJung-uk Kim if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
7474a38ee6dSJung-uk Kim {
748efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
749efcc2a30SJung-uk Kim Op->Asl.ExternalName);
750efcc2a30SJung-uk Kim }
7514a38ee6dSJung-uk Kim else
7524a38ee6dSJung-uk Kim {
7534a38ee6dSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
7544a38ee6dSJung-uk Kim Op->Asl.ExternalName);
7554a38ee6dSJung-uk Kim }
7564a38ee6dSJung-uk Kim }
757efcc2a30SJung-uk Kim }
758efcc2a30SJung-uk Kim
759efcc2a30SJung-uk Kim Status = AE_OK;
760efcc2a30SJung-uk Kim }
761313a0c13SJung-uk Kim
762313a0c13SJung-uk Kim return_ACPI_STATUS (Status);
763efcc2a30SJung-uk Kim }
764efcc2a30SJung-uk Kim
765cd6518c7SJung-uk Kim /* Check for an attempt to access an object in another method */
766cd6518c7SJung-uk Kim
767cd6518c7SJung-uk Kim if (!XfValidateCrossReference (Op, OpInfo, Node))
768cd6518c7SJung-uk Kim {
769cd6518c7SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_TEMPORARY_OBJECT, Op,
770cd6518c7SJung-uk Kim Op->Asl.ExternalName);
771cd6518c7SJung-uk Kim return_ACPI_STATUS (Status);
772cd6518c7SJung-uk Kim }
773cd6518c7SJung-uk Kim
774835b56bfSJung-uk Kim /* Object was found above, check for an illegal forward reference */
775835b56bfSJung-uk Kim
776835b56bfSJung-uk Kim if (Op->Asl.CompileFlags & OP_NOT_FOUND_DURING_LOAD)
777835b56bfSJung-uk Kim {
778835b56bfSJung-uk Kim /*
779835b56bfSJung-uk Kim * During the load phase, this Op was flagged as a possible
7809ad8b64eSJung-uk Kim * illegal forward reference. In other words, Op is a name path or
7819ad8b64eSJung-uk Kim * name segment that refers to a named object declared after the
7829ad8b64eSJung-uk Kim * reference. In this scinario, Node refers to the actual declaration
7839ad8b64eSJung-uk Kim * and Op is a parse node that references the named object.
784835b56bfSJung-uk Kim *
7859ad8b64eSJung-uk Kim * Note:
7869ad8b64eSJung-uk Kim *
7879ad8b64eSJung-uk Kim * Object references inside of control methods are allowed to
7889ad8b64eSJung-uk Kim * refer to objects declared outside of control methods.
7899ad8b64eSJung-uk Kim *
7909ad8b64eSJung-uk Kim * If the declaration and reference are both contained inside of the
7919ad8b64eSJung-uk Kim * same method or outside of any method, this is a forward reference
7929ad8b64eSJung-uk Kim * and should be reported as a compiler error.
793835b56bfSJung-uk Kim */
794ec0234b4SJung-uk Kim DeclarationParentMethod = UtGetParentMethodNode (Node);
795ec0234b4SJung-uk Kim ReferenceParentMethod = UtGetParentMethodOp (Op);
7969ad8b64eSJung-uk Kim
797ec0234b4SJung-uk Kim /* case 1: declaration and reference are both outside of method */
7989ad8b64eSJung-uk Kim
7999ad8b64eSJung-uk Kim if (!ReferenceParentMethod && !DeclarationParentMethod)
8009ad8b64eSJung-uk Kim {
8019ad8b64eSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
8029ad8b64eSJung-uk Kim Op->Asl.ExternalName);
8039ad8b64eSJung-uk Kim }
8049ad8b64eSJung-uk Kim
8059ad8b64eSJung-uk Kim /* case 2: declaration and reference are both inside of the same method */
8069ad8b64eSJung-uk Kim
8079ad8b64eSJung-uk Kim else if (ReferenceParentMethod && DeclarationParentMethod &&
8089ad8b64eSJung-uk Kim ReferenceParentMethod == DeclarationParentMethod->Op)
809835b56bfSJung-uk Kim {
810835b56bfSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
811835b56bfSJung-uk Kim Op->Asl.ExternalName);
812835b56bfSJung-uk Kim }
813835b56bfSJung-uk Kim }
814835b56bfSJung-uk Kim
815efcc2a30SJung-uk Kim /* Check for a reference vs. name declaration */
816efcc2a30SJung-uk Kim
817efcc2a30SJung-uk Kim if (!(OpInfo->Flags & AML_NAMED) &&
818efcc2a30SJung-uk Kim !(OpInfo->Flags & AML_CREATE))
819efcc2a30SJung-uk Kim {
820efcc2a30SJung-uk Kim /* This node has been referenced, mark it for reference check */
821efcc2a30SJung-uk Kim
822efcc2a30SJung-uk Kim Node->Flags |= ANOBJ_IS_REFERENCED;
823efcc2a30SJung-uk Kim }
824efcc2a30SJung-uk Kim
8250b229c80SJung-uk Kim /*
8260b229c80SJung-uk Kim * Attempt to optimize the NamePath
8270b229c80SJung-uk Kim *
8280b229c80SJung-uk Kim * One special case: CondRefOf operator - not all AML interpreter
8290b229c80SJung-uk Kim * implementations expect optimized namepaths as a parameter to this
8300b229c80SJung-uk Kim * operator. They require relative name paths with prefix operators or
8310b229c80SJung-uk Kim * namepaths starting with the root scope.
8320b229c80SJung-uk Kim *
8330b229c80SJung-uk Kim * Other AML interpreter implementations do not perform the namespace
8340b229c80SJung-uk Kim * search that starts at the current scope and recursively searching the
8350b229c80SJung-uk Kim * parent scope until the root scope. The lack of search is only known to
8360b229c80SJung-uk Kim * occur for the namestring parameter for the CondRefOf operator.
8370b229c80SJung-uk Kim */
8380b229c80SJung-uk Kim if ((Op->Asl.Parent) &&
8390b229c80SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_CONDREFOF))
8400b229c80SJung-uk Kim {
841efcc2a30SJung-uk Kim OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
8420b229c80SJung-uk Kim }
843efcc2a30SJung-uk Kim
844efcc2a30SJung-uk Kim /*
845efcc2a30SJung-uk Kim * 1) Dereference an alias (A name reference that is an alias)
846efcc2a30SJung-uk Kim * Aliases are not nested, the alias always points to the final object
847efcc2a30SJung-uk Kim */
848efcc2a30SJung-uk Kim if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
849efcc2a30SJung-uk Kim (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
850efcc2a30SJung-uk Kim {
851efcc2a30SJung-uk Kim /* This node points back to the original PARSEOP_ALIAS */
852efcc2a30SJung-uk Kim
853efcc2a30SJung-uk Kim NextOp = Node->Op;
854efcc2a30SJung-uk Kim
855efcc2a30SJung-uk Kim /* The first child is the alias target op */
856efcc2a30SJung-uk Kim
857efcc2a30SJung-uk Kim NextOp = NextOp->Asl.Child;
858efcc2a30SJung-uk Kim
859efcc2a30SJung-uk Kim /* That in turn points back to original target alias node */
860efcc2a30SJung-uk Kim
861efcc2a30SJung-uk Kim if (NextOp->Asl.Node)
862efcc2a30SJung-uk Kim {
863efcc2a30SJung-uk Kim Node = NextOp->Asl.Node;
864efcc2a30SJung-uk Kim }
865efcc2a30SJung-uk Kim
866efcc2a30SJung-uk Kim /* Else - forward reference to alias, will be resolved later */
867efcc2a30SJung-uk Kim }
868efcc2a30SJung-uk Kim
869efcc2a30SJung-uk Kim /* 2) Check for a reference to a resource descriptor */
870efcc2a30SJung-uk Kim
871efcc2a30SJung-uk Kim if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
872efcc2a30SJung-uk Kim (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
873efcc2a30SJung-uk Kim {
874efcc2a30SJung-uk Kim /*
875efcc2a30SJung-uk Kim * This was a reference to a field within a resource descriptor.
876efcc2a30SJung-uk Kim * Extract the associated field offset (either a bit or byte
877efcc2a30SJung-uk Kim * offset depending on the field type) and change the named
878efcc2a30SJung-uk Kim * reference into an integer for AML code generation
879efcc2a30SJung-uk Kim */
880efcc2a30SJung-uk Kim Offset = Node->Value;
881efcc2a30SJung-uk Kim TagBitLength = Node->Length;
882efcc2a30SJung-uk Kim
883efcc2a30SJung-uk Kim /*
884efcc2a30SJung-uk Kim * If a field is being created, generate the length (in bits) of
885efcc2a30SJung-uk Kim * the field. Note: Opcodes other than CreateXxxField and Index
886efcc2a30SJung-uk Kim * can come through here. For other opcodes, we just need to
887efcc2a30SJung-uk Kim * convert the resource tag reference to an integer offset.
888efcc2a30SJung-uk Kim */
889efcc2a30SJung-uk Kim switch (Op->Asl.Parent->Asl.AmlOpcode)
890efcc2a30SJung-uk Kim {
891efcc2a30SJung-uk Kim case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */
892efcc2a30SJung-uk Kim /*
893efcc2a30SJung-uk Kim * We know the length operand is an integer constant because
894efcc2a30SJung-uk Kim * we know that it contains a reference to a resource
895efcc2a30SJung-uk Kim * descriptor tag.
896efcc2a30SJung-uk Kim */
897efcc2a30SJung-uk Kim FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer;
898efcc2a30SJung-uk Kim break;
899efcc2a30SJung-uk Kim
900efcc2a30SJung-uk Kim case AML_CREATE_BIT_FIELD_OP:
901a9d8d09cSJung-uk Kim
902efcc2a30SJung-uk Kim FieldBitLength = 1;
903efcc2a30SJung-uk Kim break;
904efcc2a30SJung-uk Kim
905efcc2a30SJung-uk Kim case AML_CREATE_BYTE_FIELD_OP:
906efcc2a30SJung-uk Kim case AML_INDEX_OP:
907a9d8d09cSJung-uk Kim
908efcc2a30SJung-uk Kim FieldBitLength = 8;
909efcc2a30SJung-uk Kim break;
910efcc2a30SJung-uk Kim
911efcc2a30SJung-uk Kim case AML_CREATE_WORD_FIELD_OP:
912a9d8d09cSJung-uk Kim
913efcc2a30SJung-uk Kim FieldBitLength = 16;
914efcc2a30SJung-uk Kim break;
915efcc2a30SJung-uk Kim
916efcc2a30SJung-uk Kim case AML_CREATE_DWORD_FIELD_OP:
917a9d8d09cSJung-uk Kim
918efcc2a30SJung-uk Kim FieldBitLength = 32;
919efcc2a30SJung-uk Kim break;
920efcc2a30SJung-uk Kim
921efcc2a30SJung-uk Kim case AML_CREATE_QWORD_FIELD_OP:
922a9d8d09cSJung-uk Kim
923efcc2a30SJung-uk Kim FieldBitLength = 64;
924efcc2a30SJung-uk Kim break;
925efcc2a30SJung-uk Kim
926efcc2a30SJung-uk Kim default:
927a9d8d09cSJung-uk Kim
928efcc2a30SJung-uk Kim FieldBitLength = 0;
929efcc2a30SJung-uk Kim break;
930efcc2a30SJung-uk Kim }
931efcc2a30SJung-uk Kim
932efcc2a30SJung-uk Kim /* Check the field length against the length of the resource tag */
933efcc2a30SJung-uk Kim
934efcc2a30SJung-uk Kim if (FieldBitLength)
935efcc2a30SJung-uk Kim {
936efcc2a30SJung-uk Kim if (TagBitLength < FieldBitLength)
937efcc2a30SJung-uk Kim {
938efcc2a30SJung-uk Kim Message = ASL_MSG_TAG_SMALLER;
939efcc2a30SJung-uk Kim }
940efcc2a30SJung-uk Kim else if (TagBitLength > FieldBitLength)
941efcc2a30SJung-uk Kim {
942efcc2a30SJung-uk Kim Message = ASL_MSG_TAG_LARGER;
943efcc2a30SJung-uk Kim }
944efcc2a30SJung-uk Kim
945efcc2a30SJung-uk Kim if (Message)
946efcc2a30SJung-uk Kim {
9476f1f1a63SJung-uk Kim sprintf (AslGbl_MsgBuffer,
948f8146b88SJung-uk Kim "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
949efcc2a30SJung-uk Kim TagBitLength, (TagBitLength > 1) ? "s" : "",
950efcc2a30SJung-uk Kim FieldBitLength, (FieldBitLength > 1) ? "s" : "");
951efcc2a30SJung-uk Kim
9526f1f1a63SJung-uk Kim AslError (ASL_WARNING, Message, Op, AslGbl_MsgBuffer);
953efcc2a30SJung-uk Kim }
954efcc2a30SJung-uk Kim }
955efcc2a30SJung-uk Kim
956efcc2a30SJung-uk Kim /* Convert the BitOffset to a ByteOffset for certain opcodes */
957efcc2a30SJung-uk Kim
958efcc2a30SJung-uk Kim switch (Op->Asl.Parent->Asl.AmlOpcode)
959efcc2a30SJung-uk Kim {
960efcc2a30SJung-uk Kim case AML_CREATE_BYTE_FIELD_OP:
961efcc2a30SJung-uk Kim case AML_CREATE_WORD_FIELD_OP:
962efcc2a30SJung-uk Kim case AML_CREATE_DWORD_FIELD_OP:
963efcc2a30SJung-uk Kim case AML_CREATE_QWORD_FIELD_OP:
964efcc2a30SJung-uk Kim case AML_INDEX_OP:
965efcc2a30SJung-uk Kim
966efcc2a30SJung-uk Kim Offset = ACPI_DIV_8 (Offset);
967efcc2a30SJung-uk Kim break;
968efcc2a30SJung-uk Kim
969efcc2a30SJung-uk Kim default:
970a9d8d09cSJung-uk Kim
971efcc2a30SJung-uk Kim break;
972efcc2a30SJung-uk Kim }
973efcc2a30SJung-uk Kim
974efcc2a30SJung-uk Kim /* Now convert this node to an integer whose value is the field offset */
975efcc2a30SJung-uk Kim
976efcc2a30SJung-uk Kim Op->Asl.AmlLength = 0;
977efcc2a30SJung-uk Kim Op->Asl.ParseOpcode = PARSEOP_INTEGER;
978efcc2a30SJung-uk Kim Op->Asl.Value.Integer = (UINT64) Offset;
9795f9b24faSJung-uk Kim Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD;
980efcc2a30SJung-uk Kim
981efcc2a30SJung-uk Kim OpcGenerateAmlOpcode (Op);
982efcc2a30SJung-uk Kim }
983efcc2a30SJung-uk Kim
984efcc2a30SJung-uk Kim /* 3) Check for a method invocation */
985efcc2a30SJung-uk Kim
986efcc2a30SJung-uk Kim else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
987efcc2a30SJung-uk Kim (Node->Type == ACPI_TYPE_METHOD) &&
988efcc2a30SJung-uk Kim (Op->Asl.Parent) &&
989efcc2a30SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD)) ||
990efcc2a30SJung-uk Kim
991efcc2a30SJung-uk Kim (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
992efcc2a30SJung-uk Kim {
993efcc2a30SJung-uk Kim /*
994efcc2a30SJung-uk Kim * A reference to a method within one of these opcodes is not an
995efcc2a30SJung-uk Kim * invocation of the method, it is simply a reference to the method.
996493deb39SJung-uk Kim *
997493deb39SJung-uk Kim * September 2016: Removed DeRefOf from this list
99861b18036SJung-uk Kim * July 2020: Added Alias to this list
999efcc2a30SJung-uk Kim */
1000efcc2a30SJung-uk Kim if ((Op->Asl.Parent) &&
1001efcc2a30SJung-uk Kim ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF) ||
10021c0e1b6dSJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
10031c0e1b6dSJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)||
100461b18036SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE) ||
100561b18036SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_ALIAS)))
1006efcc2a30SJung-uk Kim {
1007313a0c13SJung-uk Kim return_ACPI_STATUS (AE_OK);
1008efcc2a30SJung-uk Kim }
1009493deb39SJung-uk Kim
1010efcc2a30SJung-uk Kim /*
1011efcc2a30SJung-uk Kim * There are two types of method invocation:
1012efcc2a30SJung-uk Kim * 1) Invocation with arguments -- the parser recognizes this
1013efcc2a30SJung-uk Kim * as a METHODCALL.
1014efcc2a30SJung-uk Kim * 2) Invocation with no arguments --the parser cannot determine that
1015efcc2a30SJung-uk Kim * this is a method invocation, therefore we have to figure it out
1016efcc2a30SJung-uk Kim * here.
1017efcc2a30SJung-uk Kim */
1018efcc2a30SJung-uk Kim if (Node->Type != ACPI_TYPE_METHOD)
1019efcc2a30SJung-uk Kim {
10206f1f1a63SJung-uk Kim sprintf (AslGbl_MsgBuffer, "%s is a %s",
1021efcc2a30SJung-uk Kim Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
1022efcc2a30SJung-uk Kim
10236f1f1a63SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, AslGbl_MsgBuffer);
1024313a0c13SJung-uk Kim return_ACPI_STATUS (AE_OK);
1025efcc2a30SJung-uk Kim }
1026efcc2a30SJung-uk Kim
1027efcc2a30SJung-uk Kim /* Save the method node in the caller's op */
1028efcc2a30SJung-uk Kim
1029efcc2a30SJung-uk Kim Op->Asl.Node = Node;
1030efcc2a30SJung-uk Kim if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
1031efcc2a30SJung-uk Kim {
1032313a0c13SJung-uk Kim return_ACPI_STATUS (AE_OK);
1033efcc2a30SJung-uk Kim }
1034efcc2a30SJung-uk Kim
1035efcc2a30SJung-uk Kim /*
1036efcc2a30SJung-uk Kim * This is a method invocation, with or without arguments.
1037efcc2a30SJung-uk Kim * Count the number of arguments, each appears as a child
1038efcc2a30SJung-uk Kim * under the parent node
1039efcc2a30SJung-uk Kim */
1040efcc2a30SJung-uk Kim Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
1041efcc2a30SJung-uk Kim UtSetParseOpName (Op);
1042efcc2a30SJung-uk Kim
1043efcc2a30SJung-uk Kim PassedArgs = 0;
1044efcc2a30SJung-uk Kim NextOp = Op->Asl.Child;
1045efcc2a30SJung-uk Kim
1046efcc2a30SJung-uk Kim while (NextOp)
1047efcc2a30SJung-uk Kim {
1048efcc2a30SJung-uk Kim PassedArgs++;
1049efcc2a30SJung-uk Kim NextOp = NextOp->Asl.Next;
1050efcc2a30SJung-uk Kim }
1051efcc2a30SJung-uk Kim
1052f9a6772eSJung-uk Kim if (Node->Value != ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS &&
1053f8146b88SJung-uk Kim Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL)
1054efcc2a30SJung-uk Kim {
1055efcc2a30SJung-uk Kim /*
1056efcc2a30SJung-uk Kim * Check the parsed arguments with the number expected by the
1057efcc2a30SJung-uk Kim * method declaration itself
1058efcc2a30SJung-uk Kim */
1059efcc2a30SJung-uk Kim if (PassedArgs != Node->Value)
1060efcc2a30SJung-uk Kim {
1061f9a6772eSJung-uk Kim if (Node->Flags & ANOBJ_IS_EXTERNAL)
1062f9a6772eSJung-uk Kim {
1063f9a6772eSJung-uk Kim sprintf (AslGbl_MsgBuffer,
1064f9a6772eSJung-uk Kim "according to previous use, %s requires %u",
1065f9a6772eSJung-uk Kim Op->Asl.ExternalName, Node->Value);
1066f9a6772eSJung-uk Kim }
1067f9a6772eSJung-uk Kim else
1068f9a6772eSJung-uk Kim {
10696f1f1a63SJung-uk Kim sprintf (AslGbl_MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
1070efcc2a30SJung-uk Kim Node->Value);
1071f9a6772eSJung-uk Kim }
1072efcc2a30SJung-uk Kim
1073efcc2a30SJung-uk Kim if (PassedArgs < Node->Value)
1074efcc2a30SJung-uk Kim {
10756f1f1a63SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, AslGbl_MsgBuffer);
1076efcc2a30SJung-uk Kim }
1077efcc2a30SJung-uk Kim else
1078efcc2a30SJung-uk Kim {
10796f1f1a63SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, AslGbl_MsgBuffer);
1080efcc2a30SJung-uk Kim }
1081efcc2a30SJung-uk Kim }
1082efcc2a30SJung-uk Kim }
1083f9a6772eSJung-uk Kim
1084f9a6772eSJung-uk Kim /*
1085f9a6772eSJung-uk Kim * At this point, a method call to an external method has been
1086f9a6772eSJung-uk Kim * detected. As of 11/19/2019, iASL does not support parameter counts
1087f9a6772eSJung-uk Kim * for methods declared as external. Therefore, save the parameter
1088f9a6772eSJung-uk Kim * count of the first method call and use this count check other
1089f9a6772eSJung-uk Kim * method calls to ensure that the methods are being called with the
1090f9a6772eSJung-uk Kim * same amount of parameters.
1091f9a6772eSJung-uk Kim */
1092f9a6772eSJung-uk Kim else if (Node->Type == ACPI_TYPE_METHOD &&
1093f9a6772eSJung-uk Kim (Node->Flags & ANOBJ_IS_EXTERNAL) &&
1094f9a6772eSJung-uk Kim Node->Value == ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS &&
1095f9a6772eSJung-uk Kim Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL)
1096f9a6772eSJung-uk Kim {
1097f9a6772eSJung-uk Kim Node->Value = PassedArgs;
1098f9a6772eSJung-uk Kim }
1099efcc2a30SJung-uk Kim }
1100efcc2a30SJung-uk Kim
1101efcc2a30SJung-uk Kim /* 4) Check for an ASL Field definition */
1102efcc2a30SJung-uk Kim
1103efcc2a30SJung-uk Kim else if ((Op->Asl.Parent) &&
1104efcc2a30SJung-uk Kim ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD) ||
1105efcc2a30SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
1106efcc2a30SJung-uk Kim {
1107efcc2a30SJung-uk Kim /*
1108efcc2a30SJung-uk Kim * Offset checking for fields. If the parent operation region has a
1109efcc2a30SJung-uk Kim * constant length (known at compile time), we can check fields
1110efcc2a30SJung-uk Kim * defined in that region against the region length. This will catch
1111efcc2a30SJung-uk Kim * fields and field units that cannot possibly fit within the region.
1112efcc2a30SJung-uk Kim *
1113efcc2a30SJung-uk Kim * Note: Index fields do not directly reference an operation region,
1114efcc2a30SJung-uk Kim * thus they are not included in this check.
1115efcc2a30SJung-uk Kim */
1116efcc2a30SJung-uk Kim if (Op == Op->Asl.Parent->Asl.Child)
1117efcc2a30SJung-uk Kim {
1118efcc2a30SJung-uk Kim /*
1119efcc2a30SJung-uk Kim * This is the first child of the field node, which is
1120efcc2a30SJung-uk Kim * the name of the region. Get the parse node for the
1121efcc2a30SJung-uk Kim * region -- which contains the length of the region.
1122efcc2a30SJung-uk Kim */
1123efcc2a30SJung-uk Kim OwningOp = Node->Op;
1124efcc2a30SJung-uk Kim Op->Asl.Parent->Asl.ExtraValue =
1125efcc2a30SJung-uk Kim ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
1126efcc2a30SJung-uk Kim
1127efcc2a30SJung-uk Kim /* Examine the field access width */
1128efcc2a30SJung-uk Kim
1129efcc2a30SJung-uk Kim switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
1130efcc2a30SJung-uk Kim {
1131efcc2a30SJung-uk Kim case AML_FIELD_ACCESS_ANY:
1132efcc2a30SJung-uk Kim case AML_FIELD_ACCESS_BYTE:
1133efcc2a30SJung-uk Kim case AML_FIELD_ACCESS_BUFFER:
1134efcc2a30SJung-uk Kim default:
1135a9d8d09cSJung-uk Kim
1136efcc2a30SJung-uk Kim MinimumLength = 1;
1137efcc2a30SJung-uk Kim break;
1138efcc2a30SJung-uk Kim
1139efcc2a30SJung-uk Kim case AML_FIELD_ACCESS_WORD:
1140a9d8d09cSJung-uk Kim
1141efcc2a30SJung-uk Kim MinimumLength = 2;
1142efcc2a30SJung-uk Kim break;
1143efcc2a30SJung-uk Kim
1144efcc2a30SJung-uk Kim case AML_FIELD_ACCESS_DWORD:
1145a9d8d09cSJung-uk Kim
1146efcc2a30SJung-uk Kim MinimumLength = 4;
1147efcc2a30SJung-uk Kim break;
1148efcc2a30SJung-uk Kim
1149efcc2a30SJung-uk Kim case AML_FIELD_ACCESS_QWORD:
1150a9d8d09cSJung-uk Kim
1151efcc2a30SJung-uk Kim MinimumLength = 8;
1152efcc2a30SJung-uk Kim break;
1153efcc2a30SJung-uk Kim }
1154efcc2a30SJung-uk Kim
1155efcc2a30SJung-uk Kim /*
1156efcc2a30SJung-uk Kim * Is the region at least as big as the access width?
1157efcc2a30SJung-uk Kim * Note: DataTableRegions have 0 length
1158efcc2a30SJung-uk Kim */
1159efcc2a30SJung-uk Kim if (((UINT32) OwningOp->Asl.Value.Integer) &&
1160efcc2a30SJung-uk Kim ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
1161efcc2a30SJung-uk Kim {
1162efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
1163efcc2a30SJung-uk Kim }
1164efcc2a30SJung-uk Kim
1165efcc2a30SJung-uk Kim /*
1166efcc2a30SJung-uk Kim * Check EC/CMOS/SMBUS fields to make sure that the correct
1167efcc2a30SJung-uk Kim * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
1168efcc2a30SJung-uk Kim */
1169efcc2a30SJung-uk Kim SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
1170efcc2a30SJung-uk Kim switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
1171efcc2a30SJung-uk Kim {
1172efcc2a30SJung-uk Kim case ACPI_ADR_SPACE_EC:
1173efcc2a30SJung-uk Kim case ACPI_ADR_SPACE_CMOS:
1174efcc2a30SJung-uk Kim case ACPI_ADR_SPACE_GPIO:
1175efcc2a30SJung-uk Kim
1176f8146b88SJung-uk Kim if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
1177f8146b88SJung-uk Kim AML_FIELD_ACCESS_BYTE)
1178efcc2a30SJung-uk Kim {
1179efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
1180efcc2a30SJung-uk Kim }
1181efcc2a30SJung-uk Kim break;
1182efcc2a30SJung-uk Kim
1183efcc2a30SJung-uk Kim case ACPI_ADR_SPACE_SMBUS:
1184efcc2a30SJung-uk Kim case ACPI_ADR_SPACE_IPMI:
1185efcc2a30SJung-uk Kim case ACPI_ADR_SPACE_GSBUS:
1186efcc2a30SJung-uk Kim
1187f8146b88SJung-uk Kim if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
1188f8146b88SJung-uk Kim AML_FIELD_ACCESS_BUFFER)
1189efcc2a30SJung-uk Kim {
1190efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
1191efcc2a30SJung-uk Kim }
1192efcc2a30SJung-uk Kim break;
1193efcc2a30SJung-uk Kim
1194efcc2a30SJung-uk Kim default:
1195efcc2a30SJung-uk Kim
1196efcc2a30SJung-uk Kim /* Nothing to do for other address spaces */
1197a9d8d09cSJung-uk Kim
1198efcc2a30SJung-uk Kim break;
1199efcc2a30SJung-uk Kim }
1200efcc2a30SJung-uk Kim }
1201efcc2a30SJung-uk Kim else
1202efcc2a30SJung-uk Kim {
1203efcc2a30SJung-uk Kim /*
1204efcc2a30SJung-uk Kim * This is one element of the field list. Check to make sure
1205efcc2a30SJung-uk Kim * that it does not go beyond the end of the parent operation region.
1206efcc2a30SJung-uk Kim *
1207efcc2a30SJung-uk Kim * In the code below:
1208efcc2a30SJung-uk Kim * Op->Asl.Parent->Asl.ExtraValue - Region Length (bits)
1209efcc2a30SJung-uk Kim * Op->Asl.ExtraValue - Field start offset (bits)
1210efcc2a30SJung-uk Kim * Op->Asl.Child->Asl.Value.Integer32 - Field length (bits)
1211efcc2a30SJung-uk Kim * Op->Asl.Child->Asl.ExtraValue - Field access width (bits)
1212efcc2a30SJung-uk Kim */
1213efcc2a30SJung-uk Kim if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
1214efcc2a30SJung-uk Kim {
1215efcc2a30SJung-uk Kim XfCheckFieldRange (Op,
1216efcc2a30SJung-uk Kim Op->Asl.Parent->Asl.ExtraValue,
1217efcc2a30SJung-uk Kim Op->Asl.ExtraValue,
1218efcc2a30SJung-uk Kim (UINT32) Op->Asl.Child->Asl.Value.Integer,
1219efcc2a30SJung-uk Kim Op->Asl.Child->Asl.ExtraValue);
1220efcc2a30SJung-uk Kim }
1221efcc2a30SJung-uk Kim }
1222efcc2a30SJung-uk Kim }
1223efcc2a30SJung-uk Kim
122444b0f624SJung-uk Kim /*
122544b0f624SJung-uk Kim * 5) Check for external resolution
122608ddfe86SJung-uk Kim *
122744b0f624SJung-uk Kim * By this point, everything should be loaded in the namespace. If a
122844b0f624SJung-uk Kim * namespace lookup results in a namespace node that is an external, it
122944b0f624SJung-uk Kim * means that this named object was not defined in the input ASL. This
123044b0f624SJung-uk Kim * causes issues because there are plenty of incidents where developers
123144b0f624SJung-uk Kim * use the external keyword to suppress compiler errors about undefined
123244b0f624SJung-uk Kim * objects. Note: this only applies when compiling multiple definition
123344b0f624SJung-uk Kim * blocks.
123408ddfe86SJung-uk Kim *
123508ddfe86SJung-uk Kim * Do not check for external resolution in the following cases:
123608ddfe86SJung-uk Kim *
123708ddfe86SJung-uk Kim * case 1) External (ABCD)
123808ddfe86SJung-uk Kim *
123908ddfe86SJung-uk Kim * This declares ABCD as an external so there is no requirement for
124008ddfe86SJung-uk Kim * ABCD to be loaded in the namespace when analyzing the actual
124108ddfe86SJung-uk Kim * External() statement.
124208ddfe86SJung-uk Kim *
124308ddfe86SJung-uk Kim * case 2) CondRefOf (ABCD)
124408ddfe86SJung-uk Kim *
124508ddfe86SJung-uk Kim * This operator will query the ACPI namespace on the existence of
124608ddfe86SJung-uk Kim * ABCD. If ABCD does not exist, this operator will return a 0
124708ddfe86SJung-uk Kim * without incurring AML runtime errors. Therefore, ABCD is allowed
124808ddfe86SJung-uk Kim * to not exist when analyzing the CondRefOf operator.
124908ddfe86SJung-uk Kim *
125008ddfe86SJung-uk Kim * case 3) External (ABCD)
125108ddfe86SJung-uk Kim * if (CondRefOf (ABCD))
125208ddfe86SJung-uk Kim * {
125308ddfe86SJung-uk Kim * Store (0, ABCD)
125408ddfe86SJung-uk Kim * }
125508ddfe86SJung-uk Kim *
125608ddfe86SJung-uk Kim * In this case, ABCD is accessed only if it exists due to the if
125708ddfe86SJung-uk Kim * statement so there is no need to flag the ABCD nested in the
125808ddfe86SJung-uk Kim * store operator.
125944b0f624SJung-uk Kim */
126044b0f624SJung-uk Kim if (AslGbl_ParseTreeRoot->Asl.Child && AslGbl_ParseTreeRoot->Asl.Child->Asl.Next &&
126108ddfe86SJung-uk Kim (Node->Flags & ANOBJ_IS_EXTERNAL) &&
126208ddfe86SJung-uk Kim Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL &&
126308ddfe86SJung-uk Kim Op->Asl.ParseOpcode != PARSEOP_EXTERNAL &&
126408ddfe86SJung-uk Kim Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_CONDREFOF &&
126508ddfe86SJung-uk Kim !XfRefIsGuardedByIfCondRefOf (Node, Op))
126644b0f624SJung-uk Kim {
1267f15e9afbSJung-uk Kim ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
1268f15e9afbSJung-uk Kim sprintf (AslGbl_MsgBuffer, "full path of external object: %s",
1269f15e9afbSJung-uk Kim ExternalPath);
1270f15e9afbSJung-uk Kim AslDualParseOpError (ASL_ERROR, ASL_MSG_UNDEFINED_EXTERNAL, Op, NULL,
1271f15e9afbSJung-uk Kim ASL_MSG_EXTERNAL_FOUND_HERE, Node->Op, AslGbl_MsgBuffer);
1272f15e9afbSJung-uk Kim if (ExternalPath)
1273f15e9afbSJung-uk Kim {
1274f15e9afbSJung-uk Kim ACPI_FREE (ExternalPath);
1275f15e9afbSJung-uk Kim }
127644b0f624SJung-uk Kim }
127744b0f624SJung-uk Kim
1278313a0c13SJung-uk Kim /* 5) Check for a connection object */
1279313a0c13SJung-uk Kim #if 0
1280313a0c13SJung-uk Kim else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
1281313a0c13SJung-uk Kim {
1282313a0c13SJung-uk Kim return_ACPI_STATUS (Status);
1283313a0c13SJung-uk Kim }
1284313a0c13SJung-uk Kim #endif
1285313a0c13SJung-uk Kim
1286efcc2a30SJung-uk Kim Op->Asl.Node = Node;
1287313a0c13SJung-uk Kim return_ACPI_STATUS (Status);
1288efcc2a30SJung-uk Kim }
1289efcc2a30SJung-uk Kim
1290efcc2a30SJung-uk Kim
1291efcc2a30SJung-uk Kim /*******************************************************************************
1292efcc2a30SJung-uk Kim *
129308ddfe86SJung-uk Kim * FUNCTION: XfRefIsGuardedByIfCondRefOf
129408ddfe86SJung-uk Kim *
129508ddfe86SJung-uk Kim * PARAMETERS: Node - Named object reference node
129608ddfe86SJung-uk Kim * Op - Named object reference parse node
129708ddfe86SJung-uk Kim *
129808ddfe86SJung-uk Kim * RETURN: BOOLEAN
129908ddfe86SJung-uk Kim *
130008ddfe86SJung-uk Kim * DESCRIPTION: returns true if Op checked inside if (CondRefOf (...))
130108ddfe86SJung-uk Kim * refers to Node.
130208ddfe86SJung-uk Kim *
130308ddfe86SJung-uk Kim ******************************************************************************/
130408ddfe86SJung-uk Kim
130508ddfe86SJung-uk Kim static BOOLEAN
XfRefIsGuardedByIfCondRefOf(ACPI_NAMESPACE_NODE * Node,ACPI_PARSE_OBJECT * Op)130608ddfe86SJung-uk Kim XfRefIsGuardedByIfCondRefOf (
130708ddfe86SJung-uk Kim ACPI_NAMESPACE_NODE *Node,
130808ddfe86SJung-uk Kim ACPI_PARSE_OBJECT *Op)
130908ddfe86SJung-uk Kim {
131008ddfe86SJung-uk Kim ACPI_PARSE_OBJECT *Parent = Op->Asl.Parent;
131108ddfe86SJung-uk Kim
131208ddfe86SJung-uk Kim
131308ddfe86SJung-uk Kim while (Parent)
131408ddfe86SJung-uk Kim {
131508ddfe86SJung-uk Kim if (Parent->Asl.ParseOpcode == PARSEOP_IF &&
131608ddfe86SJung-uk Kim XfFindCondRefOfName (Node, Parent->Asl.Child))
131708ddfe86SJung-uk Kim {
131808ddfe86SJung-uk Kim return (TRUE);
131908ddfe86SJung-uk Kim }
132008ddfe86SJung-uk Kim
132108ddfe86SJung-uk Kim Parent = Parent->Asl.Parent;
132208ddfe86SJung-uk Kim }
132308ddfe86SJung-uk Kim
132408ddfe86SJung-uk Kim return (FALSE);
132508ddfe86SJung-uk Kim }
132608ddfe86SJung-uk Kim
132708ddfe86SJung-uk Kim
132808ddfe86SJung-uk Kim /*******************************************************************************
132908ddfe86SJung-uk Kim *
133008ddfe86SJung-uk Kim * FUNCTION: XfRefIsGuardedByIfCondRefOf
133108ddfe86SJung-uk Kim *
133208ddfe86SJung-uk Kim * PARAMETERS: Node - Named object reference node
133308ddfe86SJung-uk Kim * Op - Named object reference parse node
133408ddfe86SJung-uk Kim *
133508ddfe86SJung-uk Kim * RETURN: BOOLEAN
133608ddfe86SJung-uk Kim *
133708ddfe86SJung-uk Kim * DESCRIPTION: returns true if Op checked inside if (CondRefOf (...))
133808ddfe86SJung-uk Kim * refers to Node.
133908ddfe86SJung-uk Kim *
134008ddfe86SJung-uk Kim ******************************************************************************/
134108ddfe86SJung-uk Kim
134208ddfe86SJung-uk Kim static BOOLEAN
XfFindCondRefOfName(ACPI_NAMESPACE_NODE * Node,ACPI_PARSE_OBJECT * Op)134308ddfe86SJung-uk Kim XfFindCondRefOfName (
134408ddfe86SJung-uk Kim ACPI_NAMESPACE_NODE *Node,
134508ddfe86SJung-uk Kim ACPI_PARSE_OBJECT *Op)
134608ddfe86SJung-uk Kim {
134708ddfe86SJung-uk Kim BOOLEAN CondRefOfFound = FALSE;
134808ddfe86SJung-uk Kim
134908ddfe86SJung-uk Kim
135008ddfe86SJung-uk Kim if (!Op)
135108ddfe86SJung-uk Kim {
135208ddfe86SJung-uk Kim return (FALSE);
135308ddfe86SJung-uk Kim }
135408ddfe86SJung-uk Kim
135508ddfe86SJung-uk Kim switch (Op->Asl.ParseOpcode)
135608ddfe86SJung-uk Kim {
135708ddfe86SJung-uk Kim case PARSEOP_CONDREFOF:
135808ddfe86SJung-uk Kim
135908ddfe86SJung-uk Kim return (Op->Asl.Child->Common.Node == Node);
136008ddfe86SJung-uk Kim break;
136108ddfe86SJung-uk Kim
136208ddfe86SJung-uk Kim case PARSEOP_LAND:
136308ddfe86SJung-uk Kim
136408ddfe86SJung-uk Kim CondRefOfFound = XfFindCondRefOfName (Node, Op->Asl.Child);
136508ddfe86SJung-uk Kim if (CondRefOfFound)
136608ddfe86SJung-uk Kim {
136708ddfe86SJung-uk Kim return (TRUE);
136808ddfe86SJung-uk Kim }
136908ddfe86SJung-uk Kim
137008ddfe86SJung-uk Kim return (XfFindCondRefOfName (Node, Op->Asl.Child->Asl.Next));
137108ddfe86SJung-uk Kim break;
137208ddfe86SJung-uk Kim
137308ddfe86SJung-uk Kim default:
137408ddfe86SJung-uk Kim
137508ddfe86SJung-uk Kim return (FALSE);
137608ddfe86SJung-uk Kim break;
137708ddfe86SJung-uk Kim }
137808ddfe86SJung-uk Kim }
137908ddfe86SJung-uk Kim
138008ddfe86SJung-uk Kim
138108ddfe86SJung-uk Kim /*******************************************************************************
138208ddfe86SJung-uk Kim *
1383efcc2a30SJung-uk Kim * FUNCTION: XfNamespaceLocateEnd
1384efcc2a30SJung-uk Kim *
1385efcc2a30SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK
1386efcc2a30SJung-uk Kim *
1387efcc2a30SJung-uk Kim * RETURN: Status
1388efcc2a30SJung-uk Kim *
1389efcc2a30SJung-uk Kim * DESCRIPTION: Ascending callback used during cross reference. We only
1390efcc2a30SJung-uk Kim * need to worry about scope management here.
1391efcc2a30SJung-uk Kim *
1392efcc2a30SJung-uk Kim ******************************************************************************/
1393efcc2a30SJung-uk Kim
1394efcc2a30SJung-uk Kim static ACPI_STATUS
XfNamespaceLocateEnd(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)1395efcc2a30SJung-uk Kim XfNamespaceLocateEnd (
1396efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op,
1397efcc2a30SJung-uk Kim UINT32 Level,
1398efcc2a30SJung-uk Kim void *Context)
1399efcc2a30SJung-uk Kim {
1400efcc2a30SJung-uk Kim ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
1401efcc2a30SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo;
1402efcc2a30SJung-uk Kim
1403efcc2a30SJung-uk Kim
1404efcc2a30SJung-uk Kim ACPI_FUNCTION_TRACE (XfNamespaceLocateEnd);
1405efcc2a30SJung-uk Kim
1406efcc2a30SJung-uk Kim
1407efcc2a30SJung-uk Kim /* We are only interested in opcodes that have an associated name */
1408efcc2a30SJung-uk Kim
1409efcc2a30SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1410efcc2a30SJung-uk Kim if (!(OpInfo->Flags & AML_NAMED))
1411efcc2a30SJung-uk Kim {
1412313a0c13SJung-uk Kim return_ACPI_STATUS (AE_OK);
1413efcc2a30SJung-uk Kim }
1414efcc2a30SJung-uk Kim
1415efcc2a30SJung-uk Kim /* Not interested in name references, we did not open a scope for them */
1416efcc2a30SJung-uk Kim
1417efcc2a30SJung-uk Kim if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
1418efcc2a30SJung-uk Kim (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
1419af051161SJung-uk Kim (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
1420af051161SJung-uk Kim (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
1421efcc2a30SJung-uk Kim {
1422313a0c13SJung-uk Kim return_ACPI_STATUS (AE_OK);
1423efcc2a30SJung-uk Kim }
1424efcc2a30SJung-uk Kim
1425efcc2a30SJung-uk Kim /* Pop the scope stack if necessary */
1426efcc2a30SJung-uk Kim
1427efcc2a30SJung-uk Kim if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
1428efcc2a30SJung-uk Kim {
1429efcc2a30SJung-uk Kim
1430efcc2a30SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1431efcc2a30SJung-uk Kim "%s: Popping scope for Op %p\n",
1432efcc2a30SJung-uk Kim AcpiUtGetTypeName (OpInfo->ObjectType), Op));
1433efcc2a30SJung-uk Kim
1434efcc2a30SJung-uk Kim (void) AcpiDsScopeStackPop (WalkState);
1435efcc2a30SJung-uk Kim }
1436efcc2a30SJung-uk Kim
1437313a0c13SJung-uk Kim return_ACPI_STATUS (AE_OK);
1438efcc2a30SJung-uk Kim }
1439cd6518c7SJung-uk Kim
1440cd6518c7SJung-uk Kim
1441cd6518c7SJung-uk Kim /*******************************************************************************
1442cd6518c7SJung-uk Kim *
1443cd6518c7SJung-uk Kim * FUNCTION: XfValidateCrossReference
1444cd6518c7SJung-uk Kim *
1445cd6518c7SJung-uk Kim * PARAMETERS: Op - Parse Op that references the object
1446cd6518c7SJung-uk Kim * OpInfo - Parse Op info struct
1447cd6518c7SJung-uk Kim * Node - Node for the referenced object
1448cd6518c7SJung-uk Kim *
1449cd6518c7SJung-uk Kim * RETURN: TRUE if the reference is legal, FALSE otherwise
1450cd6518c7SJung-uk Kim *
1451cd6518c7SJung-uk Kim * DESCRIPTION: Determine if a reference to another object is allowed.
1452cd6518c7SJung-uk Kim *
1453cd6518c7SJung-uk Kim * EXAMPLE:
1454cd6518c7SJung-uk Kim * Method (A) {Name (INT1, 1)} Declaration of object INT1
1455cd6518c7SJung-uk Kim * Method (B) (Store (2, \A.INT1)} Illegal reference to object INT1
1456cd6518c7SJung-uk Kim * (INT1 is temporary, valid only during
1457cd6518c7SJung-uk Kim * execution of A)
1458cd6518c7SJung-uk Kim *
1459cd6518c7SJung-uk Kim * NOTES:
1460ec0234b4SJung-uk Kim * A null pointer returned by either UtGetParentMethodOp or
1461ec0234b4SJung-uk Kim * UtGetParentMethodNode indicates that the parameter object is not
1462cd6518c7SJung-uk Kim * within a control method.
1463cd6518c7SJung-uk Kim *
1464cd6518c7SJung-uk Kim * Five cases are handled: Case(Op, Node)
1465cd6518c7SJung-uk Kim * 1) Case(0,0): Op is not within a method, Node is not --> OK
1466cd6518c7SJung-uk Kim * 2) Case(0,1): Op is not within a method, but Node is --> Illegal
1467cd6518c7SJung-uk Kim * 3) Case(1,0): Op is within a method, Node is not --> OK
1468cd6518c7SJung-uk Kim * 4) Case(1,1): Both are within the same method --> OK
1469cd6518c7SJung-uk Kim * 5) Case(1,1): Both are in methods, but not same method --> Illegal
1470cd6518c7SJung-uk Kim *
1471cd6518c7SJung-uk Kim ******************************************************************************/
1472cd6518c7SJung-uk Kim
1473cd6518c7SJung-uk Kim static BOOLEAN
XfValidateCrossReference(ACPI_PARSE_OBJECT * Op,const ACPI_OPCODE_INFO * OpInfo,ACPI_NAMESPACE_NODE * Node)1474cd6518c7SJung-uk Kim XfValidateCrossReference (
1475cd6518c7SJung-uk Kim ACPI_PARSE_OBJECT *Op,
1476cd6518c7SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo,
1477cd6518c7SJung-uk Kim ACPI_NAMESPACE_NODE *Node)
1478cd6518c7SJung-uk Kim {
1479cd6518c7SJung-uk Kim ACPI_PARSE_OBJECT *ReferencingMethodOp;
1480cd6518c7SJung-uk Kim ACPI_NAMESPACE_NODE *ReferencedMethodNode;
1481cd6518c7SJung-uk Kim
1482cd6518c7SJung-uk Kim
1483cd6518c7SJung-uk Kim /* Ignore actual named (and related) object declarations */
1484cd6518c7SJung-uk Kim
1485cd6518c7SJung-uk Kim if (OpInfo->Flags & (AML_NAMED | AML_CREATE | AML_DEFER | AML_HAS_ARGS))
1486cd6518c7SJung-uk Kim {
1487cd6518c7SJung-uk Kim return (TRUE);
1488cd6518c7SJung-uk Kim }
1489cd6518c7SJung-uk Kim
1490cd6518c7SJung-uk Kim /*
1491cd6518c7SJung-uk Kim * 1) Search upwards in parse tree for owner of the referencing object
1492cd6518c7SJung-uk Kim * 2) Search upwards in namespace to find the owner of the referenced object
1493cd6518c7SJung-uk Kim */
1494ec0234b4SJung-uk Kim ReferencingMethodOp = UtGetParentMethodOp (Op);
1495ec0234b4SJung-uk Kim ReferencedMethodNode = UtGetParentMethodNode (Node);
1496cd6518c7SJung-uk Kim
1497cd6518c7SJung-uk Kim if (!ReferencingMethodOp && !ReferencedMethodNode)
1498cd6518c7SJung-uk Kim {
1499cd6518c7SJung-uk Kim /*
1500cd6518c7SJung-uk Kim * 1) Case (0,0): Both Op and Node are not within methods
1501cd6518c7SJung-uk Kim * --> OK
1502cd6518c7SJung-uk Kim */
1503cd6518c7SJung-uk Kim return (TRUE);
1504cd6518c7SJung-uk Kim }
1505cd6518c7SJung-uk Kim
1506cd6518c7SJung-uk Kim if (!ReferencingMethodOp && ReferencedMethodNode)
1507cd6518c7SJung-uk Kim {
1508cd6518c7SJung-uk Kim /*
1509cd6518c7SJung-uk Kim * 2) Case (0,1): Op is not in a method, but Node is within a
1510cd6518c7SJung-uk Kim * method --> illegal
1511cd6518c7SJung-uk Kim */
1512cd6518c7SJung-uk Kim return (FALSE);
1513cd6518c7SJung-uk Kim }
1514cd6518c7SJung-uk Kim else if (ReferencingMethodOp && !ReferencedMethodNode)
1515cd6518c7SJung-uk Kim {
1516cd6518c7SJung-uk Kim /*
1517cd6518c7SJung-uk Kim * 3) Case (1,0): Op is within a method, but Node is not
1518cd6518c7SJung-uk Kim * --> OK
1519cd6518c7SJung-uk Kim */
1520cd6518c7SJung-uk Kim return (TRUE);
1521cd6518c7SJung-uk Kim }
1522cd6518c7SJung-uk Kim else if (ReferencingMethodOp->Asl.Node == ReferencedMethodNode)
1523cd6518c7SJung-uk Kim {
1524cd6518c7SJung-uk Kim /*
1525cd6518c7SJung-uk Kim * 4) Case (1,1): Both Op and Node are within the same method
1526cd6518c7SJung-uk Kim * --> OK
1527cd6518c7SJung-uk Kim */
1528cd6518c7SJung-uk Kim return (TRUE);
1529cd6518c7SJung-uk Kim }
1530cd6518c7SJung-uk Kim else
1531cd6518c7SJung-uk Kim {
1532cd6518c7SJung-uk Kim /*
1533cd6518c7SJung-uk Kim * 5) Case (1,1), Op and Node are in different methods
1534cd6518c7SJung-uk Kim * --> Illegal
1535cd6518c7SJung-uk Kim */
1536cd6518c7SJung-uk Kim return (FALSE);
1537cd6518c7SJung-uk Kim }
1538cd6518c7SJung-uk Kim }
1539