Example #1
0
ACPI_STATUS
AcpiExStoreObjectToObject (
    ACPI_OPERAND_OBJECT     *SourceDesc,
    ACPI_OPERAND_OBJECT     *DestDesc,
    ACPI_OPERAND_OBJECT     **NewDesc,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_OPERAND_OBJECT     *ActualSrcDesc;
    ACPI_STATUS             Status = AE_OK;


    ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc);


    ActualSrcDesc = SourceDesc;
    if (!DestDesc)
    {
        /*
         * There is no destination object (An uninitialized node or
         * package element), so we can simply copy the source object
         * creating a new destination object
         */
        Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState);
        return_ACPI_STATUS (Status);
    }

    if (SourceDesc->Common.Type != DestDesc->Common.Type)
    {
        /*
         * The source type does not match the type of the destination.
         * Perform the "implicit conversion" of the source to the current type
         * of the target as per the ACPI specification.
         *
         * If no conversion performed, ActualSrcDesc = SourceDesc.
         * Otherwise, ActualSrcDesc is a temporary object to hold the
         * converted object.
         */
        Status = AcpiExConvertToTargetType (DestDesc->Common.Type,
                        SourceDesc, &ActualSrcDesc, WalkState);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        if (SourceDesc == ActualSrcDesc)
        {
            /*
             * No conversion was performed. Return the SourceDesc as the
             * new object.
             */
            *NewDesc = SourceDesc;
            return_ACPI_STATUS (AE_OK);
        }
    }

    /*
     * We now have two objects of identical types, and we can perform a
     * copy of the *value* of the source object.
     */
    switch (DestDesc->Common.Type)
    {
    case ACPI_TYPE_INTEGER:

        DestDesc->Integer.Value = ActualSrcDesc->Integer.Value;

        /* Truncate value if we are executing from a 32-bit ACPI table */

        AcpiExTruncateFor32bitTable (DestDesc);
        break;

    case ACPI_TYPE_STRING:

        Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc);
        break;

    case ACPI_TYPE_BUFFER:

        Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc);
        break;

    case ACPI_TYPE_PACKAGE:

        Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc,
                    WalkState);
        break;

    default:
        /*
         * All other types come here.
         */
        ACPI_WARNING ((AE_INFO, "Store into type %s not implemented",
            AcpiUtGetObjectTypeName (DestDesc)));

        Status = AE_NOT_IMPLEMENTED;
        break;
    }

    if (ActualSrcDesc != SourceDesc)
    {
        /* Delete the intermediate (temporary) source object */

        AcpiUtRemoveReference (ActualSrcDesc);
    }

    *NewDesc = DestDesc;
    return_ACPI_STATUS (Status);
}
Example #2
0
ACPI_STATUS
AcpiDsStoreObjectToLocal (
    UINT16                  Opcode,
    UINT32                  Index,
    ACPI_OPERAND_OBJECT     *SrcDesc,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status;
    ACPI_OPERAND_OBJECT     **Entry;


    FUNCTION_TRACE ("DsMethodDataSetValue");
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n",
                       Opcode, Index, SrcDesc));


    /* Parameter validation */

    if (!SrcDesc)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }


    /* Get a pointer to the requested method stack entry */

    Status = AcpiDsMethodDataGetEntry (Opcode, Index, WalkState, &Entry);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    if (*Entry == SrcDesc)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", SrcDesc));
        goto Cleanup;
    }


    /*
     * If there is an object already in this slot, we either
     * have to delete it, or if this is an argument and there
     * is an object reference stored there, we have to do
     * an indirect store!
     */
    if (*Entry)
    {
        /*
         * Check for an indirect store if an argument
         * contains an object reference (stored as an Node).
         * We don't allow this automatic dereferencing for
         * locals, since a store to a local should overwrite
         * anything there, including an object reference.
         *
         * If both Arg0 and Local0 contain RefOf (Local4):
         *
         * Store (1, Arg0)             - Causes indirect store to local4
         * Store (1, Local0)           - Stores 1 in local0, overwriting
         *                                  the reference to local4
         * Store (1, DeRefof (Local0)) - Causes indirect store to local4
         *
         * Weird, but true.
         */
        if ((Opcode == AML_ARG_OP) &&
                (VALID_DESCRIPTOR_TYPE (*Entry, ACPI_DESC_TYPE_NAMED)))
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
                               "Arg (%p) is an ObjRef(Node), storing in %p\n",
                               SrcDesc, *Entry));

            /* Detach an existing object from the Node */

            AcpiNsDetachObject ((ACPI_NAMESPACE_NODE *) *Entry);

            /*
             * Store this object into the Node
             * (do the indirect store)
             */
            Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) *Entry, SrcDesc,
                                         SrcDesc->Common.Type);
            return_ACPI_STATUS (Status);
        }


#ifdef ACPI_ENABLE_IMPLICIT_CONVERSION
        /*
         * Perform "Implicit conversion" of the new object to the type of the
         * existing object
         */
        Status = AcpiExConvertToTargetType ((*Entry)->Common.Type, &SrcDesc, WalkState);
        if (ACPI_FAILURE (Status))
        {
            goto Cleanup;
        }
#endif

        /*
         * Delete the existing object
         * before storing the new one
         */
        AcpiDsMethodDataDeleteValue (Opcode, Index, WalkState);
    }


    /*
     * Install the ObjStack descriptor (*SrcDesc) into
     * the descriptor for the Arg or Local.
     * Install the new object in the stack entry
     * (increments the object reference count by one)
     */
    Status = AcpiDsMethodDataSetEntry (Opcode, Index, SrcDesc, WalkState);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* Normal exit */

    return_ACPI_STATUS (AE_OK);


    /* Error exit */

Cleanup:

    return_ACPI_STATUS (Status);
}