167754Smsmith/******************************************************************************
267754Smsmith *
377424Smsmith * Module Name: exstoren - AML Interpreter object store support,
471867Smsmith *                        Store to Node (namespace object)
567754Smsmith *
667754Smsmith *****************************************************************************/
767754Smsmith
8217365Sjkim/*
9245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp.
1070243Smsmith * All rights reserved.
1167754Smsmith *
12217365Sjkim * Redistribution and use in source and binary forms, with or without
13217365Sjkim * modification, are permitted provided that the following conditions
14217365Sjkim * are met:
15217365Sjkim * 1. Redistributions of source code must retain the above copyright
16217365Sjkim *    notice, this list of conditions, and the following disclaimer,
17217365Sjkim *    without modification.
18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
20217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
21217365Sjkim *    including a substantially similar Disclaimer requirement for further
22217365Sjkim *    binary redistribution.
23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
24217365Sjkim *    of any contributors may be used to endorse or promote products derived
25217365Sjkim *    from this software without specific prior written permission.
2667754Smsmith *
27217365Sjkim * Alternatively, this software may be distributed under the terms of the
28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
29217365Sjkim * Software Foundation.
3067754Smsmith *
31217365Sjkim * NO WARRANTY
32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
43217365Sjkim */
4467754Smsmith
4577424Smsmith#define __EXSTOREN_C__
4667754Smsmith
47193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
48193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
49193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
50193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
5167754Smsmith
5267754Smsmith
5377424Smsmith#define _COMPONENT          ACPI_EXECUTER
5491116Smsmith        ACPI_MODULE_NAME    ("exstoren")
5567754Smsmith
5667754Smsmith
5767754Smsmith/*******************************************************************************
5867754Smsmith *
5977424Smsmith * FUNCTION:    AcpiExResolveObject
6067754Smsmith *
6171867Smsmith * PARAMETERS:  SourceDescPtr       - Pointer to the source object
6271867Smsmith *              TargetType          - Current type of the target
6371867Smsmith *              WalkState           - Current walk state
6467754Smsmith *
6571867Smsmith * RETURN:      Status, resolved object in SourceDescPtr.
6667754Smsmith *
67241973Sjkim * DESCRIPTION: Resolve an object. If the object is a reference, dereference
6871867Smsmith *              it and return the actual object in the SourceDescPtr.
6967754Smsmith *
7067754Smsmith ******************************************************************************/
7167754Smsmith
7267754SmsmithACPI_STATUS
7377424SmsmithAcpiExResolveObject (
7471867Smsmith    ACPI_OPERAND_OBJECT     **SourceDescPtr,
7591116Smsmith    ACPI_OBJECT_TYPE        TargetType,
7667754Smsmith    ACPI_WALK_STATE         *WalkState)
7767754Smsmith{
7871867Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc = *SourceDescPtr;
7967754Smsmith    ACPI_STATUS             Status = AE_OK;
8067754Smsmith
8167754Smsmith
82167802Sjkim    ACPI_FUNCTION_TRACE (ExResolveObject);
8367754Smsmith
8467754Smsmith
85151937Sjkim    /* Ensure we have a Target that can be stored to */
86151937Sjkim
8771867Smsmith    switch (TargetType)
8871867Smsmith    {
8977424Smsmith    case ACPI_TYPE_BUFFER_FIELD:
90107325Siwasaki    case ACPI_TYPE_LOCAL_REGION_FIELD:
91107325Siwasaki    case ACPI_TYPE_LOCAL_BANK_FIELD:
92107325Siwasaki    case ACPI_TYPE_LOCAL_INDEX_FIELD:
9387031Smsmith        /*
9487031Smsmith         * These cases all require only Integers or values that
9587031Smsmith         * can be converted to Integers (Strings or Buffers)
9687031Smsmith         */
9777424Smsmith    case ACPI_TYPE_INTEGER:
9867754Smsmith    case ACPI_TYPE_STRING:
9967754Smsmith    case ACPI_TYPE_BUFFER:
10091116Smsmith        /*
10187031Smsmith         * Stores into a Field/Region or into a Integer/Buffer/String
102241973Sjkim         * are all essentially the same. This case handles the
10391116Smsmith         * "interchangeable" types Integer, String, and Buffer.
10487031Smsmith         */
105193267Sjkim        if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
10691116Smsmith        {
10791116Smsmith            /* Resolve a reference object first */
10877424Smsmith
10991116Smsmith            Status = AcpiExResolveToValue (SourceDescPtr, WalkState);
11091116Smsmith            if (ACPI_FAILURE (Status))
11191116Smsmith            {
11291116Smsmith                break;
11391116Smsmith            }
11491116Smsmith        }
11577424Smsmith
116126372Snjl        /* For CopyObject, no further validation necessary */
117126372Snjl
118126372Snjl        if (WalkState->Opcode == AML_COPY_OP)
119126372Snjl        {
120126372Snjl            break;
121126372Snjl        }
122126372Snjl
123151937Sjkim        /* Must have a Integer, Buffer, or String */
124151937Sjkim
125193267Sjkim        if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER)    &&
126193267Sjkim            (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)     &&
127193267Sjkim            (SourceDesc->Common.Type != ACPI_TYPE_STRING)     &&
128193267Sjkim            !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
129193267Sjkim                    (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE)))
13067754Smsmith        {
131151937Sjkim            /* Conversion successful but still not a valid type */
132151937Sjkim
133167802Sjkim            ACPI_ERROR ((AE_INFO,
134167802Sjkim                "Cannot assign type %s to %s (must be type Int/Str/Buf)",
13599679Siwasaki                AcpiUtGetObjectTypeName (SourceDesc),
13691116Smsmith                AcpiUtGetTypeName (TargetType)));
13791116Smsmith            Status = AE_AML_OPERAND_TYPE;
13867754Smsmith        }
13967754Smsmith        break;
14067754Smsmith
141107325Siwasaki    case ACPI_TYPE_LOCAL_ALIAS:
142128212Snjl    case ACPI_TYPE_LOCAL_METHOD_ALIAS:
143167802Sjkim        /*
144167802Sjkim         * All aliases should have been resolved earlier, during the
145167802Sjkim         * operand resolution phase.
146167802Sjkim         */
147167802Sjkim        ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object"));
14871867Smsmith        Status = AE_AML_INTERNAL;
14967754Smsmith        break;
15067754Smsmith
15171867Smsmith    case ACPI_TYPE_PACKAGE:
15267754Smsmith    default:
15367754Smsmith        /*
15471867Smsmith         * All other types than Alias and the various Fields come here,
15571867Smsmith         * including the untyped case - ACPI_TYPE_ANY.
15667754Smsmith         */
15771867Smsmith        break;
15871867Smsmith    }
15967754Smsmith
16071867Smsmith    return_ACPI_STATUS (Status);
16171867Smsmith}
16267754Smsmith
16367754Smsmith
16471867Smsmith/*******************************************************************************
16571867Smsmith *
16691116Smsmith * FUNCTION:    AcpiExStoreObjectToObject
16771867Smsmith *
16871867Smsmith * PARAMETERS:  SourceDesc          - Object to store
16999146Siwasaki *              DestDesc            - Object to receive a copy of the source
17091116Smsmith *              NewDesc             - New object if DestDesc is obsoleted
17171867Smsmith *              WalkState           - Current walk state
17271867Smsmith *
17371867Smsmith * RETURN:      Status
17471867Smsmith *
175241973Sjkim * DESCRIPTION: "Store" an object to another object. This may include
17671867Smsmith *              converting the source type to the target type (implicit
17771867Smsmith *              conversion), and a copy of the value of the source to
17871867Smsmith *              the target.
17971867Smsmith *
18091116Smsmith *              The Assignment of an object to another (not named) object
18191116Smsmith *              is handled here.
18291116Smsmith *              The Source passed in will replace the current value (if any)
18391116Smsmith *              with the input value.
18491116Smsmith *
18591116Smsmith *              When storing into an object the data is converted to the
186241973Sjkim *              target object type then stored in the object. This means
18791116Smsmith *              that the target object type (for an initialized target) will
18891116Smsmith *              not be changed by a store operation.
18991116Smsmith *
19091116Smsmith *              This module allows destination types of Number, String,
19191116Smsmith *              Buffer, and Package.
19291116Smsmith *
193241973Sjkim *              Assumes parameters are already validated. NOTE: SourceDesc
19491116Smsmith *              resolution (from a reference object) must be performed by
19591116Smsmith *              the caller if necessary.
19691116Smsmith *
19771867Smsmith ******************************************************************************/
19867754Smsmith
19971867SmsmithACPI_STATUS
20091116SmsmithAcpiExStoreObjectToObject (
20171867Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc,
20291116Smsmith    ACPI_OPERAND_OBJECT     *DestDesc,
20391116Smsmith    ACPI_OPERAND_OBJECT     **NewDesc,
20471867Smsmith    ACPI_WALK_STATE         *WalkState)
20571867Smsmith{
20691116Smsmith    ACPI_OPERAND_OBJECT     *ActualSrcDesc;
20777424Smsmith    ACPI_STATUS             Status = AE_OK;
20867754Smsmith
20971867Smsmith
210167802Sjkim    ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc);
21171867Smsmith
21271867Smsmith
21391116Smsmith    ActualSrcDesc = SourceDesc;
21491116Smsmith    if (!DestDesc)
21567754Smsmith    {
21691116Smsmith        /*
21791116Smsmith         * There is no destination object (An uninitialized node or
21891116Smsmith         * package element), so we can simply copy the source object
21991116Smsmith         * creating a new destination object
22091116Smsmith         */
22191116Smsmith        Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState);
22271867Smsmith        return_ACPI_STATUS (Status);
22367754Smsmith    }
22467754Smsmith
225193267Sjkim    if (SourceDesc->Common.Type != DestDesc->Common.Type)
22691116Smsmith    {
22791116Smsmith        /*
22891116Smsmith         * The source type does not match the type of the destination.
22991116Smsmith         * Perform the "implicit conversion" of the source to the current type
23091116Smsmith         * of the target as per the ACPI specification.
23191116Smsmith         *
23291116Smsmith         * If no conversion performed, ActualSrcDesc = SourceDesc.
23391116Smsmith         * Otherwise, ActualSrcDesc is a temporary object to hold the
23491116Smsmith         * converted object.
23591116Smsmith         */
236193267Sjkim        Status = AcpiExConvertToTargetType (DestDesc->Common.Type,
237151937Sjkim                        SourceDesc, &ActualSrcDesc, WalkState);
23891116Smsmith        if (ACPI_FAILURE (Status))
23991116Smsmith        {
24091116Smsmith            return_ACPI_STATUS (Status);
24191116Smsmith        }
242104470Siwasaki
243104470Siwasaki        if (SourceDesc == ActualSrcDesc)
244104470Siwasaki        {
245114237Snjl            /*
246151937Sjkim             * No conversion was performed. Return the SourceDesc as the
247104470Siwasaki             * new object.
248104470Siwasaki             */
249104470Siwasaki            *NewDesc = SourceDesc;
250104470Siwasaki            return_ACPI_STATUS (AE_OK);
251104470Siwasaki        }
25291116Smsmith    }
25391116Smsmith
25467754Smsmith    /*
25571867Smsmith     * We now have two objects of identical types, and we can perform a
25671867Smsmith     * copy of the *value* of the source object.
25767754Smsmith     */
258193267Sjkim    switch (DestDesc->Common.Type)
25967754Smsmith    {
26071867Smsmith    case ACPI_TYPE_INTEGER:
26167754Smsmith
26291116Smsmith        DestDesc->Integer.Value = ActualSrcDesc->Integer.Value;
26367754Smsmith
26471867Smsmith        /* Truncate value if we are executing from a 32-bit ACPI table */
26567754Smsmith
266245582Sjkim        (void) AcpiExTruncateFor32bitTable (DestDesc);
26771867Smsmith        break;
26867754Smsmith
26971867Smsmith    case ACPI_TYPE_STRING:
27067754Smsmith
27191116Smsmith        Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc);
27267754Smsmith        break;
27367754Smsmith
27471867Smsmith    case ACPI_TYPE_BUFFER:
27567754Smsmith
27691116Smsmith        Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc);
27767754Smsmith        break;
27867754Smsmith
27967754Smsmith    case ACPI_TYPE_PACKAGE:
28067754Smsmith
281151937Sjkim        Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc,
282151937Sjkim                    WalkState);
28367754Smsmith        break;
28467754Smsmith
28567754Smsmith    default:
28667754Smsmith        /*
28771867Smsmith         * All other types come here.
28867754Smsmith         */
289167802Sjkim        ACPI_WARNING ((AE_INFO, "Store into type %s not implemented",
29099679Siwasaki            AcpiUtGetObjectTypeName (DestDesc)));
29167754Smsmith
29267754Smsmith        Status = AE_NOT_IMPLEMENTED;
29367754Smsmith        break;
29467754Smsmith    }
29567754Smsmith
29691116Smsmith    if (ActualSrcDesc != SourceDesc)
29791116Smsmith    {
29891116Smsmith        /* Delete the intermediate (temporary) source object */
29967754Smsmith
30091116Smsmith        AcpiUtRemoveReference (ActualSrcDesc);
30191116Smsmith    }
30291116Smsmith
30391116Smsmith    *NewDesc = DestDesc;
30467754Smsmith    return_ACPI_STATUS (Status);
30567754Smsmith}
306