exstore.c revision 83174
167754Smsmith
267754Smsmith/******************************************************************************
367754Smsmith *
477424Smsmith * Module Name: exstore - AML Interpreter object store support
583174Smsmith *              $Revision: 147 $
667754Smsmith *
767754Smsmith *****************************************************************************/
867754Smsmith
967754Smsmith/******************************************************************************
1067754Smsmith *
1167754Smsmith * 1. Copyright Notice
1267754Smsmith *
1371867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
1470243Smsmith * All rights reserved.
1567754Smsmith *
1667754Smsmith * 2. License
1767754Smsmith *
1867754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1967754Smsmith * rights.  You may have additional license terms from the party that provided
2067754Smsmith * you this software, covering your right to use that party's intellectual
2167754Smsmith * property rights.
2267754Smsmith *
2367754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2467754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2567754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2667754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2767754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2867754Smsmith * Code in any form, with the right to sublicense such rights; and
2967754Smsmith *
3067754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3167754Smsmith * license (with the right to sublicense), under only those claims of Intel
3267754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3367754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3467754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3567754Smsmith * license, and in no event shall the patent license extend to any additions
3667754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3767754Smsmith * is granted directly or by implication, estoppel or otherwise;
3867754Smsmith *
3967754Smsmith * The above copyright and patent license is granted only if the following
4067754Smsmith * conditions are met:
4167754Smsmith *
4267754Smsmith * 3. Conditions
4367754Smsmith *
4467754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4567754Smsmith * Redistribution of source code of any substantial portion of the Covered
4667754Smsmith * Code or modification with rights to further distribute source must include
4767754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4867754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4967754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
5067754Smsmith * contain a file documenting the changes Licensee made to create that Covered
5167754Smsmith * Code and the date of any change.  Licensee must include in that file the
5267754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5367754Smsmith * must include a prominent statement that the modification is derived,
5467754Smsmith * directly or indirectly, from Original Intel Code.
5567754Smsmith *
5667754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5767754Smsmith * Redistribution of source code of any substantial portion of the Covered
5867754Smsmith * Code or modification without rights to further distribute source must
5967754Smsmith * include the following Disclaimer and Export Compliance provision in the
6067754Smsmith * documentation and/or other materials provided with distribution.  In
6167754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6267754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6367754Smsmith * license from Licensee to its licensee is limited to the intellectual
6467754Smsmith * property embodied in the software Licensee provides to its licensee, and
6567754Smsmith * not to intellectual property embodied in modifications its licensee may
6667754Smsmith * make.
6767754Smsmith *
6867754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6967754Smsmith * substantial portion of the Covered Code or modification must reproduce the
7067754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
7167754Smsmith * provision in the documentation and/or other materials provided with the
7267754Smsmith * distribution.
7367754Smsmith *
7467754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7567754Smsmith * Intel Code.
7667754Smsmith *
7767754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7867754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7967754Smsmith * other dealings in products derived from or relating to the Covered Code
8067754Smsmith * without prior written authorization from Intel.
8167754Smsmith *
8267754Smsmith * 4. Disclaimer and Export Compliance
8367754Smsmith *
8467754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8567754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8667754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8767754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8867754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8967754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
9067754Smsmith * PARTICULAR PURPOSE.
9167754Smsmith *
9267754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9367754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9467754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9567754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9667754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9767754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9867754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9967754Smsmith * LIMITED REMEDY.
10067754Smsmith *
10167754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10267754Smsmith * software or system incorporating such software without first obtaining any
10367754Smsmith * required license or other approval from the U. S. Department of Commerce or
10467754Smsmith * any other agency or department of the United States Government.  In the
10567754Smsmith * event Licensee exports any such software from the United States or
10667754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10767754Smsmith * ensure that the distribution and export/re-export of the software is in
10867754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10967754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
11067754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
11167754Smsmith * software, or service, directly or indirectly, to any country for which the
11267754Smsmith * United States government or any agency thereof requires an export license,
11367754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11467754Smsmith * such license, approval or letter.
11567754Smsmith *
11667754Smsmith *****************************************************************************/
11767754Smsmith
11877424Smsmith#define __EXSTORE_C__
11967754Smsmith
12067754Smsmith#include "acpi.h"
12167754Smsmith#include "acparser.h"
12267754Smsmith#include "acdispat.h"
12367754Smsmith#include "acinterp.h"
12467754Smsmith#include "amlcode.h"
12567754Smsmith#include "acnamesp.h"
12667754Smsmith#include "actables.h"
12767754Smsmith
12867754Smsmith
12977424Smsmith#define _COMPONENT          ACPI_EXECUTER
13077424Smsmith        MODULE_NAME         ("exstore")
13167754Smsmith
13267754Smsmith
13367754Smsmith/*******************************************************************************
13467754Smsmith *
13577424Smsmith * FUNCTION:    AcpiExStore
13667754Smsmith *
13767754Smsmith * PARAMETERS:  *ValDesc            - Value to be stored
13877424Smsmith *              *DestDesc           - Where to store it.  Must be an NS node
13977424Smsmith *                                    or an ACPI_OPERAND_OBJECT of type
14067754Smsmith *                                    Reference; if the latter the descriptor
14167754Smsmith *                                    will be either reused or deleted.
14267754Smsmith *
14367754Smsmith * RETURN:      Status
14467754Smsmith *
14567754Smsmith * DESCRIPTION: Store the value described by ValDesc into the location
14667754Smsmith *              described by DestDesc.  Called by various interpreter
14767754Smsmith *              functions to store the result of an operation into
14867754Smsmith *              the destination operand.
14967754Smsmith *
15067754Smsmith ******************************************************************************/
15167754Smsmith
15267754SmsmithACPI_STATUS
15377424SmsmithAcpiExStore (
15467754Smsmith    ACPI_OPERAND_OBJECT     *ValDesc,
15567754Smsmith    ACPI_OPERAND_OBJECT     *DestDesc,
15667754Smsmith    ACPI_WALK_STATE         *WalkState)
15767754Smsmith{
15867754Smsmith    ACPI_STATUS             Status = AE_OK;
15971867Smsmith    ACPI_OPERAND_OBJECT     *RefDesc = DestDesc;
16067754Smsmith
16167754Smsmith
16277424Smsmith    FUNCTION_TRACE_PTR ("ExStore", DestDesc);
16367754Smsmith
16467754Smsmith
16567754Smsmith    /* Validate parameters */
16667754Smsmith
16767754Smsmith    if (!ValDesc || !DestDesc)
16867754Smsmith    {
16982367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n"));
17067754Smsmith        return_ACPI_STATUS (AE_AML_NO_OPERAND);
17167754Smsmith    }
17267754Smsmith
17371867Smsmith    /* DestDesc can be either a namespace node or an ACPI object */
17467754Smsmith
17567754Smsmith    if (VALID_DESCRIPTOR_TYPE (DestDesc, ACPI_DESC_TYPE_NAMED))
17667754Smsmith    {
17777424Smsmith        /*
17871867Smsmith         * Dest is a namespace node,
17977424Smsmith         * Storing an object into a Name "container"
18071867Smsmith         */
18177424Smsmith        Status = AcpiExStoreObjectToNode (ValDesc,
18271867Smsmith                    (ACPI_NAMESPACE_NODE *) DestDesc, WalkState);
18367754Smsmith
18471867Smsmith        /* All done, that's it */
18567754Smsmith
18671867Smsmith        return_ACPI_STATUS (Status);
18767754Smsmith    }
18867754Smsmith
18967754Smsmith
19071867Smsmith    /* Destination object must be an object of type Reference */
19167754Smsmith
19267754Smsmith    if (DestDesc->Common.Type != INTERNAL_TYPE_REFERENCE)
19367754Smsmith    {
19467754Smsmith        /* Destination is not an Reference */
19567754Smsmith
19682367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
19782367Smsmith            "Destination is not a ReferenceObj [%p]\n", DestDesc));
19867754Smsmith
19967754Smsmith        DUMP_STACK_ENTRY (ValDesc);
20067754Smsmith        DUMP_STACK_ENTRY (DestDesc);
20177424Smsmith        DUMP_OPERANDS (&DestDesc, IMODE_EXECUTE, "ExStore",
20271867Smsmith                        2, "Target is not a ReferenceObj");
20367754Smsmith
20467754Smsmith        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
20567754Smsmith    }
20667754Smsmith
20767754Smsmith
20877424Smsmith    /*
20971867Smsmith     * Examine the Reference opcode.  These cases are handled:
21071867Smsmith     *
21171867Smsmith     * 1) Store to Name (Change the object associated with a name)
21271867Smsmith     * 2) Store to an indexed area of a Buffer or Package
21371867Smsmith     * 3) Store to a Method Local or Arg
21471867Smsmith     * 4) Store to the debug object
21571867Smsmith     * 5) Store to a constant -- a noop
21671867Smsmith     */
21777424Smsmith    switch (RefDesc->Reference.Opcode)
21867754Smsmith    {
21967754Smsmith
22067754Smsmith    case AML_NAME_OP:
22167754Smsmith
22271867Smsmith        /* Storing an object into a Name "container" */
22371867Smsmith
22477424Smsmith        Status = AcpiExStoreObjectToNode (ValDesc, RefDesc->Reference.Object,
22567754Smsmith                        WalkState);
22671867Smsmith        break;
22767754Smsmith
22867754Smsmith
22967754Smsmith    case AML_INDEX_OP:
23067754Smsmith
23171867Smsmith        /* Storing to an Index (pointer into a packager or buffer) */
23267754Smsmith
23377424Smsmith        Status = AcpiExStoreObjectToIndex (ValDesc, RefDesc, WalkState);
23471867Smsmith        break;
23571867Smsmith
23671867Smsmith
23771867Smsmith    case AML_LOCAL_OP:
23877424Smsmith    case AML_ARG_OP:
23971867Smsmith
24077424Smsmith        /* Store to a method local/arg  */
24171867Smsmith
24277424Smsmith        Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Opcode,
24377424Smsmith                        RefDesc->Reference.Offset, ValDesc, WalkState);
24471867Smsmith        break;
24571867Smsmith
24671867Smsmith
24771867Smsmith    case AML_DEBUG_OP:
24871867Smsmith
24967754Smsmith        /*
25071867Smsmith         * Storing to the Debug object causes the value stored to be
25171867Smsmith         * displayed and otherwise has no effect -- see ACPI Specification
25267754Smsmith         */
25383174Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Write to Debug Object: ****:\n\n"));
25477424Smsmith
25583174Smsmith        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ",
25677424Smsmith                        AcpiUtGetTypeName (ValDesc->Common.Type)));
25777424Smsmith
25877424Smsmith        switch (ValDesc->Common.Type)
25971867Smsmith        {
26077424Smsmith        case ACPI_TYPE_INTEGER:
26177424Smsmith
26283174Smsmith            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%X (%d)\n",
26377424Smsmith                (UINT32) ValDesc->Integer.Value, (UINT32) ValDesc->Integer.Value));
26477424Smsmith            break;
26577424Smsmith
26677424Smsmith
26777424Smsmith        case ACPI_TYPE_BUFFER:
26877424Smsmith
26983174Smsmith            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%X\n",
27077424Smsmith                (UINT32) ValDesc->Buffer.Length));
27177424Smsmith            break;
27277424Smsmith
27377424Smsmith
27477424Smsmith        case ACPI_TYPE_STRING:
27577424Smsmith
27683174Smsmith            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s\n", ValDesc->String.Pointer));
27777424Smsmith            break;
27877424Smsmith
27977424Smsmith
28077424Smsmith        case ACPI_TYPE_PACKAGE:
28177424Smsmith
28283174Smsmith            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Elements - 0x%X\n",
28377424Smsmith                (UINT32) ValDesc->Package.Elements));
28477424Smsmith            break;
28577424Smsmith
28677424Smsmith
28777424Smsmith        default:
28877424Smsmith
28983174Smsmith            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "@0x%p\n", ValDesc));
29077424Smsmith            break;
29171867Smsmith        }
29267754Smsmith
29383174Smsmith        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n"));
29471867Smsmith        break;
29571867Smsmith
29671867Smsmith
29771867Smsmith    case AML_ZERO_OP:
29871867Smsmith    case AML_ONE_OP:
29971867Smsmith    case AML_ONES_OP:
30082367Smsmith    case AML_REVISION_OP:
30171867Smsmith
30267754Smsmith        /*
30371867Smsmith         * Storing to a constant is a no-op -- see ACPI Specification
30471867Smsmith         * Delete the reference descriptor, however
30571867Smsmith         */
30671867Smsmith        break;
30771867Smsmith
30871867Smsmith
30971867Smsmith    default:
31071867Smsmith
31182367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - Unknown Reference subtype %02x\n",
31277424Smsmith            RefDesc->Reference.Opcode));
31371867Smsmith
31471867Smsmith        /* TBD: [Restructure] use object dump routine !! */
31571867Smsmith
31671867Smsmith        DUMP_BUFFER (RefDesc, sizeof (ACPI_OPERAND_OBJECT));
31771867Smsmith
31871867Smsmith        Status = AE_AML_INTERNAL;
31971867Smsmith        break;
32071867Smsmith
32177424Smsmith    }   /* switch (RefDesc->Reference.Opcode) */
32271867Smsmith
32371867Smsmith
32471867Smsmith    /* Always delete the reference descriptor object */
32571867Smsmith
32671867Smsmith    if (RefDesc)
32771867Smsmith    {
32877424Smsmith        AcpiUtRemoveReference (RefDesc);
32971867Smsmith    }
33071867Smsmith
33171867Smsmith    return_ACPI_STATUS (Status);
33271867Smsmith}
33371867Smsmith
33471867Smsmith
33571867Smsmith/*******************************************************************************
33671867Smsmith *
33777424Smsmith * FUNCTION:    AcpiExStoreObjectToIndex
33871867Smsmith *
33971867Smsmith * PARAMETERS:  *ValDesc            - Value to be stored
34077424Smsmith *              *Node               - Named object to receive the value
34171867Smsmith *
34271867Smsmith * RETURN:      Status
34371867Smsmith *
34471867Smsmith * DESCRIPTION: Store the object to the named object.
34571867Smsmith *
34671867Smsmith ******************************************************************************/
34771867Smsmith
34871867SmsmithACPI_STATUS
34977424SmsmithAcpiExStoreObjectToIndex (
35071867Smsmith    ACPI_OPERAND_OBJECT     *ValDesc,
35171867Smsmith    ACPI_OPERAND_OBJECT     *DestDesc,
35271867Smsmith    ACPI_WALK_STATE         *WalkState)
35371867Smsmith{
35471867Smsmith    ACPI_STATUS             Status = AE_OK;
35571867Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
35671867Smsmith    UINT32                  Length;
35771867Smsmith    UINT32                  i;
35871867Smsmith    UINT8                   Value = 0;
35971867Smsmith
36071867Smsmith
36183174Smsmith    FUNCTION_TRACE ("ExStoreObjectToIndex");
36271867Smsmith
36371867Smsmith
36471867Smsmith    /*
36571867Smsmith     * Destination must be a reference pointer, and
36671867Smsmith     * must point to either a buffer or a package
36771867Smsmith     */
36871867Smsmith    switch (DestDesc->Reference.TargetType)
36971867Smsmith    {
37071867Smsmith    case ACPI_TYPE_PACKAGE:
37171867Smsmith        /*
37271867Smsmith         * Storing to a package element is not simple.  The source must be
37367754Smsmith         * evaluated and converted to the type of the destination and then the
37467754Smsmith         * source is copied into the destination - we can't just point to the
37567754Smsmith         * source object.
37667754Smsmith         */
37767754Smsmith        if (DestDesc->Reference.TargetType == ACPI_TYPE_PACKAGE)
37867754Smsmith        {
37967754Smsmith            /*
38067754Smsmith             * The object at *(DestDesc->Reference.Where) is the
38167754Smsmith             *  element within the package that is to be modified.
38267754Smsmith             */
38371867Smsmith            ObjDesc = *(DestDesc->Reference.Where);
38471867Smsmith            if (ObjDesc)
38567754Smsmith            {
38667754Smsmith                /*
38767754Smsmith                 * If the Destination element is a package, we will delete
38867754Smsmith                 *  that object and construct a new one.
38967754Smsmith                 *
39067754Smsmith                 * TBD: [Investigate] Should both the src and dest be required
39167754Smsmith                 *      to be packages?
39267754Smsmith                 *       && (ValDesc->Common.Type == ACPI_TYPE_PACKAGE)
39367754Smsmith                 */
39471867Smsmith                if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
39567754Smsmith                {
39667754Smsmith                    /*
39767754Smsmith                     * Take away the reference for being part of a package and
39867754Smsmith                     * delete
39967754Smsmith                     */
40077424Smsmith                    AcpiUtRemoveReference (ObjDesc);
40177424Smsmith                    AcpiUtRemoveReference (ObjDesc);
40267754Smsmith
40371867Smsmith                    ObjDesc = NULL;
40467754Smsmith                }
40567754Smsmith            }
40667754Smsmith
40771867Smsmith            if (!ObjDesc)
40867754Smsmith            {
40967754Smsmith                /*
41071867Smsmith                 * If the ObjDesc is NULL, it means that an uninitialized package
41177424Smsmith                 * element has been used as a destination (this is OK), therefore,
41277424Smsmith                 * we must create the destination element to match the type of the
41371867Smsmith                 * source element NOTE: ValDesc can be of any type.
41467754Smsmith                 */
41577424Smsmith                ObjDesc = AcpiUtCreateInternalObject (ValDesc->Common.Type);
41671867Smsmith                if (!ObjDesc)
41767754Smsmith                {
41871867Smsmith                    return_ACPI_STATUS (AE_NO_MEMORY);
41967754Smsmith                }
42067754Smsmith
42167754Smsmith                /*
42267754Smsmith                 * If the source is a package, copy the source to the new dest
42367754Smsmith                 */
42471867Smsmith                if (ACPI_TYPE_PACKAGE == ObjDesc->Common.Type)
42567754Smsmith                {
42677424Smsmith                    Status = AcpiUtCopyIpackageToIpackage (ValDesc, ObjDesc, WalkState);
42767754Smsmith                    if (ACPI_FAILURE (Status))
42867754Smsmith                    {
42977424Smsmith                        AcpiUtRemoveReference (ObjDesc);
43071867Smsmith                        return_ACPI_STATUS (Status);
43167754Smsmith                    }
43267754Smsmith                }
43367754Smsmith
43467754Smsmith                /*
43567754Smsmith                 * Install the new descriptor into the package and add a
43667754Smsmith                 * reference to the newly created descriptor for now being
43767754Smsmith                 * part of the parent package
43867754Smsmith                 */
43971867Smsmith                *(DestDesc->Reference.Where) = ObjDesc;
44077424Smsmith                AcpiUtAddReference (ObjDesc);
44167754Smsmith            }
44267754Smsmith
44371867Smsmith            if (ACPI_TYPE_PACKAGE != ObjDesc->Common.Type)
44467754Smsmith            {
44567754Smsmith                /*
44667754Smsmith                 * The destination element is not a package, so we need to
44767754Smsmith                 * convert the contents of the source (ValDesc) and copy into
44871867Smsmith                 * the destination (ObjDesc)
44967754Smsmith                 */
45077424Smsmith                Status = AcpiExStoreObjectToObject (ValDesc, ObjDesc,
45167754Smsmith                                                        WalkState);
45267754Smsmith                if (ACPI_FAILURE (Status))
45367754Smsmith                {
45467754Smsmith                    /*
45567754Smsmith                     * An error occurrered when copying the internal object
45667754Smsmith                     * so delete the reference.
45767754Smsmith                     */
45882367Smsmith                    ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
45982367Smsmith                        "Unable to copy the internal object\n"));
46071867Smsmith                    return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
46167754Smsmith                }
46267754Smsmith            }
46367754Smsmith        }
46471867Smsmith        break;
46567754Smsmith
46667754Smsmith
46771867Smsmith    case ACPI_TYPE_BUFFER_FIELD:
46877424Smsmith
46977424Smsmith
47077424Smsmith        /* TBD: can probably call the generic Buffer/Field routines */
47177424Smsmith
47267754Smsmith        /*
47367754Smsmith         * Storing into a buffer at a location defined by an Index.
47467754Smsmith         *
47567754Smsmith         * Each 8-bit element of the source object is written to the
47667754Smsmith         * 8-bit Buffer Field of the Index destination object.
47767754Smsmith         */
47867754Smsmith
47967754Smsmith        /*
48071867Smsmith         * Set the ObjDesc to the destination object and type check.
48167754Smsmith         */
48271867Smsmith        ObjDesc = DestDesc->Reference.Object;
48371867Smsmith        if (ObjDesc->Common.Type != ACPI_TYPE_BUFFER)
48467754Smsmith        {
48571867Smsmith            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
48667754Smsmith        }
48767754Smsmith
48867754Smsmith        /*
48967754Smsmith         * The assignment of the individual elements will be slightly
49067754Smsmith         * different for each source type.
49167754Smsmith         */
49267754Smsmith        switch (ValDesc->Common.Type)
49367754Smsmith        {
49471867Smsmith        case ACPI_TYPE_INTEGER:
49577424Smsmith            /*
49677424Smsmith             * Type is Integer, assign bytewise
49777424Smsmith             * This loop to assign each of the elements is somewhat
49877424Smsmith             * backward because of the Big Endian-ness of IA-64
49977424Smsmith             */
50071867Smsmith            Length = sizeof (ACPI_INTEGER);
50167754Smsmith            for (i = Length; i != 0; i--)
50267754Smsmith            {
50371867Smsmith                Value = (UINT8)(ValDesc->Integer.Value >> (MUL_8 (i - 1)));
50471867Smsmith                ObjDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value;
50567754Smsmith            }
50667754Smsmith            break;
50767754Smsmith
50877424Smsmith
50967754Smsmith        case ACPI_TYPE_BUFFER:
51077424Smsmith            /*
51177424Smsmith             * Type is Buffer, the Length is in the structure.
51277424Smsmith             * Just loop through the elements and assign each one in turn.
51377424Smsmith             */
51467754Smsmith            Length = ValDesc->Buffer.Length;
51567754Smsmith            for (i = 0; i < Length; i++)
51667754Smsmith            {
51782367Smsmith                Value = ValDesc->Buffer.Pointer[i];
51871867Smsmith                ObjDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value;
51967754Smsmith            }
52067754Smsmith            break;
52167754Smsmith
52277424Smsmith
52367754Smsmith        case ACPI_TYPE_STRING:
52477424Smsmith            /*
52577424Smsmith             * Type is String, the Length is in the structure.
52677424Smsmith             * Just loop through the elements and assign each one in turn.
52777424Smsmith             */
52867754Smsmith            Length = ValDesc->String.Length;
52967754Smsmith            for (i = 0; i < Length; i++)
53067754Smsmith            {
53182367Smsmith                Value = ValDesc->String.Pointer[i];
53271867Smsmith                ObjDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value;
53367754Smsmith            }
53467754Smsmith            break;
53567754Smsmith
53677424Smsmith
53767754Smsmith        default:
53877424Smsmith
53977424Smsmith            /* Other types are invalid */
54077424Smsmith
54182367Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
54282367Smsmith                "Source must be Number/Buffer/String type, not %X\n",
54367754Smsmith                ValDesc->Common.Type));
54467754Smsmith            Status = AE_AML_OPERAND_TYPE;
54567754Smsmith            break;
54667754Smsmith        }
54771867Smsmith        break;
54867754Smsmith
54967754Smsmith
55071867Smsmith    default:
55182367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Target is not a Package or BufferField\n"));
55271867Smsmith        Status = AE_AML_OPERAND_TYPE;
55367754Smsmith        break;
55471867Smsmith    }
55567754Smsmith
55667754Smsmith
55771867Smsmith    return_ACPI_STATUS (Status);
55871867Smsmith}
55967754Smsmith
56067754Smsmith
56171867Smsmith/*******************************************************************************
56271867Smsmith *
56377424Smsmith * FUNCTION:    AcpiExStoreObjectToNode
56471867Smsmith *
56571867Smsmith * PARAMETERS:  *SourceDesc            - Value to be stored
56677424Smsmith *              *Node                  - Named object to receive the value
56771867Smsmith *
56871867Smsmith * RETURN:      Status
56971867Smsmith *
57071867Smsmith * DESCRIPTION: Store the object to the named object.
57171867Smsmith *
57271867Smsmith *              The Assignment of an object to a named object is handled here
57371867Smsmith *              The val passed in will replace the current value (if any)
57471867Smsmith *              with the input value.
57571867Smsmith *
57671867Smsmith *              When storing into an object the data is converted to the
57771867Smsmith *              target object type then stored in the object.  This means
57871867Smsmith *              that the target object type (for an initialized target) will
57971867Smsmith *              not be changed by a store operation.
58071867Smsmith *
58171867Smsmith *              NOTE: the global lock is acquired early.  This will result
58271867Smsmith *              in the global lock being held a bit longer.  Also, if the
58371867Smsmith *              function fails during set up we may get the lock when we
58471867Smsmith *              don't really need it.  I don't think we care.
58571867Smsmith *
58671867Smsmith ******************************************************************************/
58767754Smsmith
58871867SmsmithACPI_STATUS
58977424SmsmithAcpiExStoreObjectToNode (
59071867Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc,
59171867Smsmith    ACPI_NAMESPACE_NODE     *Node,
59271867Smsmith    ACPI_WALK_STATE         *WalkState)
59371867Smsmith{
59471867Smsmith    ACPI_STATUS             Status = AE_OK;
59571867Smsmith    ACPI_OPERAND_OBJECT     *TargetDesc;
59677424Smsmith    ACPI_OBJECT_TYPE8       TargetType = ACPI_TYPE_ANY;
59767754Smsmith
59871867Smsmith
59977424Smsmith    FUNCTION_TRACE ("ExStoreObjectToNode");
60071867Smsmith
60183174Smsmith
60271867Smsmith    /*
60371867Smsmith     * Assuming the parameters were already validated
60471867Smsmith     */
60571867Smsmith
60671867Smsmith    /*
60771867Smsmith     * Get current type of the node, and object attached to Node
60871867Smsmith     */
60971867Smsmith    TargetType = AcpiNsGetType (Node);
61071867Smsmith    TargetDesc = AcpiNsGetAttachedObject (Node);
61171867Smsmith
61282367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Storing %p(%s) into node %p(%s)\n",
61377424Smsmith        Node, AcpiUtGetTypeName (SourceDesc->Common.Type),
61477424Smsmith        SourceDesc, AcpiUtGetTypeName (TargetType)));
61571867Smsmith
61671867Smsmith
61771867Smsmith    /*
61871867Smsmith     * Resolve the source object to an actual value
61977424Smsmith     * (If it is a reference object)
62071867Smsmith     */
62177424Smsmith    Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState);
62271867Smsmith    if (ACPI_FAILURE (Status))
62371867Smsmith    {
62471867Smsmith        return_ACPI_STATUS (Status);
62571867Smsmith    }
62671867Smsmith
62771867Smsmith
62871867Smsmith    /*
62977424Smsmith     * Do the actual store operation
63071867Smsmith     */
63171867Smsmith    switch (TargetType)
63271867Smsmith    {
63377424Smsmith    case ACPI_TYPE_BUFFER_FIELD:
63477424Smsmith    case INTERNAL_TYPE_REGION_FIELD:
63577424Smsmith    case INTERNAL_TYPE_BANK_FIELD:
63677424Smsmith    case INTERNAL_TYPE_INDEX_FIELD:
63771867Smsmith
63877424Smsmith        /*
63977424Smsmith         * For fields, copy the source data to the target field.
64077424Smsmith         */
64177424Smsmith        Status = AcpiExWriteDataToField (SourceDesc, TargetDesc);
64267754Smsmith        break;
64367754Smsmith
64467754Smsmith
64571867Smsmith    case ACPI_TYPE_INTEGER:
64671867Smsmith    case ACPI_TYPE_STRING:
64771867Smsmith    case ACPI_TYPE_BUFFER:
64867754Smsmith
64977424Smsmith        /*
65071867Smsmith         * These target types are all of type Integer/String/Buffer, and
65171867Smsmith         * therefore support implicit conversion before the store.
65277424Smsmith         *
65377424Smsmith         * Copy and/or convert the source object to a new target object
65467754Smsmith         */
65577424Smsmith        Status = AcpiExStoreObject (SourceDesc, TargetType, &TargetDesc, WalkState);
65671867Smsmith        if (ACPI_FAILURE (Status))
65767754Smsmith        {
65871867Smsmith            return_ACPI_STATUS (Status);
65967754Smsmith        }
66067754Smsmith
66171867Smsmith        /*
66271867Smsmith         * Store the new TargetDesc as the new value of the Name, and set
66371867Smsmith         * the Name's type to that of the value being stored in it.
66471867Smsmith         * SourceDesc reference count is incremented by AttachObject.
66571867Smsmith         */
66671867Smsmith        Status = AcpiNsAttachObject (Node, TargetDesc, TargetType);
66782367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
66882367Smsmith            "Store %s into %s via Convert/Attach\n",
66977424Smsmith            AcpiUtGetTypeName (TargetDesc->Common.Type),
67077424Smsmith            AcpiUtGetTypeName (TargetType)));
67167754Smsmith        break;
67267754Smsmith
67377424Smsmith
67467754Smsmith    default:
67567754Smsmith
67671867Smsmith        /* No conversions for all other types.  Just attach the source object */
67767754Smsmith
67871867Smsmith        Status = AcpiNsAttachObject (Node, SourceDesc, SourceDesc->Common.Type);
67977424Smsmith
68082367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
68182367Smsmith            "Store %s into %s via Attach only\n",
68277424Smsmith            AcpiUtGetTypeName (SourceDesc->Common.Type),
68377424Smsmith            AcpiUtGetTypeName (SourceDesc->Common.Type)));
68471867Smsmith        break;
68571867Smsmith    }
68667754Smsmith
68767754Smsmith
68871867Smsmith    return_ACPI_STATUS (Status);
68971867Smsmith}
69067754Smsmith
69167754Smsmith
69271867Smsmith/*******************************************************************************
69371867Smsmith *
69477424Smsmith * FUNCTION:    AcpiExStoreObjectToObject
69571867Smsmith *
69671867Smsmith * PARAMETERS:  *SourceDesc            - Value to be stored
69771867Smsmith *              *DestDesc           - Object to receive the value
69871867Smsmith *
69971867Smsmith * RETURN:      Status
70071867Smsmith *
70171867Smsmith * DESCRIPTION: Store an object to another object.
70271867Smsmith *
70371867Smsmith *              The Assignment of an object to another (not named) object
70471867Smsmith *              is handled here.
70571867Smsmith *              The val passed in will replace the current value (if any)
70671867Smsmith *              with the input value.
70771867Smsmith *
70871867Smsmith *              When storing into an object the data is converted to the
70971867Smsmith *              target object type then stored in the object.  This means
71071867Smsmith *              that the target object type (for an initialized target) will
71171867Smsmith *              not be changed by a store operation.
71271867Smsmith *
71371867Smsmith *              This module allows destination types of Number, String,
71471867Smsmith *              and Buffer.
71571867Smsmith *
71671867Smsmith ******************************************************************************/
71767754Smsmith
71871867SmsmithACPI_STATUS
71977424SmsmithAcpiExStoreObjectToObject (
72071867Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc,
72171867Smsmith    ACPI_OPERAND_OBJECT     *DestDesc,
72271867Smsmith    ACPI_WALK_STATE         *WalkState)
72371867Smsmith{
72471867Smsmith    ACPI_STATUS             Status = AE_OK;
72577424Smsmith    ACPI_OBJECT_TYPE8       DestinationType = DestDesc->Common.Type;
72667754Smsmith
72771867Smsmith
72877424Smsmith    FUNCTION_TRACE ("ExStoreObjectToObject");
72971867Smsmith
73071867Smsmith
73171867Smsmith    /*
73271867Smsmith     *  Assuming the parameters are valid!
73371867Smsmith     */
73482367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Storing %p(%s) to %p(%s)\n",
73577424Smsmith                    SourceDesc, AcpiUtGetTypeName (SourceDesc->Common.Type),
73677424Smsmith                    DestDesc, AcpiUtGetTypeName (DestDesc->Common.Type)));
73771867Smsmith
73871867Smsmith
73971867Smsmith    /*
74071867Smsmith     * From this interface, we only support Integers/Strings/Buffers
74171867Smsmith     */
74271867Smsmith    switch (DestinationType)
74367754Smsmith    {
74471867Smsmith    case ACPI_TYPE_INTEGER:
74571867Smsmith    case ACPI_TYPE_STRING:
74671867Smsmith    case ACPI_TYPE_BUFFER:
74771867Smsmith        break;
74871867Smsmith
74971867Smsmith    default:
75082367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into %s not implemented\n",
75177424Smsmith            AcpiUtGetTypeName (DestDesc->Common.Type)));
75271867Smsmith
75371867Smsmith        return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
75467754Smsmith    }
75567754Smsmith
75671867Smsmith
75771867Smsmith    /*
75871867Smsmith     * Resolve the source object to an actual value
75977424Smsmith     * (If it is a reference object)
76071867Smsmith     */
76177424Smsmith    Status = AcpiExResolveObject (&SourceDesc, DestinationType, WalkState);
76271867Smsmith    if (ACPI_FAILURE (Status))
76371867Smsmith    {
76471867Smsmith        return_ACPI_STATUS (Status);
76571867Smsmith    }
76671867Smsmith
76771867Smsmith
76871867Smsmith    /*
76977424Smsmith     * Copy and/or convert the source object to the destination object
77071867Smsmith     */
77177424Smsmith    Status = AcpiExStoreObject (SourceDesc, DestinationType, &DestDesc, WalkState);
77271867Smsmith
77371867Smsmith
77467754Smsmith    return_ACPI_STATUS (Status);
77567754Smsmith}
77667754Smsmith
777