Пример #1
0
ACPI_STATUS
AcpiDsCreateNode (
    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 = ObjDesc->Common.Type;

    /* Attach obj to node */

    Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);

    /* Remove local reference to the object */

    AcpiUtRemoveReference (ObjDesc);
    return_ACPI_STATUS (Status);
}
Пример #2
0
ACPI_STATUS
AcpiDsBuildInternalPackageObj (
    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;


    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)
        {
            /* 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]);
        }
        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);
}
Пример #3
0
ACPI_STATUS
AcpiDsBuildInternalPackageObj (
    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;
    UINT32                  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;
    }

    /* Check for match between NumElements and actual length of PackageList */

    if (Arg)
    {
        /*
         * NumElements was exhausted, but there are remaining elements in the
         * PackageList. Truncate the package to NumElements.
         *
         * Note: technically, this is an error, from ACPI spec: "It is an error
         * for NumElements to be less than the number of elements in the
         * PackageList". However, we just print a message and
         * no exception is returned. This provides Windows compatibility. Some
         * BIOSs will alter the NumElements on the fly, creating this type
         * of ill-formed package object.
         */
        while (Arg)
        {
            /*
             * We must delete any package elements that were created earlier
             * and are not going to be used because of the package truncation.
             */
            if (Arg->Common.Node)
            {
                AcpiUtRemoveReference (
                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
                Arg->Common.Node = NULL;
            }

            /* Find out how many elements there really are */

            i++;
            Arg = Arg->Common.Next;
        }

        ACPI_INFO ((AE_INFO,
            "Actual Package length (%u) is larger than NumElements field (%u), truncated",
            i, ElementCount));
    }
    else if (i < ElementCount)
    {
        /*
         * Arg list (elements) was exhausted, but we did not reach NumElements count.
         * Note: this is not an error, the package is padded out with NULLs.
         */
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
            "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n",
            i, ElementCount));
    }

    ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
    Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
    return_ACPI_STATUS (Status);
}
Пример #4
0
ACPI_STATUS
AcpiDsBuildInternalPackageObj (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  PackageLength,
    ACPI_OPERAND_OBJECT     **ObjDescPtr)
{
    ACPI_PARSE_OBJECT       *Arg;
    ACPI_PARSE_OBJECT       *Parent;
    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
    UINT32                  PackageListLength;
    ACPI_STATUS             Status = AE_OK;
    UINT32                  i;


    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;
    }

    ObjDesc = *ObjDescPtr;
    if (ObjDesc)
    {
        /*
         * We are evaluating a Named package object "Name (xxxx, Package)".
         * Get the existing package object from the NS node
         */
    }
    else
    {
        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
        *ObjDescPtr = ObjDesc;
        if (!ObjDesc)
        {
            return_ACPI_STATUS (AE_NO_MEMORY);
        }

        ObjDesc->Package.Node = Parent->Common.Node;
    }

    ObjDesc->Package.Count = PackageLength;

    /* Count the number of items in the package list */

    PackageListLength = 0;
    Arg = Op->Common.Value.Arg;
    Arg = Arg->Common.Next;
    while (Arg)
    {
        PackageListLength++;
        Arg = Arg->Common.Next;
    }

    /*
     * The package length (number of elements) will be the greater
     * of the specified length and the length of the initializer list
     */
    if (PackageListLength > PackageLength)
    {
        ObjDesc->Package.Count = PackageListLength;
    }

    /*
     * Allocate the pointer array (array of pointers to the
     * individual objects). Add an extra pointer slot so
     * that the list is always null terminated.
     */
    ObjDesc->Package.Elements = ACPI_MEM_CALLOCATE (
                ((ACPI_SIZE) ObjDesc->Package.Count + 1) * sizeof (void *));

    if (!ObjDesc->Package.Elements)
    {
        AcpiUtDeleteObjectDesc (ObjDesc);
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * Now init the elements of the package
     */
    i = 0;
    Arg = Op->Common.Value.Arg;
    Arg = Arg->Common.Next;
    while (Arg)
    {
        if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
        {
            /* Object (package or buffer) is already built */

            ObjDesc->Package.Elements[i] = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
        }
        else
        {
            Status = AcpiDsBuildInternalObject (WalkState, Arg,
                                        &ObjDesc->Package.Elements[i]);
        }

        i++;
        Arg = Arg->Common.Next;
    }

    ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
    Op->Common.Node = (ACPI_NAMESPACE_NODE *) ObjDesc;
    return_ACPI_STATUS (Status);
}