The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/compiler/aslxref.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /******************************************************************************
    2  *
    3  * Module Name: aslxref - Namespace cross-reference
    4  *
    5  *****************************************************************************/
    6 
    7 /******************************************************************************
    8  *
    9  * 1. Copyright Notice
   10  *
   11  * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp.
   12  * All rights reserved.
   13  *
   14  * 2. License
   15  *
   16  * 2.1. This is your license from Intel Corp. under its intellectual property
   17  * rights. You may have additional license terms from the party that provided
   18  * you this software, covering your right to use that party's intellectual
   19  * property rights.
   20  *
   21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
   22  * copy of the source code appearing in this file ("Covered Code") an
   23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
   24  * base code distributed originally by Intel ("Original Intel Code") to copy,
   25  * make derivatives, distribute, use and display any portion of the Covered
   26  * Code in any form, with the right to sublicense such rights; and
   27  *
   28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
   29  * license (with the right to sublicense), under only those claims of Intel
   30  * patents that are infringed by the Original Intel Code, to make, use, sell,
   31  * offer to sell, and import the Covered Code and derivative works thereof
   32  * solely to the minimum extent necessary to exercise the above copyright
   33  * license, and in no event shall the patent license extend to any additions
   34  * to or modifications of the Original Intel Code. No other license or right
   35  * is granted directly or by implication, estoppel or otherwise;
   36  *
   37  * The above copyright and patent license is granted only if the following
   38  * conditions are met:
   39  *
   40  * 3. Conditions
   41  *
   42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
   43  * Redistribution of source code of any substantial portion of the Covered
   44  * Code or modification with rights to further distribute source must include
   45  * the above Copyright Notice, the above License, this list of Conditions,
   46  * and the following Disclaimer and Export Compliance provision. In addition,
   47  * Licensee must cause all Covered Code to which Licensee contributes to
   48  * contain a file documenting the changes Licensee made to create that Covered
   49  * Code and the date of any change. Licensee must include in that file the
   50  * documentation of any changes made by any predecessor Licensee. Licensee
   51  * must include a prominent statement that the modification is derived,
   52  * directly or indirectly, from Original Intel Code.
   53  *
   54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
   55  * Redistribution of source code of any substantial portion of the Covered
   56  * Code or modification without rights to further distribute source must
   57  * include the following Disclaimer and Export Compliance provision in the
   58  * documentation and/or other materials provided with distribution. In
   59  * addition, Licensee may not authorize further sublicense of source of any
   60  * portion of the Covered Code, and must include terms to the effect that the
   61  * license from Licensee to its licensee is limited to the intellectual
   62  * property embodied in the software Licensee provides to its licensee, and
   63  * not to intellectual property embodied in modifications its licensee may
   64  * make.
   65  *
   66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
   67  * substantial portion of the Covered Code or modification must reproduce the
   68  * above Copyright Notice, and the following Disclaimer and Export Compliance
   69  * provision in the documentation and/or other materials provided with the
   70  * distribution.
   71  *
   72  * 3.4. Intel retains all right, title, and interest in and to the Original
   73  * Intel Code.
   74  *
   75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
   76  * Intel shall be used in advertising or otherwise to promote the sale, use or
   77  * other dealings in products derived from or relating to the Covered Code
   78  * without prior written authorization from Intel.
   79  *
   80  * 4. Disclaimer and Export Compliance
   81  *
   82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
   83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
   84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
   85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
   86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
   87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
   88  * PARTICULAR PURPOSE.
   89  *
   90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
   91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
   92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
   93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
   94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
   95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
   96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
   97  * LIMITED REMEDY.
   98  *
   99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100  * software or system incorporating such software without first obtaining any
  101  * required license or other approval from the U. S. Department of Commerce or
  102  * any other agency or department of the United States Government. In the
  103  * event Licensee exports any such software from the United States or
  104  * re-exports any such software from a foreign destination, Licensee shall
  105  * ensure that the distribution and export/re-export of the software is in
  106  * compliance with all laws, regulations, orders, or other restrictions of the
  107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108  * any of its subsidiaries will export/re-export any technical data, process,
  109  * software, or service, directly or indirectly, to any country for which the
  110  * United States government or any agency thereof requires an export license,
  111  * other governmental approval, or letter of assurance, without first obtaining
  112  * such license, approval or letter.
  113  *
  114  *****************************************************************************
  115  *
  116  * Alternatively, you may choose to be licensed under the terms of the
  117  * following license:
  118  *
  119  * Redistribution and use in source and binary forms, with or without
  120  * modification, are permitted provided that the following conditions
  121  * are met:
  122  * 1. Redistributions of source code must retain the above copyright
  123  *    notice, this list of conditions, and the following disclaimer,
  124  *    without modification.
  125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  126  *    substantially similar to the "NO WARRANTY" disclaimer below
  127  *    ("Disclaimer") and any redistribution must be conditioned upon
  128  *    including a substantially similar Disclaimer requirement for further
  129  *    binary redistribution.
  130  * 3. Neither the names of the above-listed copyright holders nor the names
  131  *    of any contributors may be used to endorse or promote products derived
  132  *    from this software without specific prior written permission.
  133  *
  134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  145  *
  146  * Alternatively, you may choose to be licensed under the terms of the
  147  * GNU General Public License ("GPL") version 2 as published by the Free
  148  * Software Foundation.
  149  *
  150  *****************************************************************************/
  151 
  152 #include <contrib/dev/acpica/compiler/aslcompiler.h>
  153 #include "aslcompiler.y.h"
  154 #include <contrib/dev/acpica/include/acparser.h>
  155 #include <contrib/dev/acpica/include/amlcode.h>
  156 #include <contrib/dev/acpica/include/acnamesp.h>
  157 #include <contrib/dev/acpica/include/acdispat.h>
  158 
  159 
  160 #define _COMPONENT          ACPI_COMPILER
  161         ACPI_MODULE_NAME    ("aslxref")
  162 
  163 /* Local prototypes */
  164 
  165 static ACPI_STATUS
  166 XfNamespaceLocateBegin (
  167     ACPI_PARSE_OBJECT       *Op,
  168     UINT32                  Level,
  169     void                    *Context);
  170 
  171 static ACPI_STATUS
  172 XfNamespaceLocateEnd (
  173     ACPI_PARSE_OBJECT       *Op,
  174     UINT32                  Level,
  175     void                    *Context);
  176 
  177 static BOOLEAN
  178 XfValidateCrossReference (
  179     ACPI_PARSE_OBJECT       *Op,
  180     const ACPI_OPCODE_INFO  *OpInfo,
  181     ACPI_NAMESPACE_NODE     *Node);
  182 
  183 static BOOLEAN
  184 XfObjectExists (
  185     char                    *Name);
  186 
  187 static ACPI_STATUS
  188 XfCompareOneNamespaceObject (
  189     ACPI_HANDLE             ObjHandle,
  190     UINT32                  Level,
  191     void                    *Context,
  192     void                    **ReturnValue);
  193 
  194 static void
  195 XfCheckFieldRange (
  196     ACPI_PARSE_OBJECT       *Op,
  197     UINT32                  RegionBitLength,
  198     UINT32                  FieldBitOffset,
  199     UINT32                  FieldBitLength,
  200     UINT32                  AccessBitWidth);
  201 
  202 static BOOLEAN
  203 XfFindCondRefOfName (
  204     ACPI_NAMESPACE_NODE     *Node,
  205     ACPI_PARSE_OBJECT       *Op);
  206 
  207 static BOOLEAN
  208 XfRefIsGuardedByIfCondRefOf (
  209     ACPI_NAMESPACE_NODE     *Node,
  210     ACPI_PARSE_OBJECT       *Op);
  211 
  212 
  213 /*******************************************************************************
  214  *
  215  * FUNCTION:    XfCrossReferenceNamespace
  216  *
  217  * PARAMETERS:  None
  218  *
  219  * RETURN:      Status
  220  *
  221  * DESCRIPTION: Perform a cross reference check of the parse tree against the
  222  *              namespace. Every named referenced within the parse tree
  223  *              should be get resolved with a namespace lookup. If not, the
  224  *              original reference in the ASL code is invalid -- i.e., refers
  225  *              to a non-existent object.
  226  *
  227  * NOTE:  The ASL "External" operator causes the name to be inserted into the
  228  *        namespace so that references to the external name will be resolved
  229  *        correctly here.
  230  *
  231  ******************************************************************************/
  232 
  233 ACPI_STATUS
  234 XfCrossReferenceNamespace (
  235     void)
  236 {
  237     ACPI_WALK_STATE         *WalkState;
  238 
  239 
  240     /*
  241      * Create a new walk state for use when looking up names
  242      * within the namespace (Passed as context to the callbacks)
  243      */
  244     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
  245     if (!WalkState)
  246     {
  247         return (AE_NO_MEMORY);
  248     }
  249 
  250     /* Walk the entire parse tree */
  251 
  252     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
  253         XfNamespaceLocateBegin, XfNamespaceLocateEnd, WalkState);
  254 
  255     ACPI_FREE (WalkState);
  256     return (AE_OK);
  257 }
  258 
  259 
  260 /*******************************************************************************
  261  *
  262  * FUNCTION:    XfObjectExists
  263  *
  264  * PARAMETERS:  Name            - 4 char ACPI name
  265  *
  266  * RETURN:      TRUE if name exists in namespace
  267  *
  268  * DESCRIPTION: Walk the namespace to find an object
  269  *
  270  ******************************************************************************/
  271 
  272 static BOOLEAN
  273 XfObjectExists (
  274     char                    *Name)
  275 {
  276     ACPI_STATUS             Status;
  277 
  278 
  279     /* Walk entire namespace from the supplied root */
  280 
  281     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  282         ACPI_UINT32_MAX, FALSE, XfCompareOneNamespaceObject, NULL,
  283         Name, NULL);
  284     if (Status == AE_CTRL_TRUE)
  285     {
  286         /* At least one instance of the name was found */
  287 
  288         return (TRUE);
  289     }
  290 
  291     return (FALSE);
  292 }
  293 
  294 
  295 /*******************************************************************************
  296  *
  297  * FUNCTION:    XfCompareOneNamespaceObject
  298  *
  299  * PARAMETERS:  ACPI_WALK_CALLBACK
  300  *
  301  * RETURN:      Status
  302  *
  303  * DESCRIPTION: Compare name of one object.
  304  *
  305  ******************************************************************************/
  306 
  307 static ACPI_STATUS
  308 XfCompareOneNamespaceObject (
  309     ACPI_HANDLE             ObjHandle,
  310     UINT32                  Level,
  311     void                    *Context,
  312     void                    **ReturnValue)
  313 {
  314     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
  315 
  316 
  317     /* Simply check the name */
  318 
  319     if (*((UINT32 *) (Context)) == Node->Name.Integer)
  320     {
  321         /* Abort walk if we found one instance */
  322 
  323         return (AE_CTRL_TRUE);
  324     }
  325 
  326     return (AE_OK);
  327 }
  328 
  329 
  330 /*******************************************************************************
  331  *
  332  * FUNCTION:    XfCheckFieldRange
  333  *
  334  * PARAMETERS:  RegionBitLength     - Length of entire parent region
  335  *              FieldBitOffset      - Start of the field unit (within region)
  336  *              FieldBitLength      - Entire length of field unit
  337  *              AccessBitWidth      - Access width of the field unit
  338  *
  339  * RETURN:      None
  340  *
  341  * DESCRIPTION: Check one field unit to make sure it fits in the parent
  342  *              op region.
  343  *
  344  * Note: AccessBitWidth must be either 8,16,32, or 64
  345  *
  346  ******************************************************************************/
  347 
  348 static void
  349 XfCheckFieldRange (
  350     ACPI_PARSE_OBJECT       *Op,
  351     UINT32                  RegionBitLength,
  352     UINT32                  FieldBitOffset,
  353     UINT32                  FieldBitLength,
  354     UINT32                  AccessBitWidth)
  355 {
  356     UINT32                  FieldEndBitOffset;
  357 
  358 
  359     /*
  360      * Check each field unit against the region size. The entire
  361      * field unit (start offset plus length) must fit within the
  362      * region.
  363      */
  364     FieldEndBitOffset = FieldBitOffset + FieldBitLength;
  365 
  366     if (FieldEndBitOffset > RegionBitLength)
  367     {
  368         /* Field definition itself is beyond the end-of-region */
  369 
  370         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
  371         return;
  372     }
  373 
  374     /*
  375      * Now check that the field plus AccessWidth doesn't go beyond
  376      * the end-of-region. Assumes AccessBitWidth is a power of 2
  377      */
  378     FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
  379 
  380     if (FieldEndBitOffset > RegionBitLength)
  381     {
  382         /* Field definition combined with the access is beyond EOR */
  383 
  384         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
  385     }
  386 }
  387 
  388 
  389 /*******************************************************************************
  390  *
  391  * FUNCTION:    XfNamespaceLocateBegin
  392  *
  393  * PARAMETERS:  ASL_WALK_CALLBACK
  394  *
  395  * RETURN:      Status
  396  *
  397  * DESCRIPTION: Descending callback used during cross-reference. For named
  398  *              object references, attempt to locate the name in the
  399  *              namespace.
  400  *
  401  * NOTE: ASL references to named fields within resource descriptors are
  402  *       resolved to integer values here. Therefore, this step is an
  403  *       important part of the code generation. We don't know that the
  404  *       name refers to a resource descriptor until now.
  405  *
  406  ******************************************************************************/
  407 
  408 static ACPI_STATUS
  409 XfNamespaceLocateBegin (
  410     ACPI_PARSE_OBJECT       *Op,
  411     UINT32                  Level,
  412     void                    *Context)
  413 {
  414     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
  415     ACPI_NAMESPACE_NODE     *Node;
  416     ACPI_STATUS             Status;
  417     ACPI_OBJECT_TYPE        ObjectType;
  418     char                    *Path;
  419     UINT8                   PassedArgs;
  420     ACPI_PARSE_OBJECT       *NextOp;
  421     ACPI_PARSE_OBJECT       *OwningOp;
  422     ACPI_PARSE_OBJECT       *SpaceIdOp;
  423     UINT32                  MinimumLength;
  424     UINT32                  Offset;
  425     UINT32                  FieldBitLength;
  426     UINT32                  TagBitLength;
  427     UINT8                   Message = 0;
  428     const ACPI_OPCODE_INFO  *OpInfo;
  429     UINT32                  Flags;
  430     ASL_METHOD_LOCAL        *MethodLocals = NULL;
  431     ASL_METHOD_LOCAL        *MethodArgs = NULL;
  432     int                     RegisterNumber;
  433     UINT32                  i;
  434     ACPI_NAMESPACE_NODE     *DeclarationParentMethod;
  435     ACPI_PARSE_OBJECT       *ReferenceParentMethod;
  436     char                    *ExternalPath;
  437 
  438 
  439     ACPI_FUNCTION_TRACE_PTR (XfNamespaceLocateBegin, Op);
  440 
  441 
  442     if ((Op->Asl.AmlOpcode == AML_METHOD_OP) && Op->Asl.Node)
  443     {
  444         Node = Op->Asl.Node;
  445 
  446         /* Support for method LocalX/ArgX analysis */
  447 
  448         if (!Node->MethodLocals)
  449         {
  450             /* Create local/arg info blocks */
  451 
  452             MethodLocals = UtLocalCalloc (
  453                 sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_LOCALS);
  454             Node->MethodLocals = MethodLocals;
  455 
  456             MethodArgs = UtLocalCalloc (
  457                 sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_ARGS);
  458             Node->MethodArgs = MethodArgs;
  459 
  460             /*
  461              * Get the method argument count
  462              * First, get the name node
  463              */
  464             NextOp = Op->Asl.Child;
  465 
  466             /* Get the NumArguments node */
  467 
  468             NextOp = NextOp->Asl.Next;
  469             Node->ArgCount = (UINT8)
  470                 (((UINT8) NextOp->Asl.Value.Integer) & 0x07);
  471 
  472             /* We will track all possible ArgXs */
  473 
  474             for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
  475             {
  476                 if (i < Node->ArgCount)
  477                 {
  478                     /* Real Args are always "initialized" */
  479 
  480                     MethodArgs[i].Flags = ASL_ARG_INITIALIZED;
  481                 }
  482                 else
  483                 {
  484                     /* Other ArgXs can be used as locals */
  485 
  486                     MethodArgs[i].Flags = ASL_ARG_IS_LOCAL;
  487                 }
  488 
  489                 MethodArgs[i].Op = Op;
  490             }
  491         }
  492     }
  493 
  494     /*
  495      * If this node is the actual declaration of a name
  496      * [such as the XXXX name in "Method (XXXX)"],
  497      * we are not interested in it here. We only care about names that are
  498      * references to other objects within the namespace and the parent objects
  499      * of name declarations
  500      */
  501     if (Op->Asl.CompileFlags & OP_IS_NAME_DECLARATION)
  502     {
  503         return_ACPI_STATUS (AE_OK);
  504     }
  505 
  506     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
  507 
  508     /* Check method LocalX variables */
  509 
  510     if (OpInfo->Type == AML_TYPE_LOCAL_VARIABLE)
  511     {
  512         /* Find parent method Op */
  513 
  514         NextOp = UtGetParentMethodOp (Op);
  515         if (!NextOp)
  516         {
  517             return_ACPI_STATUS (AE_OK);
  518         }
  519 
  520         /* Get method node */
  521 
  522         Node = NextOp->Asl.Node;
  523 
  524         RegisterNumber = Op->Asl.AmlOpcode & 0x0007; /* 0x60 through 0x67 */
  525         MethodLocals = Node->MethodLocals;
  526 
  527         if (Op->Asl.CompileFlags & OP_IS_TARGET)
  528         {
  529             /* Local is being initialized */
  530 
  531             MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_INITIALIZED;
  532             MethodLocals[RegisterNumber].Op = Op;
  533 
  534             return_ACPI_STATUS (AE_OK);
  535         }
  536 
  537         /* Mark this Local as referenced */
  538 
  539         MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_REFERENCED;
  540         MethodLocals[RegisterNumber].Op = Op;
  541 
  542         return_ACPI_STATUS (AE_OK);
  543     }
  544 
  545     /* Check method ArgX variables */
  546 
  547     if (OpInfo->Type == AML_TYPE_METHOD_ARGUMENT)
  548     {
  549         /* Find parent method Op */
  550 
  551         NextOp = UtGetParentMethodOp (Op);
  552         if (!NextOp)
  553         {
  554             return_ACPI_STATUS (AE_OK);
  555         }
  556 
  557         /* Get method node */
  558 
  559         Node = NextOp->Asl.Node;
  560 
  561         /* Get Arg # */
  562 
  563         RegisterNumber = Op->Asl.AmlOpcode - AML_ARG0; /* 0x68 through 0x6F */
  564         MethodArgs = Node->MethodArgs;
  565 
  566         /* Mark this Arg as referenced */
  567 
  568         MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED;
  569         MethodArgs[RegisterNumber].Op = Op;
  570 
  571         if (Op->Asl.CompileFlags & OP_IS_TARGET)
  572         {
  573             /* Arg is being initialized */
  574 
  575             MethodArgs[RegisterNumber].Flags |= ASL_ARG_INITIALIZED;
  576         }
  577 
  578         return_ACPI_STATUS (AE_OK);
  579     }
  580 
  581     /*
  582      * After method ArgX and LocalX, we are only interested in opcodes
  583      * that have an associated name
  584      */
  585     if ((!(OpInfo->Flags & AML_NAMED)) &&
  586         (!(OpInfo->Flags & AML_CREATE)) &&
  587         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
  588         (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
  589         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL) &&
  590         (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
  591     {
  592         return_ACPI_STATUS (AE_OK);
  593     }
  594 
  595     /*
  596      * We must enable the "search-to-root" for single NameSegs, but
  597      * we have to be very careful about opening up scopes
  598      */
  599     Flags = ACPI_NS_SEARCH_PARENT;
  600     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
  601         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
  602         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
  603         (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)   ||
  604         (Op->Asl.ParseOpcode == PARSEOP_CONDREFOF))
  605     {
  606         /*
  607          * These are name references, do not push the scope stack
  608          * for them.
  609          */
  610         Flags |= ACPI_NS_DONT_OPEN_SCOPE;
  611     }
  612 
  613     /* Get the NamePath from the appropriate place */
  614 
  615     if (OpInfo->Flags & AML_NAMED)
  616     {
  617         /* For nearly all NAMED operators, the name reference is the first child */
  618 
  619         Path = Op->Asl.Child->Asl.Value.String;
  620         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
  621         {
  622             /*
  623              * ALIAS is the only oddball opcode, the name declaration
  624              * (alias name) is the second operand
  625              */
  626             Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
  627         }
  628     }
  629     else if (OpInfo->Flags & AML_CREATE)
  630     {
  631         /* Name must appear as the last parameter */
  632 
  633         NextOp = Op->Asl.Child;
  634         while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION))
  635         {
  636             NextOp = NextOp->Asl.Next;
  637         }
  638 
  639         Path = NextOp->Asl.Value.String;
  640     }
  641     else
  642     {
  643         Path = Op->Asl.Value.String;
  644     }
  645 
  646     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
  647     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  648         "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
  649 
  650     /*
  651      * Lookup the name in the namespace. Name must exist at this point, or it
  652      * is an invalid reference.
  653      *
  654      * The namespace is also used as a lookup table for references to resource
  655      * descriptors and the fields within them.
  656      */
  657     AslGbl_NsLookupCount++;
  658 
  659     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
  660         ACPI_IMODE_EXECUTE, Flags, WalkState, &Node);
  661     if (ACPI_FAILURE (Status))
  662     {
  663         if (Status == AE_NOT_FOUND)
  664         {
  665             /*
  666              * We didn't find the name reference by path -- we can qualify this
  667              * a little better before we print an error message
  668              */
  669 
  670             if ((Op->Asl.Parent) &&
  671                 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
  672             {
  673                 /*
  674                  * One special case: CondRefOf operator - if the name doesn't
  675                  * exist at this point, it means that there's no actual or
  676                  * external declaration. If the name is not found, just ignore
  677                  * it, the point of the operator is to determine if the name
  678                  * exists at runtime. We wanted to see if this named object
  679                  * exists to facilitate analysis to allow protected usage of
  680                  * undeclared externals.
  681                  */
  682                 return_ACPI_STATUS (AE_OK);
  683             }
  684             else if (strlen (Path) == ACPI_NAMESEG_SIZE)
  685             {
  686                 /* A simple, one-segment ACPI name */
  687 
  688                 if (XfObjectExists (Path))
  689                 {
  690                     /*
  691                      * There exists such a name, but we couldn't get to it
  692                      * from this scope
  693                      */
  694                     AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
  695                         Op->Asl.ExternalName);
  696                 }
  697                 else
  698                 {
  699                     /* The name doesn't exist, period */
  700 
  701                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
  702                         Op, Op->Asl.ExternalName);
  703                 }
  704             }
  705             else
  706             {
  707                 /* The NamePath contains multiple NameSegs */
  708 
  709                 if ((OpInfo->Flags & AML_CREATE) ||
  710                     (OpInfo->ObjectType == ACPI_TYPE_LOCAL_ALIAS))
  711                 {
  712                     /*
  713                      * The new name is the last parameter. For the
  714                      * CreateXXXXField and Alias operators
  715                      */
  716                     NextOp = Op->Asl.Child;
  717                     while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION))
  718                     {
  719                         NextOp = NextOp->Asl.Next;
  720                     }
  721 
  722                     AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, NextOp,
  723                         NextOp->Asl.ExternalName);
  724                 }
  725                 else if (OpInfo->Flags & AML_NAMED)
  726                 {
  727                     /* The new name is the first parameter */
  728 
  729                     AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, Op,
  730                         Op->Asl.ExternalName);
  731                 }
  732                 else if (Path[0] == AML_ROOT_PREFIX)
  733                 {
  734                     /* Full namepath from root, the object does not exist */
  735 
  736                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
  737                         Op->Asl.ExternalName);
  738                 }
  739                 else
  740                 {
  741                     /*
  742                      * Generic "not found" error. Cannot determine whether it
  743                      * doesn't exist or just can't be reached. However, we
  744                      * can differentiate between a NameSeg vs. NamePath.
  745                      */
  746                     if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
  747                     {
  748                         AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
  749                             Op->Asl.ExternalName);
  750                     }
  751                     else
  752                     {
  753                         AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
  754                             Op->Asl.ExternalName);
  755                     }
  756                 }
  757             }
  758 
  759             Status = AE_OK;
  760         }
  761 
  762         return_ACPI_STATUS (Status);
  763     }
  764 
  765     /* Check for an attempt to access an object in another method */
  766 
  767     if (!XfValidateCrossReference (Op, OpInfo, Node))
  768     {
  769         AslError (ASL_ERROR, ASL_MSG_TEMPORARY_OBJECT, Op,
  770             Op->Asl.ExternalName);
  771         return_ACPI_STATUS (Status);
  772     }
  773 
  774    /* Object was found above, check for an illegal forward reference */
  775 
  776     if (Op->Asl.CompileFlags & OP_NOT_FOUND_DURING_LOAD)
  777     {
  778         /*
  779          * During the load phase, this Op was flagged as a possible
  780          * illegal forward reference. In other words, Op is a name path or
  781          * name segment that refers to a named object declared after the
  782          * reference. In this scinario, Node refers to the actual declaration
  783          * and Op is a parse node that references the named object.
  784          *
  785          * Note:
  786          *
  787          * Object references inside of control methods are allowed to
  788          * refer to objects declared outside of control methods.
  789          *
  790          * If the declaration and reference are both contained inside of the
  791          * same method or outside of any method, this is a forward reference
  792          * and should be reported as a compiler error.
  793          */
  794         DeclarationParentMethod = UtGetParentMethodNode (Node);
  795         ReferenceParentMethod = UtGetParentMethodOp (Op);
  796 
  797         /* case 1: declaration and reference are both outside of method */
  798 
  799         if (!ReferenceParentMethod && !DeclarationParentMethod)
  800         {
  801             AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
  802                 Op->Asl.ExternalName);
  803         }
  804 
  805         /* case 2: declaration and reference are both inside of the same method */
  806 
  807         else if (ReferenceParentMethod && DeclarationParentMethod &&
  808             ReferenceParentMethod == DeclarationParentMethod->Op)
  809         {
  810              AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
  811                 Op->Asl.ExternalName);
  812         }
  813     }
  814 
  815     /* Check for a reference vs. name declaration */
  816 
  817     if (!(OpInfo->Flags & AML_NAMED) &&
  818         !(OpInfo->Flags & AML_CREATE))
  819     {
  820         /* This node has been referenced, mark it for reference check */
  821 
  822         Node->Flags |= ANOBJ_IS_REFERENCED;
  823     }
  824 
  825     /*
  826      * Attempt to optimize the NamePath
  827      *
  828      * One special case: CondRefOf operator - not all AML interpreter
  829      * implementations expect optimized namepaths as a parameter to this
  830      * operator. They require relative name paths with prefix operators or
  831      * namepaths starting with the root scope.
  832      *
  833      * Other AML interpreter implementations do not perform the namespace
  834      * search that starts at the current scope and recursively searching the
  835      * parent scope until the root scope. The lack of search is only known to
  836      * occur for the namestring parameter for the CondRefOf operator.
  837      */
  838     if ((Op->Asl.Parent) &&
  839         (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_CONDREFOF))
  840     {
  841         OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
  842     }
  843 
  844     /*
  845      * 1) Dereference an alias (A name reference that is an alias)
  846      *    Aliases are not nested, the alias always points to the final object
  847      */
  848     if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
  849         (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
  850     {
  851         /* This node points back to the original PARSEOP_ALIAS */
  852 
  853         NextOp = Node->Op;
  854 
  855         /* The first child is the alias target op */
  856 
  857         NextOp = NextOp->Asl.Child;
  858 
  859         /* That in turn points back to original target alias node */
  860 
  861         if (NextOp->Asl.Node)
  862         {
  863             Node = NextOp->Asl.Node;
  864         }
  865 
  866         /* Else - forward reference to alias, will be resolved later */
  867     }
  868 
  869     /* 2) Check for a reference to a resource descriptor */
  870 
  871     if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
  872         (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
  873     {
  874         /*
  875          * This was a reference to a field within a resource descriptor.
  876          * Extract the associated field offset (either a bit or byte
  877          * offset depending on the field type) and change the named
  878          * reference into an integer for AML code generation
  879          */
  880         Offset = Node->Value;
  881         TagBitLength = Node->Length;
  882 
  883         /*
  884          * If a field is being created, generate the length (in bits) of
  885          * the field. Note: Opcodes other than CreateXxxField and Index
  886          * can come through here. For other opcodes, we just need to
  887          * convert the resource tag reference to an integer offset.
  888          */
  889         switch (Op->Asl.Parent->Asl.AmlOpcode)
  890         {
  891         case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */
  892             /*
  893              * We know the length operand is an integer constant because
  894              * we know that it contains a reference to a resource
  895              * descriptor tag.
  896              */
  897             FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer;
  898             break;
  899 
  900         case AML_CREATE_BIT_FIELD_OP:
  901 
  902             FieldBitLength = 1;
  903             break;
  904 
  905         case AML_CREATE_BYTE_FIELD_OP:
  906         case AML_INDEX_OP:
  907 
  908             FieldBitLength = 8;
  909             break;
  910 
  911         case AML_CREATE_WORD_FIELD_OP:
  912 
  913             FieldBitLength = 16;
  914             break;
  915 
  916         case AML_CREATE_DWORD_FIELD_OP:
  917 
  918             FieldBitLength = 32;
  919             break;
  920 
  921         case AML_CREATE_QWORD_FIELD_OP:
  922 
  923             FieldBitLength = 64;
  924             break;
  925 
  926         default:
  927 
  928             FieldBitLength = 0;
  929             break;
  930         }
  931 
  932         /* Check the field length against the length of the resource tag */
  933 
  934         if (FieldBitLength)
  935         {
  936             if (TagBitLength < FieldBitLength)
  937             {
  938                 Message = ASL_MSG_TAG_SMALLER;
  939             }
  940             else if (TagBitLength > FieldBitLength)
  941             {
  942                 Message = ASL_MSG_TAG_LARGER;
  943             }
  944 
  945             if (Message)
  946             {
  947                 sprintf (AslGbl_MsgBuffer,
  948                     "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
  949                     TagBitLength, (TagBitLength > 1) ? "s" : "",
  950                     FieldBitLength, (FieldBitLength > 1) ? "s" : "");
  951 
  952                 AslError (ASL_WARNING, Message, Op, AslGbl_MsgBuffer);
  953             }
  954         }
  955 
  956         /* Convert the BitOffset to a ByteOffset for certain opcodes */
  957 
  958         switch (Op->Asl.Parent->Asl.AmlOpcode)
  959         {
  960         case AML_CREATE_BYTE_FIELD_OP:
  961         case AML_CREATE_WORD_FIELD_OP:
  962         case AML_CREATE_DWORD_FIELD_OP:
  963         case AML_CREATE_QWORD_FIELD_OP:
  964         case AML_INDEX_OP:
  965 
  966             Offset = ACPI_DIV_8 (Offset);
  967             break;
  968 
  969         default:
  970 
  971             break;
  972         }
  973 
  974         /* Now convert this node to an integer whose value is the field offset */
  975 
  976         Op->Asl.AmlLength = 0;
  977         Op->Asl.ParseOpcode = PARSEOP_INTEGER;
  978         Op->Asl.Value.Integer = (UINT64) Offset;
  979         Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD;
  980 
  981         OpcGenerateAmlOpcode (Op);
  982     }
  983 
  984     /* 3) Check for a method invocation */
  985 
  986     else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
  987                 (Node->Type == ACPI_TYPE_METHOD) &&
  988                 (Op->Asl.Parent) &&
  989                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
  990 
  991                 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
  992     {
  993         /*
  994          * A reference to a method within one of these opcodes is not an
  995          * invocation of the method, it is simply a reference to the method.
  996          *
  997          * September 2016: Removed DeRefOf from this list
  998          * July 2020: Added Alias to this list
  999          */
 1000         if ((Op->Asl.Parent) &&
 1001             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)     ||
 1002             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_PACKAGE)    ||
 1003             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)||
 1004             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE) ||
 1005             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_ALIAS)))
 1006         {
 1007             return_ACPI_STATUS (AE_OK);
 1008         }
 1009 
 1010         /*
 1011          * There are two types of method invocation:
 1012          * 1) Invocation with arguments -- the parser recognizes this
 1013          *    as a METHODCALL.
 1014          * 2) Invocation with no arguments --the parser cannot determine that
 1015          *    this is a method invocation, therefore we have to figure it out
 1016          *    here.
 1017          */
 1018         if (Node->Type != ACPI_TYPE_METHOD)
 1019         {
 1020             sprintf (AslGbl_MsgBuffer, "%s is a %s",
 1021                 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
 1022 
 1023             AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, AslGbl_MsgBuffer);
 1024             return_ACPI_STATUS (AE_OK);
 1025         }
 1026 
 1027         /* Save the method node in the caller's op */
 1028 
 1029         Op->Asl.Node = Node;
 1030         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
 1031         {
 1032             return_ACPI_STATUS (AE_OK);
 1033         }
 1034 
 1035         /*
 1036          * This is a method invocation, with or without arguments.
 1037          * Count the number of arguments, each appears as a child
 1038          * under the parent node
 1039          */
 1040         Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
 1041         UtSetParseOpName (Op);
 1042 
 1043         PassedArgs = 0;
 1044         NextOp = Op->Asl.Child;
 1045 
 1046         while (NextOp)
 1047         {
 1048             PassedArgs++;
 1049             NextOp = NextOp->Asl.Next;
 1050         }
 1051 
 1052         if (Node->Value != ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS &&
 1053             Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL)
 1054         {
 1055             /*
 1056              * Check the parsed arguments with the number expected by the
 1057              * method declaration itself
 1058              */
 1059             if (PassedArgs != Node->Value)
 1060             {
 1061                 if (Node->Flags & ANOBJ_IS_EXTERNAL)
 1062                 {
 1063                     sprintf (AslGbl_MsgBuffer,
 1064                         "according to previous use, %s requires %u",
 1065                         Op->Asl.ExternalName, Node->Value);
 1066                 }
 1067                 else
 1068                 {
 1069                     sprintf (AslGbl_MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
 1070                         Node->Value);
 1071                 }
 1072 
 1073                 if (PassedArgs < Node->Value)
 1074                 {
 1075                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, AslGbl_MsgBuffer);
 1076                 }
 1077                 else
 1078                 {
 1079                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, AslGbl_MsgBuffer);
 1080                 }
 1081             }
 1082         }
 1083 
 1084         /*
 1085          * At this point, a method call to an external method has been
 1086          * detected. As of 11/19/2019, iASL does not support parameter counts
 1087          * for methods declared as external. Therefore, save the parameter
 1088          * count of the first method call and use this count check other
 1089          * method calls to ensure that the methods are being called with the
 1090          * same amount of parameters.
 1091          */
 1092         else if (Node->Type == ACPI_TYPE_METHOD &&
 1093             (Node->Flags & ANOBJ_IS_EXTERNAL) &&
 1094             Node->Value == ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS &&
 1095             Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL)
 1096         {
 1097             Node->Value = PassedArgs;
 1098         }
 1099     }
 1100 
 1101     /* 4) Check for an ASL Field definition */
 1102 
 1103     else if ((Op->Asl.Parent) &&
 1104             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
 1105              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
 1106     {
 1107         /*
 1108          * Offset checking for fields. If the parent operation region has a
 1109          * constant length (known at compile time), we can check fields
 1110          * defined in that region against the region length. This will catch
 1111          * fields and field units that cannot possibly fit within the region.
 1112          *
 1113          * Note: Index fields do not directly reference an operation region,
 1114          * thus they are not included in this check.
 1115          */
 1116         if (Op == Op->Asl.Parent->Asl.Child)
 1117         {
 1118             /*
 1119              * This is the first child of the field node, which is
 1120              * the name of the region. Get the parse node for the
 1121              * region -- which contains the length of the region.
 1122              */
 1123             OwningOp = Node->Op;
 1124             Op->Asl.Parent->Asl.ExtraValue =
 1125                 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
 1126 
 1127             /* Examine the field access width */
 1128 
 1129             switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
 1130             {
 1131             case AML_FIELD_ACCESS_ANY:
 1132             case AML_FIELD_ACCESS_BYTE:
 1133             case AML_FIELD_ACCESS_BUFFER:
 1134             default:
 1135 
 1136                 MinimumLength = 1;
 1137                 break;
 1138 
 1139             case AML_FIELD_ACCESS_WORD:
 1140 
 1141                 MinimumLength = 2;
 1142                 break;
 1143 
 1144             case AML_FIELD_ACCESS_DWORD:
 1145 
 1146                 MinimumLength = 4;
 1147                 break;
 1148 
 1149             case AML_FIELD_ACCESS_QWORD:
 1150 
 1151                 MinimumLength = 8;
 1152                 break;
 1153             }
 1154 
 1155             /*
 1156              * Is the region at least as big as the access width?
 1157              * Note: DataTableRegions have 0 length
 1158              */
 1159             if (((UINT32) OwningOp->Asl.Value.Integer) &&
 1160                 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
 1161             {
 1162                 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
 1163             }
 1164 
 1165             /*
 1166              * Check EC/CMOS/SMBUS fields to make sure that the correct
 1167              * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
 1168              */
 1169             SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
 1170             switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
 1171             {
 1172             case ACPI_ADR_SPACE_EC:
 1173             case ACPI_ADR_SPACE_CMOS:
 1174             case ACPI_ADR_SPACE_GPIO:
 1175 
 1176                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
 1177                     AML_FIELD_ACCESS_BYTE)
 1178                 {
 1179                     AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
 1180                 }
 1181                 break;
 1182 
 1183             case ACPI_ADR_SPACE_SMBUS:
 1184             case ACPI_ADR_SPACE_IPMI:
 1185             case ACPI_ADR_SPACE_GSBUS:
 1186 
 1187                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
 1188                     AML_FIELD_ACCESS_BUFFER)
 1189                 {
 1190                     AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
 1191                 }
 1192                 break;
 1193 
 1194             default:
 1195 
 1196                 /* Nothing to do for other address spaces */
 1197 
 1198                 break;
 1199             }
 1200         }
 1201         else
 1202         {
 1203             /*
 1204              * This is one element of the field list. Check to make sure
 1205              * that it does not go beyond the end of the parent operation region.
 1206              *
 1207              * In the code below:
 1208              *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
 1209              *    Op->Asl.ExtraValue                  - Field start offset (bits)
 1210              *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
 1211              *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
 1212              */
 1213             if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
 1214             {
 1215                 XfCheckFieldRange (Op,
 1216                     Op->Asl.Parent->Asl.ExtraValue,
 1217                     Op->Asl.ExtraValue,
 1218                     (UINT32) Op->Asl.Child->Asl.Value.Integer,
 1219                     Op->Asl.Child->Asl.ExtraValue);
 1220             }
 1221         }
 1222     }
 1223 
 1224     /*
 1225      * 5) Check for external resolution
 1226      *
 1227      * By this point, everything should be loaded in the namespace. If a
 1228      * namespace lookup results in a namespace node that is an external, it
 1229      * means that this named object was not defined in the input ASL. This
 1230      * causes issues because there are plenty of incidents where developers
 1231      * use the external keyword to suppress compiler errors about undefined
 1232      * objects. Note: this only applies when compiling multiple definition
 1233      * blocks.
 1234      *
 1235      * Do not check for external resolution in the following cases:
 1236      *
 1237      * case 1) External (ABCD)
 1238      *
 1239      *         This declares ABCD as an external so there is no requirement for
 1240      *         ABCD to be loaded in the namespace when analyzing the actual
 1241      *         External() statement.
 1242      *
 1243      * case 2) CondRefOf (ABCD)
 1244      *
 1245      *         This operator will query the ACPI namespace on the existence of
 1246      *         ABCD. If ABCD does not exist, this operator will return a 0
 1247      *         without incurring AML runtime errors. Therefore, ABCD is allowed
 1248      *         to not exist when analyzing the CondRefOf operator.
 1249      *
 1250      * case 3) External (ABCD)
 1251      *         if (CondRefOf (ABCD))
 1252      *         {
 1253      *             Store (0, ABCD)
 1254      *         }
 1255      *
 1256      *         In this case, ABCD is accessed only if it exists due to the if
 1257      *         statement so there is no need to flag the ABCD nested in the
 1258      *         store operator.
 1259      */
 1260     if (AslGbl_ParseTreeRoot->Asl.Child && AslGbl_ParseTreeRoot->Asl.Child->Asl.Next &&
 1261         (Node->Flags & ANOBJ_IS_EXTERNAL) &&
 1262         Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL &&
 1263         Op->Asl.ParseOpcode != PARSEOP_EXTERNAL &&
 1264         Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_CONDREFOF &&
 1265         !XfRefIsGuardedByIfCondRefOf (Node, Op))
 1266     {
 1267         ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
 1268         sprintf (AslGbl_MsgBuffer, "full path of external object: %s",
 1269             ExternalPath);
 1270         AslDualParseOpError (ASL_ERROR, ASL_MSG_UNDEFINED_EXTERNAL, Op, NULL,
 1271             ASL_MSG_EXTERNAL_FOUND_HERE, Node->Op, AslGbl_MsgBuffer);
 1272         if (ExternalPath)
 1273         {
 1274             ACPI_FREE (ExternalPath);
 1275         }
 1276     }
 1277 
 1278     /* 5) Check for a connection object */
 1279 #if 0
 1280     else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
 1281     {
 1282         return_ACPI_STATUS (Status);
 1283     }
 1284 #endif
 1285 
 1286     Op->Asl.Node = Node;
 1287     return_ACPI_STATUS (Status);
 1288 }
 1289 
 1290 
 1291 /*******************************************************************************
 1292  *
 1293  * FUNCTION:    XfRefIsGuardedByIfCondRefOf
 1294  *
 1295  * PARAMETERS:  Node        - Named object reference node
 1296  *              Op          - Named object reference parse node
 1297  *
 1298  * RETURN:      BOOLEAN
 1299  *
 1300  * DESCRIPTION: returns true if Op checked inside if (CondRefOf (...))
 1301  *              refers to Node.
 1302  *
 1303  ******************************************************************************/
 1304 
 1305 static BOOLEAN
 1306 XfRefIsGuardedByIfCondRefOf (
 1307     ACPI_NAMESPACE_NODE     *Node,
 1308     ACPI_PARSE_OBJECT       *Op)
 1309 {
 1310     ACPI_PARSE_OBJECT       *Parent = Op->Asl.Parent;
 1311 
 1312 
 1313     while (Parent)
 1314     {
 1315         if (Parent->Asl.ParseOpcode == PARSEOP_IF &&
 1316             XfFindCondRefOfName (Node, Parent->Asl.Child))
 1317         {
 1318             return (TRUE);
 1319         }
 1320 
 1321         Parent = Parent->Asl.Parent;
 1322     }
 1323 
 1324     return (FALSE);
 1325 }
 1326 
 1327 
 1328 /*******************************************************************************
 1329  *
 1330  * FUNCTION:    XfRefIsGuardedByIfCondRefOf
 1331  *
 1332  * PARAMETERS:  Node        - Named object reference node
 1333  *              Op          - Named object reference parse node
 1334  *
 1335  * RETURN:      BOOLEAN
 1336  *
 1337  * DESCRIPTION: returns true if Op checked inside if (CondRefOf (...))
 1338  *              refers to Node.
 1339  *
 1340  ******************************************************************************/
 1341 
 1342 static BOOLEAN
 1343 XfFindCondRefOfName (
 1344     ACPI_NAMESPACE_NODE     *Node,
 1345     ACPI_PARSE_OBJECT       *Op)
 1346 {
 1347     BOOLEAN                 CondRefOfFound = FALSE;
 1348 
 1349 
 1350     if (!Op)
 1351     {
 1352         return (FALSE);
 1353     }
 1354 
 1355     switch (Op->Asl.ParseOpcode)
 1356     {
 1357     case PARSEOP_CONDREFOF:
 1358 
 1359         return (Op->Asl.Child->Common.Node == Node);
 1360         break;
 1361 
 1362     case PARSEOP_LAND:
 1363 
 1364         CondRefOfFound = XfFindCondRefOfName (Node, Op->Asl.Child);
 1365         if (CondRefOfFound)
 1366         {
 1367             return (TRUE);
 1368         }
 1369 
 1370         return (XfFindCondRefOfName (Node, Op->Asl.Child->Asl.Next));
 1371         break;
 1372 
 1373     default:
 1374 
 1375         return (FALSE);
 1376         break;
 1377     }
 1378 }
 1379 
 1380 
 1381 /*******************************************************************************
 1382  *
 1383  * FUNCTION:    XfNamespaceLocateEnd
 1384  *
 1385  * PARAMETERS:  ASL_WALK_CALLBACK
 1386  *
 1387  * RETURN:      Status
 1388  *
 1389  * DESCRIPTION: Ascending callback used during cross reference. We only
 1390  *              need to worry about scope management here.
 1391  *
 1392  ******************************************************************************/
 1393 
 1394 static ACPI_STATUS
 1395 XfNamespaceLocateEnd (
 1396     ACPI_PARSE_OBJECT       *Op,
 1397     UINT32                  Level,
 1398     void                    *Context)
 1399 {
 1400     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
 1401     const ACPI_OPCODE_INFO  *OpInfo;
 1402 
 1403 
 1404     ACPI_FUNCTION_TRACE (XfNamespaceLocateEnd);
 1405 
 1406 
 1407     /* We are only interested in opcodes that have an associated name */
 1408 
 1409     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
 1410     if (!(OpInfo->Flags & AML_NAMED))
 1411     {
 1412         return_ACPI_STATUS (AE_OK);
 1413     }
 1414 
 1415     /* Not interested in name references, we did not open a scope for them */
 1416 
 1417     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
 1418         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
 1419         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
 1420         (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
 1421     {
 1422         return_ACPI_STATUS (AE_OK);
 1423     }
 1424 
 1425     /* Pop the scope stack if necessary */
 1426 
 1427     if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
 1428     {
 1429 
 1430         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 1431             "%s: Popping scope for Op %p\n",
 1432             AcpiUtGetTypeName (OpInfo->ObjectType), Op));
 1433 
 1434         (void) AcpiDsScopeStackPop (WalkState);
 1435     }
 1436 
 1437     return_ACPI_STATUS (AE_OK);
 1438 }
 1439 
 1440 
 1441 /*******************************************************************************
 1442  *
 1443  * FUNCTION:    XfValidateCrossReference
 1444  *
 1445  * PARAMETERS:  Op                      - Parse Op that references the object
 1446  *              OpInfo                  - Parse Op info struct
 1447  *              Node                    - Node for the referenced object
 1448  *
 1449  * RETURN:      TRUE if the reference is legal, FALSE otherwise
 1450  *
 1451  * DESCRIPTION: Determine if a reference to another object is allowed.
 1452  *
 1453  * EXAMPLE:
 1454  *      Method (A) {Name (INT1, 1)}     Declaration of object INT1
 1455  *      Method (B) (Store (2, \A.INT1)} Illegal reference to object INT1
 1456  *                                      (INT1 is temporary, valid only during
 1457  *                                      execution of A)
 1458  *
 1459  * NOTES:
 1460  *      A null pointer returned by either UtGetParentMethodOp or
 1461  *      UtGetParentMethodNode indicates that the parameter object is not
 1462  *      within a control method.
 1463  *
 1464  *      Five cases are handled: Case(Op, Node)
 1465  *      1) Case(0,0): Op is not within a method, Node is not    --> OK
 1466  *      2) Case(0,1): Op is not within a method, but Node is    --> Illegal
 1467  *      3) Case(1,0): Op is within a method, Node is not        --> OK
 1468  *      4) Case(1,1): Both are within the same method           --> OK
 1469  *      5) Case(1,1): Both are in methods, but not same method  --> Illegal
 1470  *
 1471  ******************************************************************************/
 1472 
 1473 static BOOLEAN
 1474 XfValidateCrossReference (
 1475     ACPI_PARSE_OBJECT       *Op,
 1476     const ACPI_OPCODE_INFO  *OpInfo,
 1477     ACPI_NAMESPACE_NODE     *Node)
 1478 {
 1479     ACPI_PARSE_OBJECT       *ReferencingMethodOp;
 1480     ACPI_NAMESPACE_NODE     *ReferencedMethodNode;
 1481 
 1482 
 1483     /* Ignore actual named (and related) object declarations */
 1484 
 1485     if (OpInfo->Flags & (AML_NAMED | AML_CREATE | AML_DEFER | AML_HAS_ARGS))
 1486     {
 1487         return (TRUE);
 1488     }
 1489 
 1490     /*
 1491      * 1) Search upwards in parse tree for owner of the referencing object
 1492      * 2) Search upwards in namespace to find the owner of the referenced object
 1493      */
 1494     ReferencingMethodOp = UtGetParentMethodOp (Op);
 1495     ReferencedMethodNode = UtGetParentMethodNode (Node);
 1496 
 1497     if (!ReferencingMethodOp && !ReferencedMethodNode)
 1498     {
 1499         /*
 1500          * 1) Case (0,0): Both Op and Node are not within methods
 1501          * --> OK
 1502          */
 1503         return (TRUE);
 1504     }
 1505 
 1506     if (!ReferencingMethodOp && ReferencedMethodNode)
 1507     {
 1508         /*
 1509          * 2) Case (0,1): Op is not in a method, but Node is within a
 1510          * method --> illegal
 1511          */
 1512         return (FALSE);
 1513     }
 1514     else if (ReferencingMethodOp && !ReferencedMethodNode)
 1515     {
 1516         /*
 1517          * 3) Case (1,0): Op is within a method, but Node is not
 1518          * --> OK
 1519          */
 1520         return (TRUE);
 1521     }
 1522     else if (ReferencingMethodOp->Asl.Node == ReferencedMethodNode)
 1523     {
 1524         /*
 1525          * 4) Case (1,1): Both Op and Node are within the same method
 1526          * --> OK
 1527          */
 1528         return (TRUE);
 1529     }
 1530     else
 1531     {
 1532         /*
 1533          * 5) Case (1,1), Op and Node are in different methods
 1534          * --> Illegal
 1535          */
 1536         return (FALSE);
 1537     }
 1538 }

Cache object: 08cdd01b9adb683164fe571650b80bef


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.