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

📄 dsobject.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 2 页
字号:
 * NOTE: The number of elements in the package will be always be the NumElements * count, regardless of the number of elements in the package list. If * NumElements is smaller, only that many package list elements are used. * if NumElements is larger, the Package object is padded out with * objects of type Uninitialized (as per ACPI spec.) * * Even though the ASL compilers do not allow NumElements to be smaller * than the Package list length (for the fixed length package opcode), some * BIOS code modifies the AML on the fly to adjust the NumElements, and * this code compensates for that. This also provides compatibility with * other AML interpreters. * ******************************************************************************/ACPI_STATUSAcpiDsBuildInternalPackageObj (    ACPI_WALK_STATE         *WalkState,    ACPI_PARSE_OBJECT       *Op,    UINT32                  ElementCount,    ACPI_OPERAND_OBJECT     **ObjDescPtr){    ACPI_PARSE_OBJECT       *Arg;    ACPI_PARSE_OBJECT       *Parent;    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;    ACPI_STATUS             Status = AE_OK;    ACPI_NATIVE_UINT        i;    UINT16                  Index;    UINT16                  ReferenceCount;    ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);    /* Find the parent of a possibly nested package */    Parent = Op->Common.Parent;    while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||           (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))    {        Parent = Parent->Common.Parent;    }    /*     * If we are evaluating a Named package object "Name (xxxx, Package)",     * the package object already exists, otherwise it must be created.     */    ObjDesc = *ObjDescPtr;    if (!ObjDesc)    {        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);        *ObjDescPtr = ObjDesc;        if (!ObjDesc)        {            return_ACPI_STATUS (AE_NO_MEMORY);        }        ObjDesc->Package.Node = Parent->Common.Node;    }    /*     * Allocate the element array (array of pointers to the individual     * objects) based on the NumElements parameter. Add an extra pointer slot     * so that the list is always null terminated.     */    ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (        ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));    if (!ObjDesc->Package.Elements)    {        AcpiUtDeleteObjectDesc (ObjDesc);        return_ACPI_STATUS (AE_NO_MEMORY);    }    ObjDesc->Package.Count = ElementCount;    /*     * Initialize the elements of the package, up to the NumElements count.     * Package is automatically padded with uninitialized (NULL) elements     * if NumElements is greater than the package list length. Likewise,     * Package is truncated if NumElements is less than the list length.     */    Arg = Op->Common.Value.Arg;    Arg = Arg->Common.Next;    for (i = 0; Arg && (i < ElementCount); i++)    {        if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)        {            if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)            {                /*                 * A method reference "looks" to the parser to be a method                 * invocation, so we special case it here                 */                Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;                Status = AcpiDsBuildInternalObject (WalkState, Arg,                            &ObjDesc->Package.Elements[i]);            }            else            {                /* This package element is already built, just get it */                ObjDesc->Package.Elements[i] =                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);            }        }        else        {            Status = AcpiDsBuildInternalObject (WalkState, Arg,                        &ObjDesc->Package.Elements[i]);        }        if (*ObjDescPtr)        {            /* Existing package, get existing reference count */            ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;            if (ReferenceCount > 1)            {                /* Make new element ref count match original ref count */                for (Index = 0; Index < (ReferenceCount - 1); Index++)                {                    AcpiUtAddReference ((ObjDesc->Package.Elements[i]));                }            }        }        Arg = Arg->Common.Next;    }    if (!Arg)    {        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,            "Package List length larger than NumElements count (%X), truncated\n",            ElementCount));    }    ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;    Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiDsCreateNode * * PARAMETERS:  WalkState       - Current walk state *              Node            - NS Node to be initialized *              Op              - Parser object to be translated * * RETURN:      Status * * DESCRIPTION: Create the object to be associated with a namespace node * ******************************************************************************/ACPI_STATUSAcpiDsCreateNode (    ACPI_WALK_STATE         *WalkState,    ACPI_NAMESPACE_NODE     *Node,    ACPI_PARSE_OBJECT       *Op){    ACPI_STATUS             Status;    ACPI_OPERAND_OBJECT     *ObjDesc;    ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op);    /*     * Because of the execution pass through the non-control-method     * parts of the table, we can arrive here twice.  Only init     * the named object node the first time through     */    if (AcpiNsGetAttachedObject (Node))    {        return_ACPI_STATUS (AE_OK);    }    if (!Op->Common.Value.Arg)    {        /* No arguments, there is nothing to do */        return_ACPI_STATUS (AE_OK);    }    /* Build an internal object for the argument(s) */    Status = AcpiDsBuildInternalObject (WalkState, Op->Common.Value.Arg,                &ObjDesc);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    /* Re-type the object according to its argument */    Node->Type = ACPI_GET_OBJECT_TYPE (ObjDesc);    /* Attach obj to node */    Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);    /* Remove local reference to the object */    AcpiUtRemoveReference (ObjDesc);    return_ACPI_STATUS (Status);}#endif /* ACPI_NO_METHOD_EXECUTION *//******************************************************************************* * * FUNCTION:    AcpiDsInitObjectFromOp * * PARAMETERS:  WalkState       - Current walk state *              Op              - Parser op used to init the internal object *              Opcode          - AML opcode associated with the object *              RetObjDesc      - Namespace object to be initialized * * RETURN:      Status * * DESCRIPTION: Initialize a namespace object from a parser Op and its *              associated arguments.  The namespace object is a more compact *              representation of the Op and its arguments. * ******************************************************************************/ACPI_STATUSAcpiDsInitObjectFromOp (    ACPI_WALK_STATE         *WalkState,    ACPI_PARSE_OBJECT       *Op,    UINT16                  Opcode,    ACPI_OPERAND_OBJECT     **RetObjDesc){    const ACPI_OPCODE_INFO  *OpInfo;    ACPI_OPERAND_OBJECT     *ObjDesc;    ACPI_STATUS             Status = AE_OK;    ACPI_FUNCTION_TRACE (DsInitObjectFromOp);    ObjDesc = *RetObjDesc;    OpInfo = AcpiPsGetOpcodeInfo (Opcode);    if (OpInfo->Class == AML_CLASS_UNKNOWN)    {        /* Unknown opcode */        return_ACPI_STATUS (AE_TYPE);    }    /* Perform per-object initialization */    switch (ACPI_GET_OBJECT_TYPE (ObjDesc))    {    case ACPI_TYPE_BUFFER:        /*         * Defer evaluation of Buffer TermArg operand         */        ObjDesc->Buffer.Node      = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,                                        WalkState->Operands[0]);        ObjDesc->Buffer.AmlStart  = Op->Named.Data;        ObjDesc->Buffer.AmlLength = Op->Named.Length;        break;    case ACPI_TYPE_PACKAGE:        /*         * Defer evaluation of Package TermArg operand         */        ObjDesc->Package.Node      = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,                                        WalkState->Operands[0]);        ObjDesc->Package.AmlStart  = Op->Named.Data;        ObjDesc->Package.AmlLength = Op->Named.Length;        break;    case ACPI_TYPE_INTEGER:        switch (OpInfo->Type)        {        case AML_TYPE_CONSTANT:            /*             * Resolve AML Constants here - AND ONLY HERE!             * All constants are integers.             * We mark the integer with a flag that indicates that it started             * life as a constant -- so that stores to constants will perform             * as expected (noop). ZeroOp is used as a placeholder for optional             * target operands.             */            ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT;            switch (Opcode)            {            case AML_ZERO_OP:                ObjDesc->Integer.Value = 0;                break;            case AML_ONE_OP:                ObjDesc->Integer.Value = 1;                break;            case AML_ONES_OP:                ObjDesc->Integer.Value = ACPI_INTEGER_MAX;                /* Truncate value if we are executing from a 32-bit ACPI table */#ifndef ACPI_NO_METHOD_EXECUTION                AcpiExTruncateFor32bitTable (ObjDesc);#endif                break;            case AML_REVISION_OP:                ObjDesc->Integer.Value = ACPI_CA_VERSION;                break;            default:                ACPI_ERROR ((AE_INFO,                    "Unknown constant opcode %X", Opcode));                Status = AE_AML_OPERAND_TYPE;                break;            }            break;        case AML_TYPE_LITERAL:            ObjDesc->Integer.Value = Op->Common.Value.Integer;#ifndef ACPI_NO_METHOD_EXECUTION            AcpiExTruncateFor32bitTable (ObjDesc);#endif            break;        default:            ACPI_ERROR ((AE_INFO, "Unknown Integer type %X",                OpInfo->Type));            Status = AE_AML_OPERAND_TYPE;            break;        }        break;    case ACPI_TYPE_STRING:        ObjDesc->String.Pointer = Op->Common.Value.String;        ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Op->Common.Value.String);        /*         * The string is contained in the ACPI table, don't ever try         * to delete it         */        ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;        break;    case ACPI_TYPE_METHOD:        break;    case ACPI_TYPE_LOCAL_REFERENCE:        switch (OpInfo->Type)        {        case AML_TYPE_LOCAL_VARIABLE:            /* Split the opcode into a base opcode + offset */            ObjDesc->Reference.Opcode = AML_LOCAL_OP;            ObjDesc->Reference.Offset = Opcode - AML_LOCAL_OP;#ifndef ACPI_NO_METHOD_EXECUTION            Status = AcpiDsMethodDataGetNode (AML_LOCAL_OP,                        ObjDesc->Reference.Offset,                        WalkState,                        (ACPI_NAMESPACE_NODE **) &ObjDesc->Reference.Object);#endif            break;        case AML_TYPE_METHOD_ARGUMENT:            /* Split the opcode into a base opcode + offset */            ObjDesc->Reference.Opcode = AML_ARG_OP;            ObjDesc->Reference.Offset = Opcode - AML_ARG_OP;#ifndef ACPI_NO_METHOD_EXECUTION            Status = AcpiDsMethodDataGetNode (AML_ARG_OP,                        ObjDesc->Reference.Offset,                        WalkState,                        (ACPI_NAMESPACE_NODE **) &ObjDesc->Reference.Object);#endif            break;        default: /* Other literals, etc.. */            if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)            {                /* Node was saved in Op */                ObjDesc->Reference.Node = Op->Common.Node;                ObjDesc->Reference.Object = Op->Common.Node->Object;            }            ObjDesc->Reference.Opcode = Opcode;            break;        }        break;    default:        ACPI_ERROR ((AE_INFO, "Unimplemented data type: %X",            ACPI_GET_OBJECT_TYPE (ObjDesc)));        Status = AE_AML_OPERAND_TYPE;        break;    }    return_ACPI_STATUS (Status);}

⌨️ 快捷键说明

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