/******************************************************************************
 *
 * Module Name: aslxref - Namespace cross-reference
 *
 *****************************************************************************/

/*
 * Copyright (C) 2000 - 2023, Intel Corp.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include "aslcompiler.h"
#include "aslcompiler.y.h"
#include "acparser.h"
#include "amlcode.h"
#include "acnamesp.h"
#include "acdispat.h"


#define _COMPONENT          ACPI_COMPILER
        ACPI_MODULE_NAME    ("aslxref")

/* Local prototypes */

static ACPI_STATUS
XfNamespaceLocateBegin (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  Level,
    void                    *Context);

static ACPI_STATUS
XfNamespaceLocateEnd (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  Level,
    void                    *Context);

static BOOLEAN
XfValidateCrossReference (
    ACPI_PARSE_OBJECT       *Op,
    const ACPI_OPCODE_INFO  *OpInfo,
    ACPI_NAMESPACE_NODE     *Node);

static BOOLEAN
XfObjectExists (
    char                    *Name);

static ACPI_STATUS
XfCompareOneNamespaceObject (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue);

static void
XfCheckFieldRange (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  RegionBitLength,
    UINT32                  FieldBitOffset,
    UINT32                  FieldBitLength,
    UINT32                  AccessBitWidth);

static BOOLEAN
XfFindCondRefOfName (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_PARSE_OBJECT       *Op);

static BOOLEAN
XfRefIsGuardedByIfCondRefOf (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_PARSE_OBJECT       *Op);


/*******************************************************************************
 *
 * FUNCTION:    XfCrossReferenceNamespace
 *
 * PARAMETERS:  None
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Perform a cross reference check of the parse tree against the
 *              namespace. Every named referenced within the parse tree
 *              should be get resolved with a namespace lookup. If not, the
 *              original reference in the ASL code is invalid -- i.e., refers
 *              to a non-existent object.
 *
 * NOTE:  The ASL "External" operator causes the name to be inserted into the
 *        namespace so that references to the external name will be resolved
 *        correctly here.
 *
 ******************************************************************************/

ACPI_STATUS
XfCrossReferenceNamespace (
    void)
{
    ACPI_WALK_STATE         *WalkState;


    /*
     * Create a new walk state for use when looking up names
     * within the namespace (Passed as context to the callbacks)
     */
    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    if (!WalkState)
    {
        return (AE_NO_MEMORY);
    }

    /* Walk the entire parse tree */

    TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
        XfNamespaceLocateBegin, XfNamespaceLocateEnd, WalkState);

    ACPI_FREE (WalkState);
    return (AE_OK);
}


/*******************************************************************************
 *
 * FUNCTION:    XfObjectExists
 *
 * PARAMETERS:  Name            - 4 char ACPI name
 *
 * RETURN:      TRUE if name exists in namespace
 *
 * DESCRIPTION: Walk the namespace to find an object
 *
 ******************************************************************************/

static BOOLEAN
XfObjectExists (
    char                    *Name)
{
    ACPI_STATUS             Status;


    /* Walk entire namespace from the supplied root */

    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
        ACPI_UINT32_MAX, FALSE, XfCompareOneNamespaceObject, NULL,
        Name, NULL);
    if (Status == AE_CTRL_TRUE)
    {
        /* At least one instance of the name was found */

        return (TRUE);
    }

    return (FALSE);
}


/*******************************************************************************
 *
 * FUNCTION:    XfCompareOneNamespaceObject
 *
 * PARAMETERS:  ACPI_WALK_CALLBACK
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Compare name of one object.
 *
 ******************************************************************************/

static ACPI_STATUS
XfCompareOneNamespaceObject (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;


    /* Simply check the name */

    if (*((UINT32 *) (Context)) == Node->Name.Integer)
    {
        /* Abort walk if we found one instance */

        return (AE_CTRL_TRUE);
    }

    return (AE_OK);
}


/*******************************************************************************
 *
 * FUNCTION:    XfCheckFieldRange
 *
 * PARAMETERS:  RegionBitLength     - Length of entire parent region
 *              FieldBitOffset      - Start of the field unit (within region)
 *              FieldBitLength      - Entire length of field unit
 *              AccessBitWidth      - Access width of the field unit
 *
 * RETURN:      None
 *
 * DESCRIPTION: Check one field unit to make sure it fits in the parent
 *              op region.
 *
 * Note: AccessBitWidth must be either 8,16,32, or 64
 *
 ******************************************************************************/

static void
XfCheckFieldRange (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  RegionBitLength,
    UINT32                  FieldBitOffset,
    UINT32                  FieldBitLength,
    UINT32                  AccessBitWidth)
{
    UINT32                  FieldEndBitOffset;


    /*
     * Check each field unit against the region size. The entire
     * field unit (start offset plus length) must fit within the
     * region.
     */
    FieldEndBitOffset = FieldBitOffset + FieldBitLength;

    if (FieldEndBitOffset > RegionBitLength)
    {
        /* Field definition itself is beyond the end-of-region */

        AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
        return;
    }

    /*
     * Now check that the field plus AccessWidth doesn't go beyond
     * the end-of-region. Assumes AccessBitWidth is a power of 2
     */
    FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);

    if (FieldEndBitOffset > RegionBitLength)
    {
        /* Field definition combined with the access is beyond EOR */

        AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
    }
}


/*******************************************************************************
 *
 * FUNCTION:    XfNamespaceLocateBegin
 *
 * PARAMETERS:  ASL_WALK_CALLBACK
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Descending callback used during cross-reference. For named
 *              object references, attempt to locate the name in the
 *              namespace.
 *
 * NOTE: ASL references to named fields within resource descriptors are
 *       resolved to integer values here. Therefore, this step is an
 *       important part of the code generation. We don't know that the
 *       name refers to a resource descriptor until now.
 *
 ******************************************************************************/

static ACPI_STATUS
XfNamespaceLocateBegin (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  Level,
    void                    *Context)
{
    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_STATUS             Status;
    ACPI_OBJECT_TYPE        ObjectType;
    char                    *Path;
    UINT8                   PassedArgs;
    ACPI_PARSE_OBJECT       *NextOp;
    ACPI_PARSE_OBJECT       *OwningOp;
    ACPI_PARSE_OBJECT       *SpaceIdOp;
    UINT32                  MinimumLength;
    UINT32                  Offset;
    UINT32                  FieldBitLength;
    UINT32                  TagBitLength;
    UINT8                   Message = 0;
    const ACPI_OPCODE_INFO  *OpInfo;
    UINT32                  Flags;
    ASL_METHOD_LOCAL        *MethodLocals = NULL;
    ASL_METHOD_LOCAL        *MethodArgs = NULL;
    int                     RegisterNumber;
    UINT32                  i;
    ACPI_NAMESPACE_NODE     *DeclarationParentMethod;
    ACPI_PARSE_OBJECT       *ReferenceParentMethod;
    char                    *ExternalPath;


    ACPI_FUNCTION_TRACE_PTR (XfNamespaceLocateBegin, Op);


    if ((Op->Asl.AmlOpcode == AML_METHOD_OP) && Op->Asl.Node)
    {
        Node = Op->Asl.Node;

        /* Support for method LocalX/ArgX analysis */

        if (!Node->MethodLocals)
        {
            /* Create local/arg info blocks */

            MethodLocals = UtLocalCalloc (
                sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_LOCALS);
            Node->MethodLocals = MethodLocals;

            MethodArgs = UtLocalCalloc (
                sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_ARGS);
            Node->MethodArgs = MethodArgs;

            /*
             * Get the method argument count
             * First, get the name node
             */
            NextOp = Op->Asl.Child;

            /* Get the NumArguments node */

            NextOp = NextOp->Asl.Next;
            Node->ArgCount = (UINT8)
                (((UINT8) NextOp->Asl.Value.Integer) & 0x07);

            /* We will track all possible ArgXs */

            for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
            {
                if (i < Node->ArgCount)
                {
                    /* Real Args are always "initialized" */

                    MethodArgs[i].Flags = ASL_ARG_INITIALIZED;
                }
                else
                {
                    /* Other ArgXs can be used as locals */

                    MethodArgs[i].Flags = ASL_ARG_IS_LOCAL;
                }

                MethodArgs[i].Op = Op;
            }
        }
    }

    /*
     * If this node is the actual declaration of a name
     * [such as the XXXX name in "Method (XXXX)"],
     * we are not interested in it here. We only care about names that are
     * references to other objects within the namespace and the parent objects
     * of name declarations
     */
    if (Op->Asl.CompileFlags & OP_IS_NAME_DECLARATION)
    {
        return_ACPI_STATUS (AE_OK);
    }

    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);

    /* Check method LocalX variables */

    if (OpInfo->Type == AML_TYPE_LOCAL_VARIABLE)
    {
        /* Find parent method Op */

        NextOp = UtGetParentMethodOp (Op);
        if (!NextOp)
        {
            return_ACPI_STATUS (AE_OK);
        }

        /* Get method node */

        Node = NextOp->Asl.Node;

        RegisterNumber = Op->Asl.AmlOpcode & 0x0007; /* 0x60 through 0x67 */
        MethodLocals = Node->MethodLocals;

        if (Op->Asl.CompileFlags & OP_IS_TARGET)
        {
            /* Local is being initialized */

            MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_INITIALIZED;
            MethodLocals[RegisterNumber].Op = Op;

            return_ACPI_STATUS (AE_OK);
        }

        /* Mark this Local as referenced */

        MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_REFERENCED;
        MethodLocals[RegisterNumber].Op = Op;

        return_ACPI_STATUS (AE_OK);
    }

    /* Check method ArgX variables */

    if (OpInfo->Type == AML_TYPE_METHOD_ARGUMENT)
    {
        /* Find parent method Op */

        NextOp = UtGetParentMethodOp (Op);
        if (!NextOp)
        {
            return_ACPI_STATUS (AE_OK);
        }

        /* Get method node */

        Node = NextOp->Asl.Node;

        /* Get Arg # */

        RegisterNumber = Op->Asl.AmlOpcode - AML_ARG0; /* 0x68 through 0x6F */
        MethodArgs = Node->MethodArgs;

        /* Mark this Arg as referenced */

        MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED;
        MethodArgs[RegisterNumber].Op = Op;

        if (Op->Asl.CompileFlags & OP_IS_TARGET)
        {
            /* Arg is being initialized */

            MethodArgs[RegisterNumber].Flags |= ASL_ARG_INITIALIZED;
        }

        return_ACPI_STATUS (AE_OK);
    }

    /*
     * After method ArgX and LocalX, we are only interested in opcodes
     * that have an associated name
     */
    if ((!(OpInfo->Flags & AML_NAMED)) &&
        (!(OpInfo->Flags & AML_CREATE)) &&
        (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
        (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
        (Op->Asl.ParseOpcode != PARSEOP_METHODCALL) &&
        (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
    {
        return_ACPI_STATUS (AE_OK);
    }

    /*
     * We must enable the "search-to-root" for single NameSegs, but
     * we have to be very careful about opening up scopes
     */
    Flags = ACPI_NS_SEARCH_PARENT;
    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
        (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
        (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)   ||
        (Op->Asl.ParseOpcode == PARSEOP_CONDREFOF))
    {
        /*
         * These are name references, do not push the scope stack
         * for them.
         */
        Flags |= ACPI_NS_DONT_OPEN_SCOPE;
    }

    /* Get the NamePath from the appropriate place */

    if (OpInfo->Flags & AML_NAMED)
    {
        /* For nearly all NAMED operators, the name reference is the first child */

        Path = Op->Asl.Child->Asl.Value.String;
        if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
        {
            /*
             * ALIAS is the only oddball opcode, the name declaration
             * (alias name) is the second operand
             */
            Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
        }
    }
    else if (OpInfo->Flags & AML_CREATE)
    {
        /* Name must appear as the last parameter */

        NextOp = Op->Asl.Child;
        while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION))
        {
            NextOp = NextOp->Asl.Next;
        }

        Path = NextOp->Asl.Value.String;
    }
    else
    {
        Path = Op->Asl.Value.String;
    }

    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
        "Type=%s\n", AcpiUtGetTypeName (ObjectType)));

    /*
     * Lookup the name in the namespace. Name must exist at this point, or it
     * is an invalid reference.
     *
     * The namespace is also used as a lookup table for references to resource
     * descriptors and the fields within them.
     */
    AslGbl_NsLookupCount++;

    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
        ACPI_IMODE_EXECUTE, Flags, WalkState, &Node);
    if (ACPI_FAILURE (Status))
    {
        if (Status == AE_NOT_FOUND)
        {
            /*
             * We didn't find the name reference by path -- we can qualify this
             * a little better before we print an error message
             */

            if ((Op->Asl.Parent) &&
                (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
            {
                /*
                 * One special case: CondRefOf operator - if the name doesn't
                 * exist at this point, it means that there's no actual or
                 * external declaration. If the name is not found, just ignore
                 * it, the point of the operator is to determine if the name
                 * exists at runtime. We wanted to see if this named object
                 * exists to facilitate analysis to allow protected usage of
                 * undeclared externals.
                 */
                return_ACPI_STATUS (AE_OK);
            }
            else if (strlen (Path) == ACPI_NAMESEG_SIZE)
            {
                /* A simple, one-segment ACPI name */

                if (XfObjectExists (Path))
                {
                    /*
                     * There exists such a name, but we couldn't get to it
                     * from this scope
                     */
                    AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
                        Op->Asl.ExternalName);
                }
                else
                {
                    /* The name doesn't exist, period */

                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
                        Op, Op->Asl.ExternalName);
                }
            }
            else
            {
                /* The NamePath contains multiple NameSegs */

                if ((OpInfo->Flags & AML_CREATE) ||
                    (OpInfo->ObjectType == ACPI_TYPE_LOCAL_ALIAS))
                {
                    /*
                     * The new name is the last parameter. For the
                     * CreateXXXXField and Alias operators
                     */
                    NextOp = Op->Asl.Child;
                    while (!(NextOp->Asl.CompileFlags & OP_IS_NAME_DECLARATION))
                    {
                        NextOp = NextOp->Asl.Next;
                    }

                    AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, NextOp,
                        NextOp->Asl.ExternalName);
                }
                else if (OpInfo->Flags & AML_NAMED)
                {
                    /* The new name is the first parameter */

                    AslError (ASL_ERROR, ASL_MSG_PREFIX_NOT_EXIST, Op,
                        Op->Asl.ExternalName);
                }
                else if (Path[0] == AML_ROOT_PREFIX)
                {
                    /* Full namepath from root, the object does not exist */

                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
                        Op->Asl.ExternalName);
                }
                else
                {
                    /*
                     * Generic "not found" error. Cannot determine whether it
                     * doesn't exist or just can't be reached. However, we
                     * can differentiate between a NameSeg vs. NamePath.
                     */
                    if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
                    {
                        AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
                            Op->Asl.ExternalName);
                    }
                    else
                    {
                        AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
                            Op->Asl.ExternalName);
                    }
                }
            }

            Status = AE_OK;
        }

        return_ACPI_STATUS (Status);
    }

    /* Check for an attempt to access an object in another method */

    if (!XfValidateCrossReference (Op, OpInfo, Node))
    {
        AslError (ASL_ERROR, ASL_MSG_TEMPORARY_OBJECT, Op,
            Op->Asl.ExternalName);
        return_ACPI_STATUS (Status);
    }

   /* Object was found above, check for an illegal forward reference */

    if (Op->Asl.CompileFlags & OP_NOT_FOUND_DURING_LOAD)
    {
        /*
         * During the load phase, this Op was flagged as a possible
         * illegal forward reference. In other words, Op is a name path or
         * name segment that refers to a named object declared after the
         * reference. In this scinario, Node refers to the actual declaration
         * and Op is a parse node that references the named object.
         *
         * Note:
         *
         * Object references inside of control methods are allowed to
         * refer to objects declared outside of control methods.
         *
         * If the declaration and reference are both contained inside of the
         * same method or outside of any method, this is a forward reference
         * and should be reported as a compiler error.
         */
        DeclarationParentMethod = UtGetParentMethodNode (Node);
        ReferenceParentMethod = UtGetParentMethodOp (Op);

        /* case 1: declaration and reference are both outside of method */

        if (!ReferenceParentMethod && !DeclarationParentMethod)
        {
            AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
                Op->Asl.ExternalName);
        }

        /* case 2: declaration and reference are both inside of the same method */

        else if (ReferenceParentMethod && DeclarationParentMethod &&
            ReferenceParentMethod == DeclarationParentMethod->Op)
        {
             AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
                Op->Asl.ExternalName);
        }
    }

    /* Check for a reference vs. name declaration */

    if (!(OpInfo->Flags & AML_NAMED) &&
        !(OpInfo->Flags & AML_CREATE))
    {
        /* This node has been referenced, mark it for reference check */

        Node->Flags |= ANOBJ_IS_REFERENCED;
    }

    /*
     * Attempt to optimize the NamePath
     *
     * One special case: CondRefOf operator - not all AML interpreter
     * implementations expect optimized namepaths as a parameter to this
     * operator. They require relative name paths with prefix operators or
     * namepaths starting with the root scope.
     *
     * Other AML interpreter implementations do not perform the namespace
     * search that starts at the current scope and recursively searching the
     * parent scope until the root scope. The lack of search is only known to
     * occur for the namestring parameter for the CondRefOf operator.
     */
    if ((Op->Asl.Parent) &&
        (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_CONDREFOF))
    {
        OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
    }

    /*
     * 1) Dereference an alias (A name reference that is an alias)
     *    Aliases are not nested, the alias always points to the final object
     */
    if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
        (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
    {
        /* This node points back to the original PARSEOP_ALIAS */

        NextOp = Node->Op;

        /* The first child is the alias target op */

        NextOp = NextOp->Asl.Child;

        /* That in turn points back to original target alias node */

        if (NextOp->Asl.Node)
        {
            Node = NextOp->Asl.Node;
        }

        /* Else - forward reference to alias, will be resolved later */
    }

    /* 2) Check for a reference to a resource descriptor */

    if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
        (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
    {
        /*
         * This was a reference to a field within a resource descriptor.
         * Extract the associated field offset (either a bit or byte
         * offset depending on the field type) and change the named
         * reference into an integer for AML code generation
         */
        Offset = Node->Value;
        TagBitLength = Node->Length;

        /*
         * If a field is being created, generate the length (in bits) of
         * the field. Note: Opcodes other than CreateXxxField and Index
         * can come through here. For other opcodes, we just need to
         * convert the resource tag reference to an integer offset.
         */
        switch (Op->Asl.Parent->Asl.AmlOpcode)
        {
        case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */
            /*
             * We know the length operand is an integer constant because
             * we know that it contains a reference to a resource
             * descriptor tag.
             */
            FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer;
            break;

        case AML_CREATE_BIT_FIELD_OP:

            FieldBitLength = 1;
            break;

        case AML_CREATE_BYTE_FIELD_OP:
        case AML_INDEX_OP:

            FieldBitLength = 8;
            break;

        case AML_CREATE_WORD_FIELD_OP:

            FieldBitLength = 16;
            break;

        case AML_CREATE_DWORD_FIELD_OP:

            FieldBitLength = 32;
            break;

        case AML_CREATE_QWORD_FIELD_OP:

            FieldBitLength = 64;
            break;

        default:

            FieldBitLength = 0;
            break;
        }

        /* Check the field length against the length of the resource tag */

        if (FieldBitLength)
        {
            if (TagBitLength < FieldBitLength)
            {
                Message = ASL_MSG_TAG_SMALLER;
            }
            else if (TagBitLength > FieldBitLength)
            {
                Message = ASL_MSG_TAG_LARGER;
            }

            if (Message)
            {
                sprintf (AslGbl_MsgBuffer,
                    "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
                    TagBitLength, (TagBitLength > 1) ? "s" : "",
                    FieldBitLength, (FieldBitLength > 1) ? "s" : "");

                AslError (ASL_WARNING, Message, Op, AslGbl_MsgBuffer);
            }
        }

        /* Convert the BitOffset to a ByteOffset for certain opcodes */

        switch (Op->Asl.Parent->Asl.AmlOpcode)
        {
        case AML_CREATE_BYTE_FIELD_OP:
        case AML_CREATE_WORD_FIELD_OP:
        case AML_CREATE_DWORD_FIELD_OP:
        case AML_CREATE_QWORD_FIELD_OP:
        case AML_INDEX_OP:

            Offset = ACPI_DIV_8 (Offset);
            break;

        default:

            break;
        }

        /* Now convert this node to an integer whose value is the field offset */

        Op->Asl.AmlLength = 0;
        Op->Asl.ParseOpcode = PARSEOP_INTEGER;
        Op->Asl.Value.Integer = (UINT64) Offset;
        Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD;

        OpcGenerateAmlOpcode (Op);
    }

    /* 3) Check for a method invocation */

    else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
                (Node->Type == ACPI_TYPE_METHOD) &&
                (Op->Asl.Parent) &&
                (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||

                (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
    {
        /*
         * A reference to a method within one of these opcodes is not an
         * invocation of the method, it is simply a reference to the method.
         *
         * September 2016: Removed DeRefOf from this list
         * July 2020: Added Alias to this list
         */
        if ((Op->Asl.Parent) &&
            ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)     ||
            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_PACKAGE)    ||
            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)||
            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE) ||
            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_ALIAS)))
        {
            return_ACPI_STATUS (AE_OK);
        }

        /*
         * There are two types of method invocation:
         * 1) Invocation with arguments -- the parser recognizes this
         *    as a METHODCALL.
         * 2) Invocation with no arguments --the parser cannot determine that
         *    this is a method invocation, therefore we have to figure it out
         *    here.
         */
        if (Node->Type != ACPI_TYPE_METHOD)
        {
            sprintf (AslGbl_MsgBuffer, "%s is a %s",
                Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));

            AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, AslGbl_MsgBuffer);
            return_ACPI_STATUS (AE_OK);
        }

        /* Save the method node in the caller's op */

        Op->Asl.Node = Node;
        if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
        {
            return_ACPI_STATUS (AE_OK);
        }

        /*
         * This is a method invocation, with or without arguments.
         * Count the number of arguments, each appears as a child
         * under the parent node
         */
        Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
        UtSetParseOpName (Op);

        PassedArgs = 0;
        NextOp = Op->Asl.Child;

        while (NextOp)
        {
            PassedArgs++;
            NextOp = NextOp->Asl.Next;
        }

        if (Node->Value != ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS &&
            Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL)
        {
            /*
             * Check the parsed arguments with the number expected by the
             * method declaration itself
             */
            if (PassedArgs != Node->Value)
            {
                if (Node->Flags & ANOBJ_IS_EXTERNAL)
                {
                    sprintf (AslGbl_MsgBuffer,
                        "according to previous use, %s requires %u",
                        Op->Asl.ExternalName, Node->Value);
                }
                else
                {
                    sprintf (AslGbl_MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
                        Node->Value);
                }

                if (PassedArgs < Node->Value)
                {
                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, AslGbl_MsgBuffer);
                }
                else
                {
                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, AslGbl_MsgBuffer);
                }
            }
        }

        /*
         * At this point, a method call to an external method has been
         * detected. As of 11/19/2019, iASL does not support parameter counts
         * for methods declared as external. Therefore, save the parameter
         * count of the first method call and use this count check other
         * method calls to ensure that the methods are being called with the
         * same amount of parameters.
         */
        else if (Node->Type == ACPI_TYPE_METHOD &&
            (Node->Flags & ANOBJ_IS_EXTERNAL) &&
            Node->Value == ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS &&
            Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL)
        {
            Node->Value = PassedArgs;
        }
    }

    /* 4) Check for an ASL Field definition */

    else if ((Op->Asl.Parent) &&
            ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
    {
        /*
         * Offset checking for fields. If the parent operation region has a
         * constant length (known at compile time), we can check fields
         * defined in that region against the region length. This will catch
         * fields and field units that cannot possibly fit within the region.
         *
         * Note: Index fields do not directly reference an operation region,
         * thus they are not included in this check.
         */
        if (Op == Op->Asl.Parent->Asl.Child)
        {
            /*
             * This is the first child of the field node, which is
             * the name of the region. Get the parse node for the
             * region -- which contains the length of the region.
             */
            OwningOp = Node->Op;
            Op->Asl.Parent->Asl.ExtraValue =
                ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);

            /* Examine the field access width */

            switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
            {
            case AML_FIELD_ACCESS_ANY:
            case AML_FIELD_ACCESS_BYTE:
            case AML_FIELD_ACCESS_BUFFER:
            default:

                MinimumLength = 1;
                break;

            case AML_FIELD_ACCESS_WORD:

                MinimumLength = 2;
                break;

            case AML_FIELD_ACCESS_DWORD:

                MinimumLength = 4;
                break;

            case AML_FIELD_ACCESS_QWORD:

                MinimumLength = 8;
                break;
            }

            /*
             * Is the region at least as big as the access width?
             * Note: DataTableRegions have 0 length
             */
            if (((UINT32) OwningOp->Asl.Value.Integer) &&
                ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
            {
                AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
            }

            /*
             * Check EC/CMOS/SMBUS fields to make sure that the correct
             * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
             */
            SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
            switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
            {
            case ACPI_ADR_SPACE_EC:
            case ACPI_ADR_SPACE_CMOS:
            case ACPI_ADR_SPACE_GPIO:

                if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
                    AML_FIELD_ACCESS_BYTE)
                {
                    AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
                }
                break;

            case ACPI_ADR_SPACE_SMBUS:
            case ACPI_ADR_SPACE_IPMI:
            case ACPI_ADR_SPACE_GSBUS:

                if ((UINT8) Op->Asl.Parent->Asl.Value.Integer !=
                    AML_FIELD_ACCESS_BUFFER)
                {
                    AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
                }
                break;

            default:

                /* Nothing to do for other address spaces */

                break;
            }
        }
        else
        {
            /*
             * This is one element of the field list. Check to make sure
             * that it does not go beyond the end of the parent operation region.
             *
             * In the code below:
             *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
             *    Op->Asl.ExtraValue                  - Field start offset (bits)
             *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
             *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
             */
            if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
            {
                XfCheckFieldRange (Op,
                    Op->Asl.Parent->Asl.ExtraValue,
                    Op->Asl.ExtraValue,
                    (UINT32) Op->Asl.Child->Asl.Value.Integer,
                    Op->Asl.Child->Asl.ExtraValue);
            }
        }
    }

    /*
     * 5) Check for external resolution
     *
     * By this point, everything should be loaded in the namespace. If a
     * namespace lookup results in a namespace node that is an external, it
     * means that this named object was not defined in the input ASL. This
     * causes issues because there are plenty of incidents where developers
     * use the external keyword to suppress compiler errors about undefined
     * objects. Note: this only applies when compiling multiple definition
     * blocks.
     *
     * Do not check for external resolution in the following cases:
     *
     * case 1) External (ABCD)
     *
     *         This declares ABCD as an external so there is no requirement for
     *         ABCD to be loaded in the namespace when analyzing the actual
     *         External() statement.
     *
     * case 2) CondRefOf (ABCD)
     *
     *         This operator will query the ACPI namespace on the existence of
     *         ABCD. If ABCD does not exist, this operator will return a 0
     *         without incurring AML runtime errors. Therefore, ABCD is allowed
     *         to not exist when analyzing the CondRefOf operator.
     *
     * case 3) External (ABCD)
     *         if (CondRefOf (ABCD))
     *         {
     *             Store (0, ABCD)
     *         }
     *
     *         In this case, ABCD is accessed only if it exists due to the if
     *         statement so there is no need to flag the ABCD nested in the
     *         store operator.
     */
    if (AslGbl_ParseTreeRoot->Asl.Child && AslGbl_ParseTreeRoot->Asl.Child->Asl.Next &&
        (Node->Flags & ANOBJ_IS_EXTERNAL) &&
        Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_EXTERNAL &&
        Op->Asl.ParseOpcode != PARSEOP_EXTERNAL &&
        Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_CONDREFOF &&
        !XfRefIsGuardedByIfCondRefOf (Node, Op))
    {
        ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
        sprintf (AslGbl_MsgBuffer, "full path of external object: %s",
            ExternalPath);
        AslDualParseOpError (ASL_ERROR, ASL_MSG_UNDEFINED_EXTERNAL, Op, NULL,
            ASL_MSG_EXTERNAL_FOUND_HERE, Node->Op, AslGbl_MsgBuffer);
        if (ExternalPath)
        {
            ACPI_FREE (ExternalPath);
        }
    }

    /* 5) Check for a connection object */
#if 0
    else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
    {
        return_ACPI_STATUS (Status);
    }
#endif

    Op->Asl.Node = Node;
    return_ACPI_STATUS (Status);
}


/*******************************************************************************
 *
 * FUNCTION:    XfRefIsGuardedByIfCondRefOf
 *
 * PARAMETERS:  Node        - Named object reference node
 *              Op          - Named object reference parse node
 *
 * RETURN:      BOOLEAN
 *
 * DESCRIPTION: returns true if Op checked inside if (CondRefOf (...))
 *              refers to Node.
 *
 ******************************************************************************/

static BOOLEAN
XfRefIsGuardedByIfCondRefOf (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_PARSE_OBJECT       *Parent = Op->Asl.Parent;


    while (Parent)
    {
        if (Parent->Asl.ParseOpcode == PARSEOP_IF &&
            XfFindCondRefOfName (Node, Parent->Asl.Child))
        {
            return (TRUE);
        }

        Parent = Parent->Asl.Parent;
    }

    return (FALSE);
}


/*******************************************************************************
 *
 * FUNCTION:    XfRefIsGuardedByIfCondRefOf
 *
 * PARAMETERS:  Node        - Named object reference node
 *              Op          - Named object reference parse node
 *
 * RETURN:      BOOLEAN
 *
 * DESCRIPTION: returns true if Op checked inside if (CondRefOf (...))
 *              refers to Node.
 *
 ******************************************************************************/

static BOOLEAN
XfFindCondRefOfName (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_PARSE_OBJECT       *Op)
{
    BOOLEAN                 CondRefOfFound = FALSE;


    if (!Op)
    {
        return (FALSE);
    }

    switch (Op->Asl.ParseOpcode)
    {
    case PARSEOP_CONDREFOF:

        return (Op->Asl.Child->Common.Node == Node);
        break;

    case PARSEOP_LAND:

        CondRefOfFound = XfFindCondRefOfName (Node, Op->Asl.Child);
        if (CondRefOfFound)
        {
            return (TRUE);
        }

        return (XfFindCondRefOfName (Node, Op->Asl.Child->Asl.Next));
        break;

    default:

        return (FALSE);
        break;
    }
}


/*******************************************************************************
 *
 * FUNCTION:    XfNamespaceLocateEnd
 *
 * PARAMETERS:  ASL_WALK_CALLBACK
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Ascending callback used during cross reference. We only
 *              need to worry about scope management here.
 *
 ******************************************************************************/

static ACPI_STATUS
XfNamespaceLocateEnd (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  Level,
    void                    *Context)
{
    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
    const ACPI_OPCODE_INFO  *OpInfo;


    ACPI_FUNCTION_TRACE (XfNamespaceLocateEnd);


    /* We are only interested in opcodes that have an associated name */

    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    if (!(OpInfo->Flags & AML_NAMED))
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Not interested in name references, we did not open a scope for them */

    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
        (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
        (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Pop the scope stack if necessary */

    if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
    {

        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
            "%s: Popping scope for Op %p\n",
            AcpiUtGetTypeName (OpInfo->ObjectType), Op));

        (void) AcpiDsScopeStackPop (WalkState);
    }

    return_ACPI_STATUS (AE_OK);
}


/*******************************************************************************
 *
 * FUNCTION:    XfValidateCrossReference
 *
 * PARAMETERS:  Op                      - Parse Op that references the object
 *              OpInfo                  - Parse Op info struct
 *              Node                    - Node for the referenced object
 *
 * RETURN:      TRUE if the reference is legal, FALSE otherwise
 *
 * DESCRIPTION: Determine if a reference to another object is allowed.
 *
 * EXAMPLE:
 *      Method (A) {Name (INT1, 1)}     Declaration of object INT1
 *      Method (B) (Store (2, \A.INT1)} Illegal reference to object INT1
 *                                      (INT1 is temporary, valid only during
 *                                      execution of A)
 *
 * NOTES:
 *      A null pointer returned by either UtGetParentMethodOp or
 *      UtGetParentMethodNode indicates that the parameter object is not
 *      within a control method.
 *
 *      Five cases are handled: Case(Op, Node)
 *      1) Case(0,0): Op is not within a method, Node is not    --> OK
 *      2) Case(0,1): Op is not within a method, but Node is    --> Illegal
 *      3) Case(1,0): Op is within a method, Node is not        --> OK
 *      4) Case(1,1): Both are within the same method           --> OK
 *      5) Case(1,1): Both are in methods, but not same method  --> Illegal
 *
 ******************************************************************************/

static BOOLEAN
XfValidateCrossReference (
    ACPI_PARSE_OBJECT       *Op,
    const ACPI_OPCODE_INFO  *OpInfo,
    ACPI_NAMESPACE_NODE     *Node)
{
    ACPI_PARSE_OBJECT       *ReferencingMethodOp;
    ACPI_NAMESPACE_NODE     *ReferencedMethodNode;


    /* Ignore actual named (and related) object declarations */

    if (OpInfo->Flags & (AML_NAMED | AML_CREATE | AML_DEFER | AML_HAS_ARGS))
    {
        return (TRUE);
    }

    /*
     * 1) Search upwards in parse tree for owner of the referencing object
     * 2) Search upwards in namespace to find the owner of the referenced object
     */
    ReferencingMethodOp = UtGetParentMethodOp (Op);
    ReferencedMethodNode = UtGetParentMethodNode (Node);

    if (!ReferencingMethodOp && !ReferencedMethodNode)
    {
        /*
         * 1) Case (0,0): Both Op and Node are not within methods
         * --> OK
         */
        return (TRUE);
    }

    if (!ReferencingMethodOp && ReferencedMethodNode)
    {
        /*
         * 2) Case (0,1): Op is not in a method, but Node is within a
         * method --> illegal
         */
        return (FALSE);
    }
    else if (ReferencingMethodOp && !ReferencedMethodNode)
    {
        /*
         * 3) Case (1,0): Op is within a method, but Node is not
         * --> OK
         */
        return (TRUE);
    }
    else if (ReferencingMethodOp->Asl.Node == ReferencedMethodNode)
    {
        /*
         * 4) Case (1,1): Both Op and Node are within the same method
         * --> OK
         */
        return (TRUE);
    }
    else
    {
        /*
         * 5) Case (1,1), Op and Node are in different methods
         * --> Illegal
         */
        return (FALSE);
    }
}
