⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asllookup.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* Name must appear as the last parameter */        NextOp = Op->Asl.Child;        while (!(NextOp->Asl.CompileFlags & NODE_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.     */    Gbl_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 (strlen (Path) == ACPI_NAME_SIZE)            {                /* A simple, one-segment ACPI name */                if (LkObjectExists (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 */                    if ((Op->Asl.Parent) &&                        (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))                    {                        /* Ignore not found if parent is CondRefOf */                        return (AE_OK);                    }                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,                        Op, Op->Asl.ExternalName);                }            }            else            {                /* Check for a fully qualified path */                if (Path[0] == AML_ROOT_PREFIX)                {                    /* Gave full path, the object does not exist */                    if ((Op->Asl.Parent) &&                        (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))                    {                        /* Ignore not found if parent is CondRefOf */                        return (AE_OK);                    }                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,                        Op->Asl.ExternalName);                }                else                {                    /*                     * We can't tell whether it doesn't exist or just                     * can't be reached.                     */                    AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,                        Op->Asl.ExternalName);                }            }            Status = AE_OK;        }        return (Status);    }    /* 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 */    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         */        Temp = Node->Value;        if (Node->Flags & ANOBJ_IS_BIT_OFFSET)        {            Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;        }        /* Perform BitOffset <--> ByteOffset conversion if necessary */        switch (Op->Asl.Parent->Asl.AmlOpcode)        {        case AML_CREATE_FIELD_OP:            /* We allow a Byte offset to Bit Offset conversion for this op */            if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))            {                /* Simply multiply byte offset times 8 to get bit offset */                Temp = ACPI_MUL_8 (Temp);            }            break;        case AML_CREATE_BIT_FIELD_OP:            /* This op requires a Bit Offset */            if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))            {                AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);            }            break;        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:            /* These Ops require Byte offsets */            if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)            {                AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);            }            break;        default:            /* Nothing to do for other opcodes */            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) Temp;        Op->Asl.CompileFlags   |= NODE_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.         */        if ((Op->Asl.Parent) &&           ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)      ||            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF)    ||            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))        {            return (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 (MsgBuffer, "%s is a %s",                    Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));            AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);            return (AE_OK);        }        /* Save the method node in the caller's op */        Op->Asl.Node = Node;        if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)        {            return (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)        {            /*             * Check the parsed arguments with the number expected by the             * method declaration itself             */            if (PassedArgs != Node->Value)            {                sprintf (MsgBuffer, "%s requires %d", Op->Asl.ExternalName,                            Node->Value);                if (PassedArgs < Node->Value)                {                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);                }                else                {                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);                }            }        }    }    /* 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 REGION_EC:            case REGION_CMOS:                if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)                {                    AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);                }                break;            case REGION_SMBUS:                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)            {                LkCheckFieldRange (Op,                            Op->Asl.Parent->Asl.ExtraValue,                            Op->Asl.ExtraValue,                            (UINT32) Op->Asl.Child->Asl.Value.Integer,                            Op->Asl.Child->Asl.ExtraValue);            }        }    }    Op->Asl.Node = Node;    return (Status);}/******************************************************************************* * * FUNCTION:    LkNamespaceLocateEnd * * PARAMETERS:  ASL_WALK_CALLBACK * * RETURN:      Status * * DESCRIPTION: Ascending callback used during cross reference.  We only *              need to worry about scope management here. * ******************************************************************************/static ACPI_STATUSLkNamespaceLocateEnd (    ACPI_PARSE_OBJECT       *Op,    UINT32                  Level,    void                    *Context){    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;    const ACPI_OPCODE_INFO  *OpInfo;    ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd);    /* We are only interested in opcodes that have an associated name */    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);    if (!(OpInfo->Flags & AML_NAMED))    {        return (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))    {        return (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 (AE_OK);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -