Home | History | Annotate | Line # | Download | only in compiler
aslxref.c revision 1.10.2.2
      1 /******************************************************************************
      2  *
      3  * Module Name: aslxref - Namespace cross-reference
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2018, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "aslcompiler.h"
     45 #include "aslcompiler.y.h"
     46 #include "acparser.h"
     47 #include "amlcode.h"
     48 #include "acnamesp.h"
     49 #include "acdispat.h"
     50 
     51 
     52 #define _COMPONENT          ACPI_COMPILER
     53         ACPI_MODULE_NAME    ("aslxref")
     54 
     55 /* Local prototypes */
     56 
     57 static ACPI_STATUS
     58 XfNamespaceLocateBegin (
     59     ACPI_PARSE_OBJECT       *Op,
     60     UINT32                  Level,
     61     void                    *Context);
     62 
     63 static ACPI_STATUS
     64 XfNamespaceLocateEnd (
     65     ACPI_PARSE_OBJECT       *Op,
     66     UINT32                  Level,
     67     void                    *Context);
     68 
     69 static ACPI_PARSE_OBJECT *
     70 XfGetParentMethod (
     71     ACPI_PARSE_OBJECT       *Op);
     72 
     73 static BOOLEAN
     74 XfObjectExists (
     75     char                    *Name);
     76 
     77 static ACPI_STATUS
     78 XfCompareOneNamespaceObject (
     79     ACPI_HANDLE             ObjHandle,
     80     UINT32                  Level,
     81     void                    *Context,
     82     void                    **ReturnValue);
     83 
     84 static void
     85 XfCheckFieldRange (
     86     ACPI_PARSE_OBJECT       *Op,
     87     UINT32                  RegionBitLength,
     88     UINT32                  FieldBitOffset,
     89     UINT32                  FieldBitLength,
     90     UINT32                  AccessBitWidth);
     91 
     92 
     93 /*******************************************************************************
     94  *
     95  * FUNCTION:    XfCrossReferenceNamespace
     96  *
     97  * PARAMETERS:  None
     98  *
     99  * RETURN:      Status
    100  *
    101  * DESCRIPTION: Perform a cross reference check of the parse tree against the
    102  *              namespace. Every named referenced within the parse tree
    103  *              should be get resolved with a namespace lookup. If not, the
    104  *              original reference in the ASL code is invalid -- i.e., refers
    105  *              to a non-existent object.
    106  *
    107  * NOTE:  The ASL "External" operator causes the name to be inserted into the
    108  *        namespace so that references to the external name will be resolved
    109  *        correctly here.
    110  *
    111  ******************************************************************************/
    112 
    113 ACPI_STATUS
    114 XfCrossReferenceNamespace (
    115     void)
    116 {
    117     ACPI_WALK_STATE         *WalkState;
    118 
    119 
    120     /*
    121      * Create a new walk state for use when looking up names
    122      * within the namespace (Passed as context to the callbacks)
    123      */
    124     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    125     if (!WalkState)
    126     {
    127         return (AE_NO_MEMORY);
    128     }
    129 
    130     /* Walk the entire parse tree */
    131 
    132     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    133         XfNamespaceLocateBegin, XfNamespaceLocateEnd, WalkState);
    134 
    135     ACPI_FREE (WalkState);
    136     return (AE_OK);
    137 }
    138 
    139 
    140 /*******************************************************************************
    141  *
    142  * FUNCTION:    XfObjectExists
    143  *
    144  * PARAMETERS:  Name            - 4 char ACPI name
    145  *
    146  * RETURN:      TRUE if name exists in namespace
    147  *
    148  * DESCRIPTION: Walk the namespace to find an object
    149  *
    150  ******************************************************************************/
    151 
    152 static BOOLEAN
    153 XfObjectExists (
    154     char                    *Name)
    155 {
    156     ACPI_STATUS             Status;
    157 
    158 
    159     /* Walk entire namespace from the supplied root */
    160 
    161     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    162         ACPI_UINT32_MAX, FALSE, XfCompareOneNamespaceObject, NULL,
    163         Name, NULL);
    164     if (Status == AE_CTRL_TRUE)
    165     {
    166         /* At least one instance of the name was found */
    167 
    168         return (TRUE);
    169     }
    170 
    171     return (FALSE);
    172 }
    173 
    174 
    175 /*******************************************************************************
    176  *
    177  * FUNCTION:    XfCompareOneNamespaceObject
    178  *
    179  * PARAMETERS:  ACPI_WALK_CALLBACK
    180  *
    181  * RETURN:      Status
    182  *
    183  * DESCRIPTION: Compare name of one object.
    184  *
    185  ******************************************************************************/
    186 
    187 static ACPI_STATUS
    188 XfCompareOneNamespaceObject (
    189     ACPI_HANDLE             ObjHandle,
    190     UINT32                  Level,
    191     void                    *Context,
    192     void                    **ReturnValue)
    193 {
    194     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    195 
    196 
    197     /* Simply check the name */
    198 
    199     if (*((UINT32 *) (Context)) == Node->Name.Integer)
    200     {
    201         /* Abort walk if we found one instance */
    202 
    203         return (AE_CTRL_TRUE);
    204     }
    205 
    206     return (AE_OK);
    207 }
    208 
    209 
    210 /*******************************************************************************
    211  *
    212  * FUNCTION:    XfCheckFieldRange
    213  *
    214  * PARAMETERS:  RegionBitLength     - Length of entire parent region
    215  *              FieldBitOffset      - Start of the field unit (within region)
    216  *              FieldBitLength      - Entire length of field unit
    217  *              AccessBitWidth      - Access width of the field unit
    218  *
    219  * RETURN:      None
    220  *
    221  * DESCRIPTION: Check one field unit to make sure it fits in the parent
    222  *              op region.
    223  *
    224  * Note: AccessBitWidth must be either 8,16,32, or 64
    225  *
    226  ******************************************************************************/
    227 
    228 static void
    229 XfCheckFieldRange (
    230     ACPI_PARSE_OBJECT       *Op,
    231     UINT32                  RegionBitLength,
    232     UINT32                  FieldBitOffset,
    233     UINT32                  FieldBitLength,
    234     UINT32                  AccessBitWidth)
    235 {
    236     UINT32                  FieldEndBitOffset;
    237 
    238 
    239     /*
    240      * Check each field unit against the region size. The entire
    241      * field unit (start offset plus length) must fit within the
    242      * region.
    243      */
    244     FieldEndBitOffset = FieldBitOffset + FieldBitLength;
    245 
    246     if (FieldEndBitOffset > RegionBitLength)
    247     {
    248         /* Field definition itself is beyond the end-of-region */
    249 
    250         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
    251         return;
    252     }
    253 
    254     /*
    255      * Now check that the field plus AccessWidth doesn't go beyond
    256      * the end-of-region. Assumes AccessBitWidth is a power of 2
    257      */
    258     FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
    259 
    260     if (FieldEndBitOffset > RegionBitLength)
    261     {
    262         /* Field definition combined with the access is beyond EOR */
    263 
    264         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
    265     }
    266 }
    267 
    268 
    269 /*******************************************************************************
    270  *
    271  * FUNCTION:    XfGetParentMethod
    272  *
    273  * PARAMETERS:  Op                      - Parse Op to be checked
    274  *
    275  * RETURN:      Control method Op if found. NULL otherwise
    276  *
    277  * DESCRIPTION: Find the control method parent of a parse op. Returns NULL if
    278  *              the input Op is not within a control method.
    279  *
    280  ******************************************************************************/
    281 
    282 static ACPI_PARSE_OBJECT *
    283 XfGetParentMethod (
    284     ACPI_PARSE_OBJECT       *Op)
    285 {
    286     ACPI_PARSE_OBJECT       *NextOp;
    287 
    288 
    289     NextOp = Op->Asl.Parent;
    290     while (NextOp)
    291     {
    292         if (NextOp->Asl.AmlOpcode == AML_METHOD_OP)
    293         {
    294             return (NextOp);
    295         }
    296 
    297         NextOp = NextOp->Asl.Parent;
    298     }
    299 
    300     return (NULL); /* No parent method found */
    301 }
    302 
    303 /*******************************************************************************
    304  *
    305  * FUNCTION:    XfNamespaceLocateBegin
    306  *
    307  * PARAMETERS:  ASL_WALK_CALLBACK
    308  *
    309  * RETURN:      Status
    310  *
    311  * DESCRIPTION: Descending callback used during cross-reference. For named
    312  *              object references, attempt to locate the name in the
    313  *              namespace.
    314  *
    315  * NOTE: ASL references to named fields within resource descriptors are
    316  *       resolved to integer values here. Therefore, this step is an
    317  *       important part of the code generation. We don't know that the
    318  *       name refers to a resource descriptor until now.
    319  *
    320  ******************************************************************************/
    321 
    322 static ACPI_STATUS
    323 XfNamespaceLocateBegin (
    324     ACPI_PARSE_OBJECT       *Op,
    325     UINT32                  Level,
    326     void                    *Context)
    327 {
    328     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
    329     ACPI_NAMESPACE_NODE     *Node;
    330     ACPI_STATUS             Status;
    331     ACPI_OBJECT_TYPE        ObjectType;
    332     char                    *Path;
    333     UINT8                   PassedArgs;
    334     ACPI_PARSE_OBJECT       *NextOp;
    335     ACPI_PARSE_OBJECT       *OwningOp;
    336     ACPI_PARSE_OBJECT       *SpaceIdOp;
    337     UINT32                  MinimumLength;
    338     UINT32                  Offset;
    339     UINT32                  FieldBitLength;
    340     UINT32                  TagBitLength;
    341     UINT8                   Message = 0;
    342     const ACPI_OPCODE_INFO  *OpInfo;
    343     UINT32                  Flags;
    344     ASL_METHOD_LOCAL        *MethodLocals = NULL;
    345     ASL_METHOD_LOCAL        *MethodArgs = NULL;
    346     int                     RegisterNumber;
    347     UINT32                  i;
    348 
    349 
    350     ACPI_FUNCTION_TRACE_PTR (XfNamespaceLocateBegin, Op);
    351 
    352 
    353     if ((Op->Asl.AmlOpcode == AML_METHOD_OP) && Op->Asl.Node)
    354     {
    355         Node = Op->Asl.Node;
    356 
    357         /* Support for method LocalX/ArgX analysis */
    358 
    359         if (!Node->MethodLocals)
    360         {
    361             /* Create local/arg info blocks */
    362 
    363             MethodLocals = UtLocalCalloc (
    364                 sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_LOCALS);
    365             Node->MethodLocals = MethodLocals;
    366 
    367             MethodArgs = UtLocalCalloc (
    368                 sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_ARGS);
    369             Node->MethodArgs = MethodArgs;
    370 
    371             /*
    372              * Get the method argument count
    373              * First, get the name node
    374              */
    375             NextOp = Op->Asl.Child;
    376 
    377             /* Get the NumArguments node */
    378 
    379             NextOp = NextOp->Asl.Next;
    380             Node->ArgCount = (UINT8)
    381                 (((UINT8) NextOp->Asl.Value.Integer) & 0x07);
    382 
    383             /* We will track all posible ArgXs */
    384 
    385             for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
    386             {
    387                 if (i < Node->ArgCount)
    388                 {
    389                     /* Real Args are always "initialized" */
    390 
    391                     MethodArgs[i].Flags = ASL_ARG_INITIALIZED;
    392                 }
    393                 else
    394                 {
    395                     /* Other ArgXs can be used as locals */
    396 
    397                     MethodArgs[i].Flags = ASL_ARG_IS_LOCAL;
    398                 }
    399 
    400                 MethodArgs[i].Op = Op;
    401             }
    402         }
    403     }
    404 
    405     /*
    406      * If this node is the actual declaration of a name
    407      * [such as the XXXX name in "Method (XXXX)"],
    408      * we are not interested in it here. We only care about names that are
    409      * references to other objects within the namespace and the parent objects
    410      * of name declarations
    411      */
    412     if (Op->Asl.CompileFlags & OP_IS_NAME_DECLARATION)
    413     {
    414         return_ACPI_STATUS (AE_OK);
    415     }
    416 
    417     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    418 
    419     /* Check method LocalX variables */
    420 
    421     if (OpInfo->Type == AML_TYPE_LOCAL_VARIABLE)
    422     {
    423         /* Find parent method Op */
    424 
    425         NextOp = XfGetParentMethod (Op);
    426         if (!NextOp)
    427         {
    428             return_ACPI_STATUS (AE_OK);
    429         }
    430 
    431         /* Get method node */
    432 
    433         Node = NextOp->Asl.Node;
    434 
    435         RegisterNumber = Op->Asl.AmlOpcode & 0x0007; /* 0x60 through 0x67 */
    436         MethodLocals = Node->MethodLocals;
    437 
    438         if (Op->Asl.CompileFlags & OP_IS_TARGET)
    439         {
    440             /* Local is being initialized */
    441 
    442             MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_INITIALIZED;
    443             MethodLocals[RegisterNumber].Op = Op;
    444 
    445             return_ACPI_STATUS (AE_OK);
    446         }
    447 
    448         /* Mark this Local as referenced */
    449 
    450         MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_REFERENCED;
    451         MethodLocals[RegisterNumber].Op = Op;
    452 
    453         return_ACPI_STATUS (AE_OK);
    454     }
    455 
    456     /* Check method ArgX variables */
    457 
    458     if (OpInfo->Type == AML_TYPE_METHOD_ARGUMENT)
    459     {
    460         /* Find parent method Op */
    461 
    462         NextOp = XfGetParentMethod (Op);
    463         if (!NextOp)
    464         {
    465             return_ACPI_STATUS (AE_OK);
    466         }
    467 
    468         /* Get method node */
    469 
    470         Node = NextOp->Asl.Node;
    471 
    472         /* Get Arg # */
    473 
    474         RegisterNumber = Op->Asl.AmlOpcode - AML_ARG0; /* 0x68 through 0x6F */
    475         MethodArgs = Node->MethodArgs;
    476 
    477         /* Mark this Arg as referenced */
    478 
    479         MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED;
    480         MethodArgs[RegisterNumber].Op = Op;
    481 
    482         if (Op->Asl.CompileFlags & OP_IS_TARGET)
    483         {
    484             /* Arg is being initialized */
    485 
    486             MethodArgs[RegisterNumber].Flags |= ASL_ARG_INITIALIZED;
    487         }
    488 
    489         return_ACPI_STATUS (AE_OK);
    490     }
    491 
    492     /*
    493      * After method ArgX and LocalX, we are only interested in opcodes
    494      * that have an associated name
    495      */
    496     if ((!(OpInfo->Flags & AML_NAMED)) &&
    497         (!(OpInfo->Flags & AML_CREATE)) &&
    498         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
    499         (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
    500         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL) &&
    501         (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
    502     {
    503         return_ACPI_STATUS (AE_OK);
    504     }
    505 
    506     /*
    507      * One special case: CondRefOf operator - we don't care if the name exists
    508      * or not at this point, just ignore it, the point of the operator is to
    509      * determine if the name exists at runtime.
    510      */
    511     if ((Op->Asl.Parent) &&
    512         (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
    513     {
    514         return_ACPI_STATUS (AE_OK);
    515     }
    516 
    517     /*
    518      * We must enable the "search-to-root" for single NameSegs, but
    519      * we have to be very careful about opening up scopes
    520      */
    521     Flags = ACPI_NS_SEARCH_PARENT;
    522     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
    523         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
    524         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
    525         (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
    526     {
    527         /*
    528          * These are name references, do not push the scope stack
    529          * for them.
    530          */
    531         Flags |= ACPI_NS_DONT_OPEN_SCOPE;
    532     }
    533 
    534     /* Get the NamePath from the appropriate place */
    535 
    536     if (OpInfo->Flags & AML_NAMED)
    537     {
    538         /* For nearly all NAMED operators, the name reference is the first child */
    539 
    540         Path = Op->Asl.Child->Asl.Value.String;
    541         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
    542         {
    543             /*
    544              * ALIAS is the only oddball opcode, the name declaration
    545              * (alias name) is the second operand
    546              */
    547             Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
    548         }
    549     }
    550     else if (OpInfo->Flags & AML_CREATE)
    551     {
    552         /* Name must appear as the last parameter */
    553 
    554         NextOp = Op->Asl.Child;
    555         while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION))
    556         {
    557             NextOp = NextOp->Asl.Next;
    558         }
    559 
    560         Path = NextOp->Asl.Value.String;
    561     }
    562     else
    563     {
    564         Path = Op->Asl.Value.String;
    565     }
    566 
    567     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
    568     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
    569         "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
    570 
    571     /*
    572      * Lookup the name in the namespace. Name must exist at this point, or it
    573      * is an invalid reference.
    574      *
    575      * The namespace is also used as a lookup table for references to resource
    576      * descriptors and the fields within them.
    577      */
    578     Gbl_NsLookupCount++;
    579 
    580     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
    581         ACPI_IMODE_EXECUTE, Flags, WalkState, &Node);
    582     if (ACPI_FAILURE (Status))
    583     {
    584         if (Status == AE_NOT_FOUND)
    585         {
    586             /*
    587              * We didn't find the name reference by path -- we can qualify this
    588              * a little better before we print an error message
    589              */
    590             if (strlen (Path) == ACPI_NAME_SIZE)
    591             {
    592                 /* A simple, one-segment ACPI name */
    593 
    594                 if (XfObjectExists (Path))
    595                 {
    596                     /*
    597                      * There exists such a name, but we couldn't get to it
    598                      * from this scope
    599                      */
    600                     AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
    601                         Op->Asl.ExternalName);
    602                 }
    603                 else
    604                 {
    605                     /* The name doesn't exist, period */
    606 
    607                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
    608                         Op, Op->Asl.ExternalName);
    609                 }
    610             }
    611             else
    612             {
    613                 /* Check for a fully qualified path */
    614 
    615                 if (Path[0] == AML_ROOT_PREFIX)
    616                 {
    617                     /* Gave full path, the object does not exist */
    618 
    619                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
    620                         Op->Asl.ExternalName);
    621                 }
    622                 else
    623                 {
    624                     /*
    625                      * We can't tell whether it doesn't exist or just
    626                      * can't be reached.
    627                      */
    628                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
    629                         Op->Asl.ExternalName);
    630                 }
    631             }
    632 
    633             Status = AE_OK;
    634         }
    635 
    636         return_ACPI_STATUS (Status);
    637     }
    638 
    639     /* Object was found above, check for an illegal forward reference */
    640 
    641     if (Op->Asl.CompileFlags & OP_NOT_FOUND_DURING_LOAD)
    642     {
    643         /*
    644          * During the load phase, this Op was flagged as a possible
    645          * illegal forward reference
    646          *
    647          * Note: Allow "forward references" from within a method to an
    648          * object that is not within any method (module-level code)
    649          */
    650         if (!WalkState->ScopeInfo || (UtGetParentMethod (Node) &&
    651             !UtNodeIsDescendantOf (WalkState->ScopeInfo->Scope.Node,
    652                 UtGetParentMethod (Node))))
    653         {
    654             AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
    655                 Op->Asl.ExternalName);
    656         }
    657     }
    658 
    659     /* Check for a reference vs. name declaration */
    660 
    661     if (!(OpInfo->Flags & AML_NAMED) &&
    662         !(OpInfo->Flags & AML_CREATE))
    663     {
    664         /* This node has been referenced, mark it for reference check */
    665 
    666         Node->Flags |= ANOBJ_IS_REFERENCED;
    667     }
    668 
    669     /* Attempt to optimize the NamePath */
    670 
    671     OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
    672 
    673     /*
    674      * 1) Dereference an alias (A name reference that is an alias)
    675      *    Aliases are not nested, the alias always points to the final object
    676      */
    677     if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
    678         (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
    679     {
    680         /* This node points back to the original PARSEOP_ALIAS */
    681 
    682         NextOp = Node->Op;
    683 
    684         /* The first child is the alias target op */
    685 
    686         NextOp = NextOp->Asl.Child;
    687 
    688         /* That in turn points back to original target alias node */
    689 
    690         if (NextOp->Asl.Node)
    691         {
    692             Node = NextOp->Asl.Node;
    693         }
    694 
    695         /* Else - forward reference to alias, will be resolved later */
    696     }
    697 
    698     /* 2) Check for a reference to a resource descriptor */
    699 
    700     if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
    701         (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
    702     {
    703         /*
    704          * This was a reference to a field within a resource descriptor.
    705          * Extract the associated field offset (either a bit or byte
    706          * offset depending on the field type) and change the named
    707          * reference into an integer for AML code generation
    708          */
    709         Offset = Node->Value;
    710         TagBitLength = Node->Length;
    711 
    712         /*
    713          * If a field is being created, generate the length (in bits) of
    714          * the field. Note: Opcodes other than CreateXxxField and Index
    715          * can come through here. For other opcodes, we just need to
    716          * convert the resource tag reference to an integer offset.
    717          */
    718         switch (Op->Asl.Parent->Asl.AmlOpcode)
    719         {
    720         case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */
    721             /*
    722              * We know the length operand is an integer constant because
    723              * we know that it contains a reference to a resource
    724              * descriptor tag.
    725              */
    726             FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer;
    727             break;
    728 
    729         case AML_CREATE_BIT_FIELD_OP:
    730 
    731             FieldBitLength = 1;
    732             break;
    733 
    734         case AML_CREATE_BYTE_FIELD_OP:
    735         case AML_INDEX_OP:
    736 
    737             FieldBitLength = 8;
    738             break;
    739 
    740         case AML_CREATE_WORD_FIELD_OP:
    741 
    742             FieldBitLength = 16;
    743             break;
    744 
    745         case AML_CREATE_DWORD_FIELD_OP:
    746 
    747             FieldBitLength = 32;
    748             break;
    749 
    750         case AML_CREATE_QWORD_FIELD_OP:
    751 
    752             FieldBitLength = 64;
    753             break;
    754 
    755         default:
    756 
    757             FieldBitLength = 0;
    758             break;
    759         }
    760 
    761         /* Check the field length against the length of the resource tag */
    762 
    763         if (FieldBitLength)
    764         {
    765             if (TagBitLength < FieldBitLength)
    766             {
    767                 Message = ASL_MSG_TAG_SMALLER;
    768             }
    769             else if (TagBitLength > FieldBitLength)
    770             {
    771                 Message = ASL_MSG_TAG_LARGER;
    772             }
    773 
    774             if (Message)
    775             {
    776                 snprintf (MsgBuffer, sizeof(MsgBuffer),
    777                     "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
    778                     TagBitLength, (TagBitLength > 1) ? "s" : "",
    779                     FieldBitLength, (FieldBitLength > 1) ? "s" : "");
    780 
    781                 AslError (ASL_WARNING, Message, Op, MsgBuffer);
    782             }
    783         }
    784 
    785         /* Convert the BitOffset to a ByteOffset for certain opcodes */
    786 
    787         switch (Op->Asl.Parent->Asl.AmlOpcode)
    788         {
    789         case AML_CREATE_BYTE_FIELD_OP:
    790         case AML_CREATE_WORD_FIELD_OP:
    791         case AML_CREATE_DWORD_FIELD_OP:
    792         case AML_CREATE_QWORD_FIELD_OP:
    793         case AML_INDEX_OP:
    794 
    795             Offset = ACPI_DIV_8 (Offset);
    796             break;
    797 
    798         default:
    799 
    800             break;
    801         }
    802 
    803         /* Now convert this node to an integer whose value is the field offset */
    804 
    805         Op->Asl.AmlLength = 0;
    806         Op->Asl.ParseOpcode = PARSEOP_INTEGER;
    807         Op->Asl.Value.Integer = (UINT64) Offset;
    808         Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD;
    809 
    810         OpcGenerateAmlOpcode (Op);
    811     }
    812 
    813     /* 3) Check for a method invocation */
    814 
    815     else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
    816                 (Node->Type == ACPI_TYPE_METHOD) &&
    817                 (Op->Asl.Parent) &&
    818                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
    819 
    820                 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
    821     {
    822         /*
    823          * A reference to a method within one of these opcodes is not an
    824          * invocation of the method, it is simply a reference to the method.
    825          *
    826          * September 2016: Removed DeRefOf from this list
    827          */
    828         if ((Op->Asl.Parent) &&
    829             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)     ||
    830             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_PACKAGE)    ||
    831             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)||
    832             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
    833         {
    834             return_ACPI_STATUS (AE_OK);
    835         }
    836 
    837         /*
    838          * There are two types of method invocation:
    839          * 1) Invocation with arguments -- the parser recognizes this
    840          *    as a METHODCALL.
    841          * 2) Invocation with no arguments --the parser cannot determine that
    842          *    this is a method invocation, therefore we have to figure it out
    843          *    here.
    844          */
    845         if (Node->Type != ACPI_TYPE_METHOD)
    846         {
    847             snprintf (MsgBuffer, sizeof(MsgBuffer), "%s is a %s",
    848                 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
    849 
    850             AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
    851             return_ACPI_STATUS (AE_OK);
    852         }
    853 
    854         /* Save the method node in the caller's op */
    855 
    856         Op->Asl.Node = Node;
    857         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
    858         {
    859             return_ACPI_STATUS (AE_OK);
    860         }
    861 
    862         /*
    863          * This is a method invocation, with or without arguments.
    864          * Count the number of arguments, each appears as a child
    865          * under the parent node
    866          */
    867         Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
    868         UtSetParseOpName (Op);
    869 
    870         PassedArgs = 0;
    871         NextOp = Op->Asl.Child;
    872 
    873         while (NextOp)
    874         {
    875             PassedArgs++;
    876             NextOp = NextOp->Asl.Next;
    877         }
    878 
    879         if (Node->Value != ASL_EXTERNAL_METHOD &&
    880             Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL)
    881         {
    882             /*
    883              * Check the parsed arguments with the number expected by the
    884              * method declaration itself
    885              */
    886             if (PassedArgs != Node->Value)
    887             {
    888                 snprintf (MsgBuffer, sizeof(MsgBuffer), "%s requires %u", Op->Asl.ExternalName,
    889                             Node->Value);
    890 
    891                 if (PassedArgs < Node->Value)
    892                 {
    893                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
    894                 }
    895                 else
    896                 {
    897                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
    898                 }
    899             }
    900         }
    901     }
    902 
    903     /* 4) Check for an ASL Field definition */
    904 
    905     else if ((Op->Asl.Parent) &&
    906             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
    907              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
    908     {
    909         /*
    910          * Offset checking for fields. If the parent operation region has a
    911          * constant length (known at compile time), we can check fields
    912          * defined in that region against the region length. This will catch
    913          * fields and field units that cannot possibly fit within the region.
    914          *
    915          * Note: Index fields do not directly reference an operation region,
    916          * thus they are not included in this check.
    917          */
    918         if (Op == Op->Asl.Parent->Asl.Child)
    919         {
    920             /*
    921              * This is the first child of the field node, which is
    922              * the name of the region. Get the parse node for the
    923              * region -- which contains the length of the region.
    924              */
    925             OwningOp = Node->Op;
    926             Op->Asl.Parent->Asl.ExtraValue =
    927                 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
    928 
    929             /* Examine the field access width */
    930 
    931             switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
    932             {
    933             case AML_FIELD_ACCESS_ANY:
    934             case AML_FIELD_ACCESS_BYTE:
    935             case AML_FIELD_ACCESS_BUFFER:
    936             default:
    937 
    938                 MinimumLength = 1;
    939                 break;
    940 
    941             case AML_FIELD_ACCESS_WORD:
    942 
    943                 MinimumLength = 2;
    944                 break;
    945 
    946             case AML_FIELD_ACCESS_DWORD:
    947 
    948                 MinimumLength = 4;
    949                 break;
    950 
    951             case AML_FIELD_ACCESS_QWORD:
    952 
    953                 MinimumLength = 8;
    954                 break;
    955             }
    956 
    957             /*
    958              * Is the region at least as big as the access width?
    959              * Note: DataTableRegions have 0 length
    960              */
    961             if (((UINT32) OwningOp->Asl.Value.Integer) &&
    962                 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
    963             {
    964                 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
    965             }
    966 
    967             /*
    968              * Check EC/CMOS/SMBUS fields to make sure that the correct
    969              * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
    970              */
    971             SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
    972             switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
    973             {
    974             case ACPI_ADR_SPACE_EC:
    975             case ACPI_ADR_SPACE_CMOS:
    976             case ACPI_ADR_SPACE_GPIO:
    977 
    978                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
    979                     AML_FIELD_ACCESS_BYTE)
    980                 {
    981                     AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
    982                 }
    983                 break;
    984 
    985             case ACPI_ADR_SPACE_SMBUS:
    986             case ACPI_ADR_SPACE_IPMI:
    987             case ACPI_ADR_SPACE_GSBUS:
    988 
    989                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
    990                     AML_FIELD_ACCESS_BUFFER)
    991                 {
    992                     AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
    993                 }
    994                 break;
    995 
    996             default:
    997 
    998                 /* Nothing to do for other address spaces */
    999 
   1000                 break;
   1001             }
   1002         }
   1003         else
   1004         {
   1005             /*
   1006              * This is one element of the field list. Check to make sure
   1007              * that it does not go beyond the end of the parent operation region.
   1008              *
   1009              * In the code below:
   1010              *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
   1011              *    Op->Asl.ExtraValue                  - Field start offset (bits)
   1012              *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
   1013              *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
   1014              */
   1015             if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
   1016             {
   1017                 XfCheckFieldRange (Op,
   1018                     Op->Asl.Parent->Asl.ExtraValue,
   1019                     Op->Asl.ExtraValue,
   1020                     (UINT32) Op->Asl.Child->Asl.Value.Integer,
   1021                     Op->Asl.Child->Asl.ExtraValue);
   1022             }
   1023         }
   1024     }
   1025 
   1026     /* 5) Check for a connection object */
   1027 #if 0
   1028     else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
   1029     {
   1030         return_ACPI_STATUS (Status);
   1031     }
   1032 #endif
   1033 
   1034     Op->Asl.Node = Node;
   1035     return_ACPI_STATUS (Status);
   1036 }
   1037 
   1038 
   1039 /*******************************************************************************
   1040  *
   1041  * FUNCTION:    XfNamespaceLocateEnd
   1042  *
   1043  * PARAMETERS:  ASL_WALK_CALLBACK
   1044  *
   1045  * RETURN:      Status
   1046  *
   1047  * DESCRIPTION: Ascending callback used during cross reference. We only
   1048  *              need to worry about scope management here.
   1049  *
   1050  ******************************************************************************/
   1051 
   1052 static ACPI_STATUS
   1053 XfNamespaceLocateEnd (
   1054     ACPI_PARSE_OBJECT       *Op,
   1055     UINT32                  Level,
   1056     void                    *Context)
   1057 {
   1058     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
   1059     const ACPI_OPCODE_INFO  *OpInfo;
   1060 
   1061 
   1062     ACPI_FUNCTION_TRACE (XfNamespaceLocateEnd);
   1063 
   1064 
   1065     /* We are only interested in opcodes that have an associated name */
   1066 
   1067     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
   1068     if (!(OpInfo->Flags & AML_NAMED))
   1069     {
   1070         return_ACPI_STATUS (AE_OK);
   1071     }
   1072 
   1073     /* Not interested in name references, we did not open a scope for them */
   1074 
   1075     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
   1076         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
   1077         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
   1078         (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
   1079     {
   1080         return_ACPI_STATUS (AE_OK);
   1081     }
   1082 
   1083     /* Pop the scope stack if necessary */
   1084 
   1085     if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
   1086     {
   1087 
   1088         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
   1089             "%s: Popping scope for Op %p\n",
   1090             AcpiUtGetTypeName (OpInfo->ObjectType), Op));
   1091 
   1092         (void) AcpiDsScopeStackPop (WalkState);
   1093     }
   1094 
   1095     return_ACPI_STATUS (AE_OK);
   1096 }
   1097