exstore.c revision 281075
167754Smsmith/******************************************************************************
267754Smsmith *
377424Smsmith * Module Name: exstore - AML Interpreter object store support
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8281075Sdim * Copyright (C) 2000 - 2015, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
47193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
5067754Smsmith
5167754Smsmith
5277424Smsmith#define _COMPONENT          ACPI_EXECUTER
5391116Smsmith        ACPI_MODULE_NAME    ("exstore")
5467754Smsmith
55151937Sjkim/* Local prototypes */
5667754Smsmith
57151937Sjkimstatic ACPI_STATUS
58151937SjkimAcpiExStoreObjectToIndex (
59151937Sjkim    ACPI_OPERAND_OBJECT     *ValDesc,
60151937Sjkim    ACPI_OPERAND_OBJECT     *DestDesc,
61151937Sjkim    ACPI_WALK_STATE         *WalkState);
62151937Sjkim
63281075Sdimstatic ACPI_STATUS
64281075SdimAcpiExStoreDirectToNode (
65281075Sdim    ACPI_OPERAND_OBJECT     *SourceDesc,
66281075Sdim    ACPI_NAMESPACE_NODE     *Node,
67281075Sdim    ACPI_WALK_STATE         *WalkState);
68151937Sjkim
69281075Sdim
7067754Smsmith/*******************************************************************************
7167754Smsmith *
7277424Smsmith * FUNCTION:    AcpiExStore
7367754Smsmith *
7485756Smsmith * PARAMETERS:  *SourceDesc         - Value to be stored
75238381Sjkim *              *DestDesc           - Where to store it. Must be an NS node
76238381Sjkim *                                    or ACPI_OPERAND_OBJECT of type
7787031Smsmith *                                    Reference;
7887031Smsmith *              WalkState           - Current walk state
7967754Smsmith *
8067754Smsmith * RETURN:      Status
8167754Smsmith *
8285756Smsmith * DESCRIPTION: Store the value described by SourceDesc into the location
83238381Sjkim *              described by DestDesc. Called by various interpreter
8467754Smsmith *              functions to store the result of an operation into
8591116Smsmith *              the destination operand -- not just simply the actual "Store"
8687031Smsmith *              ASL operator.
8767754Smsmith *
8867754Smsmith ******************************************************************************/
8967754Smsmith
9067754SmsmithACPI_STATUS
9177424SmsmithAcpiExStore (
9285756Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc,
9367754Smsmith    ACPI_OPERAND_OBJECT     *DestDesc,
9467754Smsmith    ACPI_WALK_STATE         *WalkState)
9567754Smsmith{
9667754Smsmith    ACPI_STATUS             Status = AE_OK;
9771867Smsmith    ACPI_OPERAND_OBJECT     *RefDesc = DestDesc;
9867754Smsmith
9967754Smsmith
100167802Sjkim    ACPI_FUNCTION_TRACE_PTR (ExStore, DestDesc);
10167754Smsmith
10267754Smsmith
10367754Smsmith    /* Validate parameters */
10467754Smsmith
10585756Smsmith    if (!SourceDesc || !DestDesc)
10667754Smsmith    {
107167802Sjkim        ACPI_ERROR ((AE_INFO, "Null parameter"));
10867754Smsmith        return_ACPI_STATUS (AE_AML_NO_OPERAND);
10967754Smsmith    }
11067754Smsmith
11171867Smsmith    /* DestDesc can be either a namespace node or an ACPI object */
11267754Smsmith
11391116Smsmith    if (ACPI_GET_DESCRIPTOR_TYPE (DestDesc) == ACPI_DESC_TYPE_NAMED)
11467754Smsmith    {
11577424Smsmith        /*
11671867Smsmith         * Dest is a namespace node,
117107325Siwasaki         * Storing an object into a Named node.
11871867Smsmith         */
11985756Smsmith        Status = AcpiExStoreObjectToNode (SourceDesc,
120128212Snjl                    (ACPI_NAMESPACE_NODE *) DestDesc, WalkState,
121128212Snjl                    ACPI_IMPLICIT_CONVERSION);
12267754Smsmith
12371867Smsmith        return_ACPI_STATUS (Status);
12467754Smsmith    }
12567754Smsmith
12699679Siwasaki    /* Destination object must be a Reference or a Constant object */
12767754Smsmith
128193267Sjkim    switch (DestDesc->Common.Type)
129102550Siwasaki    {
130107325Siwasaki    case ACPI_TYPE_LOCAL_REFERENCE:
131250838Sjkim
13299679Siwasaki        break;
13399679Siwasaki
13499679Siwasaki    case ACPI_TYPE_INTEGER:
13599679Siwasaki
13699679Siwasaki        /* Allow stores to Constants -- a Noop as per ACPI spec */
13799679Siwasaki
13899679Siwasaki        if (DestDesc->Common.Flags & AOPOBJ_AML_CONSTANT)
13999679Siwasaki        {
14099679Siwasaki            return_ACPI_STATUS (AE_OK);
14199679Siwasaki        }
14299679Siwasaki
143104470Siwasaki        /*lint -fallthrough */
14499679Siwasaki
14599679Siwasaki    default:
14699679Siwasaki
147126372Snjl        /* Destination is not a Reference object */
14867754Smsmith
149167802Sjkim        ACPI_ERROR ((AE_INFO,
150167802Sjkim            "Target is not a Reference or Constant object - %s [%p]",
151138287Smarks            AcpiUtGetObjectTypeName (DestDesc), DestDesc));
15267754Smsmith
15367754Smsmith        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
15467754Smsmith    }
15567754Smsmith
15677424Smsmith    /*
157193267Sjkim     * Examine the Reference class. These cases are handled:
15871867Smsmith     *
15971867Smsmith     * 1) Store to Name (Change the object associated with a name)
16071867Smsmith     * 2) Store to an indexed area of a Buffer or Package
16171867Smsmith     * 3) Store to a Method Local or Arg
16271867Smsmith     * 4) Store to the debug object
16371867Smsmith     */
164193267Sjkim    switch (RefDesc->Reference.Class)
16567754Smsmith    {
166193267Sjkim    case ACPI_REFCLASS_REFOF:
16767754Smsmith
16871867Smsmith        /* Storing an object into a Name "container" */
16971867Smsmith
170151937Sjkim        Status = AcpiExStoreObjectToNode (SourceDesc,
171151937Sjkim                    RefDesc->Reference.Object,
172151937Sjkim                    WalkState, ACPI_IMPLICIT_CONVERSION);
17371867Smsmith        break;
17467754Smsmith
175193267Sjkim    case ACPI_REFCLASS_INDEX:
17667754Smsmith
17771867Smsmith        /* Storing to an Index (pointer into a packager or buffer) */
17867754Smsmith
17985756Smsmith        Status = AcpiExStoreObjectToIndex (SourceDesc, RefDesc, WalkState);
18071867Smsmith        break;
18171867Smsmith
182193267Sjkim    case ACPI_REFCLASS_LOCAL:
183193267Sjkim    case ACPI_REFCLASS_ARG:
18471867Smsmith
18577424Smsmith        /* Store to a method local/arg  */
18671867Smsmith
187193267Sjkim        Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Class,
188193267Sjkim                    RefDesc->Reference.Value, SourceDesc, WalkState);
18971867Smsmith        break;
19071867Smsmith
191193267Sjkim    case ACPI_REFCLASS_DEBUG:
19267754Smsmith        /*
19371867Smsmith         * Storing to the Debug object causes the value stored to be
19471867Smsmith         * displayed and otherwise has no effect -- see ACPI Specification
19567754Smsmith         */
196138287Smarks        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
197138287Smarks            "**** Write to Debug Object: Object %p %s ****:\n\n",
198138287Smarks            SourceDesc, AcpiUtGetObjectTypeName (SourceDesc)));
19977424Smsmith
200204773Sjkim        ACPI_DEBUG_OBJECT (SourceDesc, 0, 0);
20171867Smsmith        break;
20271867Smsmith
20371867Smsmith    default:
20471867Smsmith
205204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
206193267Sjkim            RefDesc->Reference.Class));
207193267Sjkim        ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_INFO);
20871867Smsmith
20971867Smsmith        Status = AE_AML_INTERNAL;
21071867Smsmith        break;
21199679Siwasaki    }
21271867Smsmith
21371867Smsmith    return_ACPI_STATUS (Status);
21471867Smsmith}
21571867Smsmith
21671867Smsmith
21771867Smsmith/*******************************************************************************
21871867Smsmith *
21977424Smsmith * FUNCTION:    AcpiExStoreObjectToIndex
22071867Smsmith *
22187031Smsmith * PARAMETERS:  *SourceDesc             - Value to be stored
22287031Smsmith *              *DestDesc               - Named object to receive the value
22387031Smsmith *              WalkState               - Current walk state
22471867Smsmith *
22571867Smsmith * RETURN:      Status
22671867Smsmith *
22787031Smsmith * DESCRIPTION: Store the object to indexed Buffer or Package element
22871867Smsmith *
22971867Smsmith ******************************************************************************/
23071867Smsmith
231151937Sjkimstatic ACPI_STATUS
23277424SmsmithAcpiExStoreObjectToIndex (
23385756Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc,
23491116Smsmith    ACPI_OPERAND_OBJECT     *IndexDesc,
23571867Smsmith    ACPI_WALK_STATE         *WalkState)
23671867Smsmith{
23771867Smsmith    ACPI_STATUS             Status = AE_OK;
23871867Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
23991116Smsmith    ACPI_OPERAND_OBJECT     *NewDesc;
24071867Smsmith    UINT8                   Value = 0;
241126372Snjl    UINT32                  i;
24271867Smsmith
24371867Smsmith
244167802Sjkim    ACPI_FUNCTION_TRACE (ExStoreObjectToIndex);
24571867Smsmith
24671867Smsmith
24771867Smsmith    /*
24871867Smsmith     * Destination must be a reference pointer, and
24971867Smsmith     * must point to either a buffer or a package
25071867Smsmith     */
25191116Smsmith    switch (IndexDesc->Reference.TargetType)
25271867Smsmith    {
25371867Smsmith    case ACPI_TYPE_PACKAGE:
25471867Smsmith        /*
255138287Smarks         * Storing to a package element. Copy the object and replace
256138287Smarks         * any existing object with the new object. No implicit
257138287Smarks         * conversion is performed.
258138287Smarks         *
25991116Smsmith         * The object at *(IndexDesc->Reference.Where) is the
26091116Smsmith         * element within the package that is to be modified.
261126372Snjl         * The parent package object is at IndexDesc->Reference.Object
26291116Smsmith         */
26391116Smsmith        ObjDesc = *(IndexDesc->Reference.Where);
26485756Smsmith
265193267Sjkim        if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE &&
266193267Sjkim            SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
26791116Smsmith        {
268193267Sjkim            /* This is a DDBHandle, just add a reference to it */
269193267Sjkim
270193267Sjkim            AcpiUtAddReference (SourceDesc);
271193267Sjkim            NewDesc = SourceDesc;
27291116Smsmith        }
273193267Sjkim        else
274193267Sjkim        {
275193267Sjkim            /* Normal object, copy it */
27667754Smsmith
277193267Sjkim            Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState);
278193267Sjkim            if (ACPI_FAILURE (Status))
279193267Sjkim            {
280193267Sjkim                return_ACPI_STATUS (Status);
281193267Sjkim            }
282193267Sjkim        }
283193267Sjkim
284138287Smarks        if (ObjDesc)
28591116Smsmith        {
286138287Smarks            /* Decrement reference count by the ref count of the parent package */
287104470Siwasaki
288151937Sjkim            for (i = 0;
289151937Sjkim                 i < ((ACPI_OPERAND_OBJECT *)
290151937Sjkim                        IndexDesc->Reference.Object)->Common.ReferenceCount;
291151937Sjkim                 i++)
292104470Siwasaki            {
293138287Smarks                AcpiUtRemoveReference (ObjDesc);
294104470Siwasaki            }
295138287Smarks        }
296151937Sjkim
297138287Smarks        *(IndexDesc->Reference.Where) = NewDesc;
298126372Snjl
299151937Sjkim        /* Increment ref count by the ref count of the parent package-1 */
300126372Snjl
301151937Sjkim        for (i = 1;
302151937Sjkim             i < ((ACPI_OPERAND_OBJECT *)
303151937Sjkim                    IndexDesc->Reference.Object)->Common.ReferenceCount;
304151937Sjkim             i++)
305138287Smarks        {
306138287Smarks            AcpiUtAddReference (NewDesc);
30767754Smsmith        }
308151937Sjkim
30971867Smsmith        break;
31067754Smsmith
31171867Smsmith    case ACPI_TYPE_BUFFER_FIELD:
31267754Smsmith        /*
313138287Smarks         * Store into a Buffer or String (not actually a real BufferField)
314138287Smarks         * at a location defined by an Index.
31567754Smsmith         *
31687031Smsmith         * The first 8-bit element of the source object is written to the
31787031Smsmith         * 8-bit Buffer location defined by the Index destination object,
31887031Smsmith         * according to the ACPI 2.0 specification.
31967754Smsmith         */
32067754Smsmith
32167754Smsmith        /*
322138287Smarks         * Make sure the target is a Buffer or String. An error should
323138287Smarks         * not happen here, since the ReferenceObject was constructed
324138287Smarks         * by the INDEX_OP code.
32567754Smsmith         */
32691116Smsmith        ObjDesc = IndexDesc->Reference.Object;
327193267Sjkim        if ((ObjDesc->Common.Type != ACPI_TYPE_BUFFER) &&
328193267Sjkim            (ObjDesc->Common.Type != ACPI_TYPE_STRING))
32967754Smsmith        {
33071867Smsmith            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
33167754Smsmith        }
33267754Smsmith
33367754Smsmith        /*
33467754Smsmith         * The assignment of the individual elements will be slightly
33567754Smsmith         * different for each source type.
33667754Smsmith         */
337193267Sjkim        switch (SourceDesc->Common.Type)
33867754Smsmith        {
33971867Smsmith        case ACPI_TYPE_INTEGER:
34087031Smsmith
34187031Smsmith            /* Use the least-significant byte of the integer */
34287031Smsmith
34387031Smsmith            Value = (UINT8) (SourceDesc->Integer.Value);
34467754Smsmith            break;
34567754Smsmith
34687031Smsmith        case ACPI_TYPE_BUFFER:
347138287Smarks        case ACPI_TYPE_STRING:
34877424Smsmith
349138287Smarks            /* Note: Takes advantage of common string/buffer fields */
350138287Smarks
35187031Smsmith            Value = SourceDesc->Buffer.Pointer[0];
35267754Smsmith            break;
35367754Smsmith
35467754Smsmith        default:
35577424Smsmith
35687031Smsmith            /* All other types are invalid */
35777424Smsmith
358167802Sjkim            ACPI_ERROR ((AE_INFO,
359167802Sjkim                "Source must be Integer/Buffer/String type, not %s",
36099679Siwasaki                AcpiUtGetObjectTypeName (SourceDesc)));
36187031Smsmith            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
36267754Smsmith        }
36387031Smsmith
36487031Smsmith        /* Store the source value into the target buffer byte */
36587031Smsmith
366193267Sjkim        ObjDesc->Buffer.Pointer[IndexDesc->Reference.Value] = Value;
36771867Smsmith        break;
36867754Smsmith
36971867Smsmith    default:
370167802Sjkim        ACPI_ERROR ((AE_INFO,
371167802Sjkim            "Target is not a Package or BufferField"));
37271867Smsmith        Status = AE_AML_OPERAND_TYPE;
37367754Smsmith        break;
37471867Smsmith    }
37567754Smsmith
37671867Smsmith    return_ACPI_STATUS (Status);
37771867Smsmith}
37867754Smsmith
37967754Smsmith
38071867Smsmith/*******************************************************************************
38171867Smsmith *
38277424Smsmith * FUNCTION:    AcpiExStoreObjectToNode
38371867Smsmith *
38487031Smsmith * PARAMETERS:  SourceDesc              - Value to be stored
38587031Smsmith *              Node                    - Named object to receive the value
38687031Smsmith *              WalkState               - Current walk state
387128212Snjl *              ImplicitConversion      - Perform implicit conversion (yes/no)
38871867Smsmith *
38971867Smsmith * RETURN:      Status
39071867Smsmith *
39171867Smsmith * DESCRIPTION: Store the object to the named object.
39271867Smsmith *
39371867Smsmith *              The Assignment of an object to a named object is handled here
39487031Smsmith *              The value passed in will replace the current value (if any)
39571867Smsmith *              with the input value.
39671867Smsmith *
39771867Smsmith *              When storing into an object the data is converted to the
398241973Sjkim *              target object type then stored in the object. This means
39971867Smsmith *              that the target object type (for an initialized target) will
400281075Sdim *              not be changed by a store operation. A CopyObject can change
401281075Sdim *              the target type, however.
40271867Smsmith *
403281075Sdim *              The ImplicitConversion flag is set to NO/FALSE only when
404281075Sdim *              storing to an ArgX -- as per the rules of the ACPI spec.
405281075Sdim *
40687031Smsmith *              Assumes parameters are already validated.
40771867Smsmith *
40871867Smsmith ******************************************************************************/
40967754Smsmith
41071867SmsmithACPI_STATUS
41177424SmsmithAcpiExStoreObjectToNode (
41271867Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc,
41371867Smsmith    ACPI_NAMESPACE_NODE     *Node,
414128212Snjl    ACPI_WALK_STATE         *WalkState,
415128212Snjl    UINT8                   ImplicitConversion)
41671867Smsmith{
41771867Smsmith    ACPI_STATUS             Status = AE_OK;
41871867Smsmith    ACPI_OPERAND_OBJECT     *TargetDesc;
41991116Smsmith    ACPI_OPERAND_OBJECT     *NewDesc;
42091116Smsmith    ACPI_OBJECT_TYPE        TargetType;
42167754Smsmith
42271867Smsmith
423167802Sjkim    ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToNode, SourceDesc);
42471867Smsmith
42583174Smsmith
426151937Sjkim    /* Get current type of the node, and object attached to Node */
427151937Sjkim
42871867Smsmith    TargetType = AcpiNsGetType (Node);
42971867Smsmith    TargetDesc = AcpiNsGetAttachedObject (Node);
43071867Smsmith
431281075Sdim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n",
43299679Siwasaki        SourceDesc, AcpiUtGetObjectTypeName (SourceDesc),
43391116Smsmith              Node, AcpiUtGetTypeName (TargetType)));
43471867Smsmith
43571867Smsmith    /*
43671867Smsmith     * Resolve the source object to an actual value
43777424Smsmith     * (If it is a reference object)
43871867Smsmith     */
43977424Smsmith    Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState);
44071867Smsmith    if (ACPI_FAILURE (Status))
44171867Smsmith    {
44271867Smsmith        return_ACPI_STATUS (Status);
44371867Smsmith    }
44471867Smsmith
445151937Sjkim    /* Do the actual store operation */
446151937Sjkim
44771867Smsmith    switch (TargetType)
44871867Smsmith    {
44971867Smsmith    case ACPI_TYPE_INTEGER:
45071867Smsmith    case ACPI_TYPE_STRING:
45171867Smsmith    case ACPI_TYPE_BUFFER:
45277424Smsmith        /*
453281075Sdim         * The simple data types all support implicit source operand
454281075Sdim         * conversion before the store.
45567754Smsmith         */
456281075Sdim
457281075Sdim        if ((WalkState->Opcode == AML_COPY_OP) ||
458281075Sdim            !ImplicitConversion)
459281075Sdim        {
460281075Sdim            /*
461281075Sdim             * However, CopyObject and Stores to ArgX do not perform
462281075Sdim             * an implicit conversion, as per the ACPI specification.
463281075Sdim             * A direct store is performed instead.
464281075Sdim             */
465281075Sdim            Status = AcpiExStoreDirectToNode (SourceDesc, Node,
466281075Sdim                WalkState);
467281075Sdim            break;
468281075Sdim        }
469281075Sdim
470281075Sdim        /* Store with implicit source operand conversion support */
471281075Sdim
472151937Sjkim        Status = AcpiExStoreObjectToObject (SourceDesc, TargetDesc,
473281075Sdim            &NewDesc, WalkState);
47471867Smsmith        if (ACPI_FAILURE (Status))
47567754Smsmith        {
47671867Smsmith            return_ACPI_STATUS (Status);
47767754Smsmith        }
47867754Smsmith
47991116Smsmith        if (NewDesc != TargetDesc)
48091116Smsmith        {
48191116Smsmith            /*
48291116Smsmith             * Store the new NewDesc as the new value of the Name, and set
48391116Smsmith             * the Name's type to that of the value being stored in it.
48491116Smsmith             * SourceDesc reference count is incremented by AttachObject.
485104470Siwasaki             *
486281075Sdim             * Note: This may change the type of the node if an explicit
487281075Sdim             * store has been performed such that the node/object type
488281075Sdim             * has been changed.
48991116Smsmith             */
490281075Sdim            Status = AcpiNsAttachObject (Node, NewDesc,
491281075Sdim                NewDesc->Common.Type);
49285756Smsmith
49399146Siwasaki            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
49491116Smsmith                "Store %s into %s via Convert/Attach\n",
49599679Siwasaki                AcpiUtGetObjectTypeName (SourceDesc),
49699679Siwasaki                AcpiUtGetObjectTypeName (NewDesc)));
49791116Smsmith        }
49867754Smsmith        break;
49967754Smsmith
500281075Sdim    case ACPI_TYPE_BUFFER_FIELD:
501281075Sdim    case ACPI_TYPE_LOCAL_REGION_FIELD:
502281075Sdim    case ACPI_TYPE_LOCAL_BANK_FIELD:
503281075Sdim    case ACPI_TYPE_LOCAL_INDEX_FIELD:
504281075Sdim        /*
505281075Sdim         * For all fields, always write the source data to the target
506281075Sdim         * field. Any required implicit source operand conversion is
507281075Sdim         * performed in the function below as necessary. Note, field
508281075Sdim         * objects must retain their original type permanently.
509281075Sdim         */
510281075Sdim        Status = AcpiExWriteDataToField (SourceDesc, TargetDesc,
511281075Sdim            &WalkState->ResultObj);
512281075Sdim        break;
513281075Sdim
51467754Smsmith    default:
515245582Sjkim        /*
516245582Sjkim         * No conversions for all other types. Directly store a copy of
517281075Sdim         * the source object. This is the ACPI spec-defined behavior for
518281075Sdim         * the CopyObject operator.
519245582Sjkim         *
520281075Sdim         * NOTE: For the Store operator, this is a departure from the
521281075Sdim         * ACPI spec, which states "If conversion is impossible, abort
522281075Sdim         * the running control method". Instead, this code implements
523281075Sdim         * "If conversion is impossible, treat the Store operation as
524281075Sdim         * a CopyObject".
525245582Sjkim         */
526281075Sdim        Status = AcpiExStoreDirectToNode (SourceDesc, Node,
527281075Sdim            WalkState);
52871867Smsmith        break;
52971867Smsmith    }
53067754Smsmith
53171867Smsmith    return_ACPI_STATUS (Status);
53271867Smsmith}
533281075Sdim
534281075Sdim
535281075Sdim/*******************************************************************************
536281075Sdim *
537281075Sdim * FUNCTION:    AcpiExStoreDirectToNode
538281075Sdim *
539281075Sdim * PARAMETERS:  SourceDesc              - Value to be stored
540281075Sdim *              Node                    - Named object to receive the value
541281075Sdim *              WalkState               - Current walk state
542281075Sdim *
543281075Sdim * RETURN:      Status
544281075Sdim *
545281075Sdim * DESCRIPTION: "Store" an object directly to a node. This involves a copy
546281075Sdim *              and an attach.
547281075Sdim *
548281075Sdim ******************************************************************************/
549281075Sdim
550281075Sdimstatic ACPI_STATUS
551281075SdimAcpiExStoreDirectToNode (
552281075Sdim    ACPI_OPERAND_OBJECT     *SourceDesc,
553281075Sdim    ACPI_NAMESPACE_NODE     *Node,
554281075Sdim    ACPI_WALK_STATE         *WalkState)
555281075Sdim{
556281075Sdim    ACPI_STATUS             Status;
557281075Sdim    ACPI_OPERAND_OBJECT     *NewDesc;
558281075Sdim
559281075Sdim
560281075Sdim    ACPI_FUNCTION_TRACE (ExStoreDirectToNode);
561281075Sdim
562281075Sdim
563281075Sdim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
564281075Sdim        "Storing [%s] (%p) directly into node [%s] (%p)"
565281075Sdim        " with no implicit conversion\n",
566281075Sdim        AcpiUtGetObjectTypeName (SourceDesc), SourceDesc,
567281075Sdim        AcpiUtGetTypeName (Node->Type), Node));
568281075Sdim
569281075Sdim    /* Copy the source object to a new object */
570281075Sdim
571281075Sdim    Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState);
572281075Sdim    if (ACPI_FAILURE (Status))
573281075Sdim    {
574281075Sdim        return_ACPI_STATUS (Status);
575281075Sdim    }
576281075Sdim
577281075Sdim    /* Attach the new object to the node */
578281075Sdim
579281075Sdim    Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type);
580281075Sdim    AcpiUtRemoveReference (NewDesc);
581281075Sdim    return_ACPI_STATUS (Status);
582281075Sdim}
583