167754Smsmith/******************************************************************************
267754Smsmith *
377424Smsmith * Module Name: exstore - AML Interpreter object store support
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, 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,
120306536Sjkim            (ACPI_NAMESPACE_NODE *) DestDesc, WalkState,
121306536Sjkim            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,
150306536Sjkim            "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,
171306536Sjkim            RefDesc->Reference.Object,
172306536Sjkim            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,
188306536Sjkim            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,
197306536Sjkim            "**** 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
277306536Sjkim            Status = AcpiUtCopyIobjectToIobject (
278306536Sjkim                SourceDesc, &NewDesc, WalkState);
279193267Sjkim            if (ACPI_FAILURE (Status))
280193267Sjkim            {
281193267Sjkim                return_ACPI_STATUS (Status);
282193267Sjkim            }
283193267Sjkim        }
284193267Sjkim
285138287Smarks        if (ObjDesc)
28691116Smsmith        {
287138287Smarks            /* Decrement reference count by the ref count of the parent package */
288104470Siwasaki
289151937Sjkim            for (i = 0;
290151937Sjkim                 i < ((ACPI_OPERAND_OBJECT *)
291151937Sjkim                        IndexDesc->Reference.Object)->Common.ReferenceCount;
292151937Sjkim                 i++)
293104470Siwasaki            {
294138287Smarks                AcpiUtRemoveReference (ObjDesc);
295104470Siwasaki            }
296138287Smarks        }
297151937Sjkim
298138287Smarks        *(IndexDesc->Reference.Where) = NewDesc;
299126372Snjl
300151937Sjkim        /* Increment ref count by the ref count of the parent package-1 */
301126372Snjl
302151937Sjkim        for (i = 1;
303151937Sjkim             i < ((ACPI_OPERAND_OBJECT *)
304151937Sjkim                    IndexDesc->Reference.Object)->Common.ReferenceCount;
305151937Sjkim             i++)
306138287Smarks        {
307138287Smarks            AcpiUtAddReference (NewDesc);
30867754Smsmith        }
309151937Sjkim
31071867Smsmith        break;
31167754Smsmith
31271867Smsmith    case ACPI_TYPE_BUFFER_FIELD:
31367754Smsmith        /*
314138287Smarks         * Store into a Buffer or String (not actually a real BufferField)
315138287Smarks         * at a location defined by an Index.
31667754Smsmith         *
31787031Smsmith         * The first 8-bit element of the source object is written to the
31887031Smsmith         * 8-bit Buffer location defined by the Index destination object,
31987031Smsmith         * according to the ACPI 2.0 specification.
32067754Smsmith         */
32167754Smsmith
32267754Smsmith        /*
323138287Smarks         * Make sure the target is a Buffer or String. An error should
324138287Smarks         * not happen here, since the ReferenceObject was constructed
325138287Smarks         * by the INDEX_OP code.
32667754Smsmith         */
32791116Smsmith        ObjDesc = IndexDesc->Reference.Object;
328193267Sjkim        if ((ObjDesc->Common.Type != ACPI_TYPE_BUFFER) &&
329193267Sjkim            (ObjDesc->Common.Type != ACPI_TYPE_STRING))
33067754Smsmith        {
33171867Smsmith            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
33267754Smsmith        }
33367754Smsmith
33467754Smsmith        /*
33567754Smsmith         * The assignment of the individual elements will be slightly
33667754Smsmith         * different for each source type.
33767754Smsmith         */
338193267Sjkim        switch (SourceDesc->Common.Type)
33967754Smsmith        {
34071867Smsmith        case ACPI_TYPE_INTEGER:
34187031Smsmith
34287031Smsmith            /* Use the least-significant byte of the integer */
34387031Smsmith
34487031Smsmith            Value = (UINT8) (SourceDesc->Integer.Value);
34567754Smsmith            break;
34667754Smsmith
34787031Smsmith        case ACPI_TYPE_BUFFER:
348138287Smarks        case ACPI_TYPE_STRING:
34977424Smsmith
350138287Smarks            /* Note: Takes advantage of common string/buffer fields */
351138287Smarks
35287031Smsmith            Value = SourceDesc->Buffer.Pointer[0];
35367754Smsmith            break;
35467754Smsmith
35567754Smsmith        default:
35677424Smsmith
35787031Smsmith            /* All other types are invalid */
35877424Smsmith
359167802Sjkim            ACPI_ERROR ((AE_INFO,
360306536Sjkim                "Source must be type [Integer/Buffer/String], found [%s]",
36199679Siwasaki                AcpiUtGetObjectTypeName (SourceDesc)));
36287031Smsmith            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
36367754Smsmith        }
36487031Smsmith
36587031Smsmith        /* Store the source value into the target buffer byte */
36687031Smsmith
367193267Sjkim        ObjDesc->Buffer.Pointer[IndexDesc->Reference.Value] = Value;
36871867Smsmith        break;
36967754Smsmith
37071867Smsmith    default:
371167802Sjkim        ACPI_ERROR ((AE_INFO,
372306536Sjkim            "Target is not of type [Package/BufferField]"));
373306536Sjkim        Status = AE_AML_TARGET_TYPE;
37467754Smsmith        break;
37571867Smsmith    }
37667754Smsmith
37771867Smsmith    return_ACPI_STATUS (Status);
37871867Smsmith}
37967754Smsmith
38067754Smsmith
38171867Smsmith/*******************************************************************************
38271867Smsmith *
38377424Smsmith * FUNCTION:    AcpiExStoreObjectToNode
38471867Smsmith *
38587031Smsmith * PARAMETERS:  SourceDesc              - Value to be stored
38687031Smsmith *              Node                    - Named object to receive the value
38787031Smsmith *              WalkState               - Current walk state
388128212Snjl *              ImplicitConversion      - Perform implicit conversion (yes/no)
38971867Smsmith *
39071867Smsmith * RETURN:      Status
39171867Smsmith *
39271867Smsmith * DESCRIPTION: Store the object to the named object.
39371867Smsmith *
394306536Sjkim * The assignment of an object to a named object is handled here.
395306536Sjkim * The value passed in will replace the current value (if any)
396306536Sjkim * with the input value.
39771867Smsmith *
398306536Sjkim * When storing into an object the data is converted to the
399306536Sjkim * target object type then stored in the object. This means
400306536Sjkim * that the target object type (for an initialized target) will
401306536Sjkim * not be changed by a store operation. A CopyObject can change
402306536Sjkim * the target type, however.
40371867Smsmith *
404306536Sjkim * The ImplicitConversion flag is set to NO/FALSE only when
405306536Sjkim * storing to an ArgX -- as per the rules of the ACPI spec.
406281075Sdim *
407306536Sjkim * Assumes parameters are already validated.
40871867Smsmith *
40971867Smsmith ******************************************************************************/
41067754Smsmith
41171867SmsmithACPI_STATUS
41277424SmsmithAcpiExStoreObjectToNode (
41371867Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc,
41471867Smsmith    ACPI_NAMESPACE_NODE     *Node,
415128212Snjl    ACPI_WALK_STATE         *WalkState,
416128212Snjl    UINT8                   ImplicitConversion)
41771867Smsmith{
41871867Smsmith    ACPI_STATUS             Status = AE_OK;
41971867Smsmith    ACPI_OPERAND_OBJECT     *TargetDesc;
42091116Smsmith    ACPI_OPERAND_OBJECT     *NewDesc;
42191116Smsmith    ACPI_OBJECT_TYPE        TargetType;
42267754Smsmith
42371867Smsmith
424167802Sjkim    ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToNode, SourceDesc);
42571867Smsmith
42683174Smsmith
427151937Sjkim    /* Get current type of the node, and object attached to Node */
428151937Sjkim
42971867Smsmith    TargetType = AcpiNsGetType (Node);
43071867Smsmith    TargetDesc = AcpiNsGetAttachedObject (Node);
43171867Smsmith
432306536Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
43399679Siwasaki        SourceDesc, AcpiUtGetObjectTypeName (SourceDesc),
434306536Sjkim        Node, AcpiUtGetTypeName (TargetType)));
43571867Smsmith
436306536Sjkim    /* Only limited target types possible for everything except CopyObject */
437306536Sjkim
438306536Sjkim    if (WalkState->Opcode != AML_COPY_OP)
439306536Sjkim    {
440306536Sjkim        /*
441306536Sjkim         * Only CopyObject allows all object types to be overwritten. For
442306536Sjkim         * TargetRef(s), there are restrictions on the object types that
443306536Sjkim         * are allowed.
444306536Sjkim         *
445306536Sjkim         * Allowable operations/typing for Store:
446306536Sjkim         *
447306536Sjkim         * 1) Simple Store
448306536Sjkim         *      Integer     --> Integer (Named/Local/Arg)
449306536Sjkim         *      String      --> String  (Named/Local/Arg)
450306536Sjkim         *      Buffer      --> Buffer  (Named/Local/Arg)
451306536Sjkim         *      Package     --> Package (Named/Local/Arg)
452306536Sjkim         *
453306536Sjkim         * 2) Store with implicit conversion
454306536Sjkim         *      Integer     --> String or Buffer  (Named)
455306536Sjkim         *      String      --> Integer or Buffer (Named)
456306536Sjkim         *      Buffer      --> Integer or String (Named)
457306536Sjkim         */
458306536Sjkim        switch (TargetType)
459306536Sjkim        {
460306536Sjkim        case ACPI_TYPE_PACKAGE:
461306536Sjkim            /*
462306536Sjkim             * Here, can only store a package to an existing package.
463306536Sjkim             * Storing a package to a Local/Arg is OK, and handled
464306536Sjkim             * elsewhere.
465306536Sjkim             */
466306536Sjkim            if (WalkState->Opcode == AML_STORE_OP)
467306536Sjkim            {
468306536Sjkim                if (SourceDesc->Common.Type != ACPI_TYPE_PACKAGE)
469306536Sjkim                {
470306536Sjkim                    ACPI_ERROR ((AE_INFO,
471306536Sjkim                        "Cannot assign type [%s] to [Package] "
472306536Sjkim                        "(source must be type Pkg)",
473306536Sjkim                        AcpiUtGetObjectTypeName (SourceDesc)));
474306536Sjkim
475306536Sjkim                    return_ACPI_STATUS (AE_AML_TARGET_TYPE);
476306536Sjkim                }
477306536Sjkim                break;
478306536Sjkim            }
479306536Sjkim
480306536Sjkim        /* Fallthrough */
481306536Sjkim
482306536Sjkim        case ACPI_TYPE_DEVICE:
483306536Sjkim        case ACPI_TYPE_EVENT:
484306536Sjkim        case ACPI_TYPE_MUTEX:
485306536Sjkim        case ACPI_TYPE_REGION:
486306536Sjkim        case ACPI_TYPE_POWER:
487306536Sjkim        case ACPI_TYPE_PROCESSOR:
488306536Sjkim        case ACPI_TYPE_THERMAL:
489306536Sjkim
490306536Sjkim            ACPI_ERROR ((AE_INFO,
491306536Sjkim                "Target must be [Buffer/Integer/String/Reference]"
492306536Sjkim                ", found [%s] (%4.4s)",
493306536Sjkim                AcpiUtGetTypeName (Node->Type), Node->Name.Ascii));
494306536Sjkim
495306536Sjkim            return_ACPI_STATUS (AE_AML_TARGET_TYPE);
496306536Sjkim
497306536Sjkim        default:
498306536Sjkim            break;
499306536Sjkim        }
500306536Sjkim    }
501306536Sjkim
50271867Smsmith    /*
50371867Smsmith     * Resolve the source object to an actual value
50477424Smsmith     * (If it is a reference object)
50571867Smsmith     */
50677424Smsmith    Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState);
50771867Smsmith    if (ACPI_FAILURE (Status))
50871867Smsmith    {
50971867Smsmith        return_ACPI_STATUS (Status);
51071867Smsmith    }
51171867Smsmith
512151937Sjkim    /* Do the actual store operation */
513151937Sjkim
51471867Smsmith    switch (TargetType)
51571867Smsmith    {
51677424Smsmith        /*
517281075Sdim         * The simple data types all support implicit source operand
518281075Sdim         * conversion before the store.
51967754Smsmith         */
520306536Sjkim    case ACPI_TYPE_INTEGER:
521306536Sjkim    case ACPI_TYPE_STRING:
522306536Sjkim    case ACPI_TYPE_BUFFER:
523281075Sdim
524281075Sdim        if ((WalkState->Opcode == AML_COPY_OP) ||
525281075Sdim            !ImplicitConversion)
526281075Sdim        {
527281075Sdim            /*
528281075Sdim             * However, CopyObject and Stores to ArgX do not perform
529281075Sdim             * an implicit conversion, as per the ACPI specification.
530281075Sdim             * A direct store is performed instead.
531281075Sdim             */
532306536Sjkim            Status = AcpiExStoreDirectToNode (SourceDesc, Node, WalkState);
533281075Sdim            break;
534281075Sdim        }
535281075Sdim
536281075Sdim        /* Store with implicit source operand conversion support */
537281075Sdim
538151937Sjkim        Status = AcpiExStoreObjectToObject (SourceDesc, TargetDesc,
539281075Sdim            &NewDesc, WalkState);
54071867Smsmith        if (ACPI_FAILURE (Status))
54167754Smsmith        {
54271867Smsmith            return_ACPI_STATUS (Status);
54367754Smsmith        }
54467754Smsmith
54591116Smsmith        if (NewDesc != TargetDesc)
54691116Smsmith        {
54791116Smsmith            /*
54891116Smsmith             * Store the new NewDesc as the new value of the Name, and set
54991116Smsmith             * the Name's type to that of the value being stored in it.
55091116Smsmith             * SourceDesc reference count is incremented by AttachObject.
551104470Siwasaki             *
552281075Sdim             * Note: This may change the type of the node if an explicit
553281075Sdim             * store has been performed such that the node/object type
554281075Sdim             * has been changed.
55591116Smsmith             */
556306536Sjkim            Status = AcpiNsAttachObject (
557306536Sjkim                Node, NewDesc, NewDesc->Common.Type);
55885756Smsmith
55999146Siwasaki            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
560306536Sjkim                "Store type [%s] into [%s] via Convert/Attach\n",
56199679Siwasaki                AcpiUtGetObjectTypeName (SourceDesc),
56299679Siwasaki                AcpiUtGetObjectTypeName (NewDesc)));
56391116Smsmith        }
56467754Smsmith        break;
56567754Smsmith
566281075Sdim    case ACPI_TYPE_BUFFER_FIELD:
567281075Sdim    case ACPI_TYPE_LOCAL_REGION_FIELD:
568281075Sdim    case ACPI_TYPE_LOCAL_BANK_FIELD:
569281075Sdim    case ACPI_TYPE_LOCAL_INDEX_FIELD:
570281075Sdim        /*
571281075Sdim         * For all fields, always write the source data to the target
572281075Sdim         * field. Any required implicit source operand conversion is
573281075Sdim         * performed in the function below as necessary. Note, field
574281075Sdim         * objects must retain their original type permanently.
575281075Sdim         */
576281075Sdim        Status = AcpiExWriteDataToField (SourceDesc, TargetDesc,
577281075Sdim            &WalkState->ResultObj);
578281075Sdim        break;
579281075Sdim
58067754Smsmith    default:
581245582Sjkim        /*
582306536Sjkim         * CopyObject operator: No conversions for all other types.
583306536Sjkim         * Instead, directly store a copy of the source object.
584245582Sjkim         *
585306536Sjkim         * This is the ACPI spec-defined behavior for the CopyObject
586306536Sjkim         * operator. (Note, for this default case, all normal
587306536Sjkim         * Store/Target operations exited above with an error).
588245582Sjkim         */
589306536Sjkim        Status = AcpiExStoreDirectToNode (SourceDesc, Node, WalkState);
59071867Smsmith        break;
59171867Smsmith    }
59267754Smsmith
59371867Smsmith    return_ACPI_STATUS (Status);
59471867Smsmith}
595281075Sdim
596281075Sdim
597281075Sdim/*******************************************************************************
598281075Sdim *
599281075Sdim * FUNCTION:    AcpiExStoreDirectToNode
600281075Sdim *
601281075Sdim * PARAMETERS:  SourceDesc              - Value to be stored
602281075Sdim *              Node                    - Named object to receive the value
603281075Sdim *              WalkState               - Current walk state
604281075Sdim *
605281075Sdim * RETURN:      Status
606281075Sdim *
607281075Sdim * DESCRIPTION: "Store" an object directly to a node. This involves a copy
608281075Sdim *              and an attach.
609281075Sdim *
610281075Sdim ******************************************************************************/
611281075Sdim
612281075Sdimstatic ACPI_STATUS
613281075SdimAcpiExStoreDirectToNode (
614281075Sdim    ACPI_OPERAND_OBJECT     *SourceDesc,
615281075Sdim    ACPI_NAMESPACE_NODE     *Node,
616281075Sdim    ACPI_WALK_STATE         *WalkState)
617281075Sdim{
618281075Sdim    ACPI_STATUS             Status;
619281075Sdim    ACPI_OPERAND_OBJECT     *NewDesc;
620281075Sdim
621281075Sdim
622281075Sdim    ACPI_FUNCTION_TRACE (ExStoreDirectToNode);
623281075Sdim
624281075Sdim
625281075Sdim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
626281075Sdim        "Storing [%s] (%p) directly into node [%s] (%p)"
627281075Sdim        " with no implicit conversion\n",
628281075Sdim        AcpiUtGetObjectTypeName (SourceDesc), SourceDesc,
629281075Sdim        AcpiUtGetTypeName (Node->Type), Node));
630281075Sdim
631281075Sdim    /* Copy the source object to a new object */
632281075Sdim
633281075Sdim    Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState);
634281075Sdim    if (ACPI_FAILURE (Status))
635281075Sdim    {
636281075Sdim        return_ACPI_STATUS (Status);
637281075Sdim    }
638281075Sdim
639281075Sdim    /* Attach the new object to the node */
640281075Sdim
641281075Sdim    Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type);
642281075Sdim    AcpiUtRemoveReference (NewDesc);
643281075Sdim    return_ACPI_STATUS (Status);
644281075Sdim}
645