167754Smsmith/******************************************************************************
267754Smsmith *
377424Smsmith * Module Name: exstoren - AML Interpreter object store support,
471867Smsmith *                        Store to Node (namespace object)
567754Smsmith *
667754Smsmith *****************************************************************************/
767754Smsmith
8217365Sjkim/*
9306536Sjkim * Copyright (C) 2000 - 2016, 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
45193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
46193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
47193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
4967754Smsmith
5067754Smsmith
5177424Smsmith#define _COMPONENT          ACPI_EXECUTER
5291116Smsmith        ACPI_MODULE_NAME    ("exstoren")
5367754Smsmith
5467754Smsmith
5567754Smsmith/*******************************************************************************
5667754Smsmith *
5777424Smsmith * FUNCTION:    AcpiExResolveObject
5867754Smsmith *
5971867Smsmith * PARAMETERS:  SourceDescPtr       - Pointer to the source object
6071867Smsmith *              TargetType          - Current type of the target
6171867Smsmith *              WalkState           - Current walk state
6267754Smsmith *
6371867Smsmith * RETURN:      Status, resolved object in SourceDescPtr.
6467754Smsmith *
65241973Sjkim * DESCRIPTION: Resolve an object. If the object is a reference, dereference
6671867Smsmith *              it and return the actual object in the SourceDescPtr.
6767754Smsmith *
6867754Smsmith ******************************************************************************/
6967754Smsmith
7067754SmsmithACPI_STATUS
7177424SmsmithAcpiExResolveObject (
7271867Smsmith    ACPI_OPERAND_OBJECT     **SourceDescPtr,
7391116Smsmith    ACPI_OBJECT_TYPE        TargetType,
7467754Smsmith    ACPI_WALK_STATE         *WalkState)
7567754Smsmith{
7671867Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc = *SourceDescPtr;
7767754Smsmith    ACPI_STATUS             Status = AE_OK;
7867754Smsmith
7967754Smsmith
80167802Sjkim    ACPI_FUNCTION_TRACE (ExResolveObject);
8167754Smsmith
8267754Smsmith
83151937Sjkim    /* Ensure we have a Target that can be stored to */
84151937Sjkim
8571867Smsmith    switch (TargetType)
8671867Smsmith    {
8777424Smsmith    case ACPI_TYPE_BUFFER_FIELD:
88107325Siwasaki    case ACPI_TYPE_LOCAL_REGION_FIELD:
89107325Siwasaki    case ACPI_TYPE_LOCAL_BANK_FIELD:
90107325Siwasaki    case ACPI_TYPE_LOCAL_INDEX_FIELD:
9187031Smsmith        /*
9287031Smsmith         * These cases all require only Integers or values that
9387031Smsmith         * can be converted to Integers (Strings or Buffers)
9487031Smsmith         */
9577424Smsmith    case ACPI_TYPE_INTEGER:
9667754Smsmith    case ACPI_TYPE_STRING:
9767754Smsmith    case ACPI_TYPE_BUFFER:
9891116Smsmith        /*
9987031Smsmith         * Stores into a Field/Region or into a Integer/Buffer/String
100241973Sjkim         * are all essentially the same. This case handles the
10191116Smsmith         * "interchangeable" types Integer, String, and Buffer.
10287031Smsmith         */
103193267Sjkim        if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
10491116Smsmith        {
10591116Smsmith            /* Resolve a reference object first */
10677424Smsmith
10791116Smsmith            Status = AcpiExResolveToValue (SourceDescPtr, WalkState);
10891116Smsmith            if (ACPI_FAILURE (Status))
10991116Smsmith            {
11091116Smsmith                break;
11191116Smsmith            }
11291116Smsmith        }
11377424Smsmith
114126372Snjl        /* For CopyObject, no further validation necessary */
115126372Snjl
116126372Snjl        if (WalkState->Opcode == AML_COPY_OP)
117126372Snjl        {
118126372Snjl            break;
119126372Snjl        }
120126372Snjl
121151937Sjkim        /* Must have a Integer, Buffer, or String */
122151937Sjkim
123193267Sjkim        if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER)    &&
124193267Sjkim            (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)     &&
125193267Sjkim            (SourceDesc->Common.Type != ACPI_TYPE_STRING)     &&
126193267Sjkim            !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
127306536Sjkim                (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE)))
12867754Smsmith        {
129151937Sjkim            /* Conversion successful but still not a valid type */
130151937Sjkim
131167802Sjkim            ACPI_ERROR ((AE_INFO,
132306536Sjkim                "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)",
13399679Siwasaki                AcpiUtGetObjectTypeName (SourceDesc),
13491116Smsmith                AcpiUtGetTypeName (TargetType)));
135306536Sjkim
13691116Smsmith            Status = AE_AML_OPERAND_TYPE;
13767754Smsmith        }
13867754Smsmith        break;
13967754Smsmith
140107325Siwasaki    case ACPI_TYPE_LOCAL_ALIAS:
141128212Snjl    case ACPI_TYPE_LOCAL_METHOD_ALIAS:
142167802Sjkim        /*
143167802Sjkim         * All aliases should have been resolved earlier, during the
144167802Sjkim         * operand resolution phase.
145167802Sjkim         */
146167802Sjkim        ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object"));
14771867Smsmith        Status = AE_AML_INTERNAL;
14867754Smsmith        break;
14967754Smsmith
15071867Smsmith    case ACPI_TYPE_PACKAGE:
15167754Smsmith    default:
15267754Smsmith        /*
15371867Smsmith         * All other types than Alias and the various Fields come here,
15471867Smsmith         * including the untyped case - ACPI_TYPE_ANY.
15567754Smsmith         */
15671867Smsmith        break;
15771867Smsmith    }
15867754Smsmith
15971867Smsmith    return_ACPI_STATUS (Status);
16071867Smsmith}
16167754Smsmith
16267754Smsmith
16371867Smsmith/*******************************************************************************
16471867Smsmith *
16591116Smsmith * FUNCTION:    AcpiExStoreObjectToObject
16671867Smsmith *
16771867Smsmith * PARAMETERS:  SourceDesc          - Object to store
16899146Siwasaki *              DestDesc            - Object to receive a copy of the source
16991116Smsmith *              NewDesc             - New object if DestDesc is obsoleted
17071867Smsmith *              WalkState           - Current walk state
17171867Smsmith *
17271867Smsmith * RETURN:      Status
17371867Smsmith *
174241973Sjkim * DESCRIPTION: "Store" an object to another object. This may include
17571867Smsmith *              converting the source type to the target type (implicit
17671867Smsmith *              conversion), and a copy of the value of the source to
17771867Smsmith *              the target.
17871867Smsmith *
17991116Smsmith *              The Assignment of an object to another (not named) object
18091116Smsmith *              is handled here.
18191116Smsmith *              The Source passed in will replace the current value (if any)
18291116Smsmith *              with the input value.
18391116Smsmith *
18491116Smsmith *              When storing into an object the data is converted to the
185241973Sjkim *              target object type then stored in the object. This means
18691116Smsmith *              that the target object type (for an initialized target) will
18791116Smsmith *              not be changed by a store operation.
18891116Smsmith *
18991116Smsmith *              This module allows destination types of Number, String,
19091116Smsmith *              Buffer, and Package.
19191116Smsmith *
192241973Sjkim *              Assumes parameters are already validated. NOTE: SourceDesc
19391116Smsmith *              resolution (from a reference object) must be performed by
19491116Smsmith *              the caller if necessary.
19591116Smsmith *
19671867Smsmith ******************************************************************************/
19767754Smsmith
19871867SmsmithACPI_STATUS
19991116SmsmithAcpiExStoreObjectToObject (
20071867Smsmith    ACPI_OPERAND_OBJECT     *SourceDesc,
20191116Smsmith    ACPI_OPERAND_OBJECT     *DestDesc,
20291116Smsmith    ACPI_OPERAND_OBJECT     **NewDesc,
20371867Smsmith    ACPI_WALK_STATE         *WalkState)
20471867Smsmith{
20591116Smsmith    ACPI_OPERAND_OBJECT     *ActualSrcDesc;
20677424Smsmith    ACPI_STATUS             Status = AE_OK;
20767754Smsmith
20871867Smsmith
209167802Sjkim    ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc);
21071867Smsmith
21171867Smsmith
21291116Smsmith    ActualSrcDesc = SourceDesc;
21391116Smsmith    if (!DestDesc)
21467754Smsmith    {
21591116Smsmith        /*
21691116Smsmith         * There is no destination object (An uninitialized node or
21791116Smsmith         * package element), so we can simply copy the source object
21891116Smsmith         * creating a new destination object
21991116Smsmith         */
22091116Smsmith        Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState);
22171867Smsmith        return_ACPI_STATUS (Status);
22267754Smsmith    }
22367754Smsmith
224193267Sjkim    if (SourceDesc->Common.Type != DestDesc->Common.Type)
22591116Smsmith    {
22691116Smsmith        /*
22791116Smsmith         * The source type does not match the type of the destination.
22891116Smsmith         * Perform the "implicit conversion" of the source to the current type
22991116Smsmith         * of the target as per the ACPI specification.
23091116Smsmith         *
23191116Smsmith         * If no conversion performed, ActualSrcDesc = SourceDesc.
23291116Smsmith         * Otherwise, ActualSrcDesc is a temporary object to hold the
23391116Smsmith         * converted object.
23491116Smsmith         */
235193267Sjkim        Status = AcpiExConvertToTargetType (DestDesc->Common.Type,
236306536Sjkim            SourceDesc, &ActualSrcDesc, WalkState);
23791116Smsmith        if (ACPI_FAILURE (Status))
23891116Smsmith        {
23991116Smsmith            return_ACPI_STATUS (Status);
24091116Smsmith        }
241104470Siwasaki
242104470Siwasaki        if (SourceDesc == ActualSrcDesc)
243104470Siwasaki        {
244114237Snjl            /*
245151937Sjkim             * No conversion was performed. Return the SourceDesc as the
246104470Siwasaki             * new object.
247104470Siwasaki             */
248104470Siwasaki            *NewDesc = SourceDesc;
249104470Siwasaki            return_ACPI_STATUS (AE_OK);
250104470Siwasaki        }
25191116Smsmith    }
25291116Smsmith
25367754Smsmith    /*
25471867Smsmith     * We now have two objects of identical types, and we can perform a
25571867Smsmith     * copy of the *value* of the source object.
25667754Smsmith     */
257193267Sjkim    switch (DestDesc->Common.Type)
25867754Smsmith    {
25971867Smsmith    case ACPI_TYPE_INTEGER:
26067754Smsmith
26191116Smsmith        DestDesc->Integer.Value = ActualSrcDesc->Integer.Value;
26267754Smsmith
26371867Smsmith        /* Truncate value if we are executing from a 32-bit ACPI table */
26467754Smsmith
265245582Sjkim        (void) AcpiExTruncateFor32bitTable (DestDesc);
26671867Smsmith        break;
26767754Smsmith
26871867Smsmith    case ACPI_TYPE_STRING:
26967754Smsmith
27091116Smsmith        Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc);
27167754Smsmith        break;
27267754Smsmith
27371867Smsmith    case ACPI_TYPE_BUFFER:
27467754Smsmith
27591116Smsmith        Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc);
27667754Smsmith        break;
27767754Smsmith
27867754Smsmith    case ACPI_TYPE_PACKAGE:
27967754Smsmith
280151937Sjkim        Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc,
281151937Sjkim                    WalkState);
28267754Smsmith        break;
28367754Smsmith
28467754Smsmith    default:
28567754Smsmith        /*
28671867Smsmith         * All other types come here.
28767754Smsmith         */
288306536Sjkim        ACPI_WARNING ((AE_INFO, "Store into type [%s] not implemented",
28999679Siwasaki            AcpiUtGetObjectTypeName (DestDesc)));
29067754Smsmith
29167754Smsmith        Status = AE_NOT_IMPLEMENTED;
29267754Smsmith        break;
29367754Smsmith    }
29467754Smsmith
29591116Smsmith    if (ActualSrcDesc != SourceDesc)
29691116Smsmith    {
29791116Smsmith        /* Delete the intermediate (temporary) source object */
29867754Smsmith
29991116Smsmith        AcpiUtRemoveReference (ActualSrcDesc);
30091116Smsmith    }
30191116Smsmith
30291116Smsmith    *NewDesc = DestDesc;
30367754Smsmith    return_ACPI_STATUS (Status);
30467754Smsmith}
305