exstoren.c revision 241973
1219185Sadrian/******************************************************************************
2219185Sadrian *
3219185Sadrian * Module Name: exstoren - AML Interpreter object store support,
4219185Sadrian *                        Store to Node (namespace object)
5219185Sadrian *
6219185Sadrian *****************************************************************************/
7219185Sadrian
8219185Sadrian/*
9219185Sadrian * Copyright (C) 2000 - 2012, Intel Corp.
10219185Sadrian * All rights reserved.
11219185Sadrian *
12219185Sadrian * Redistribution and use in source and binary forms, with or without
13219185Sadrian * modification, are permitted provided that the following conditions
14219185Sadrian * are met:
15219185Sadrian * 1. Redistributions of source code must retain the above copyright
16219185Sadrian *    notice, this list of conditions, and the following disclaimer,
17219185Sadrian *    without modification.
18219185Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19219185Sadrian *    substantially similar to the "NO WARRANTY" disclaimer below
20219185Sadrian *    ("Disclaimer") and any redistribution must be conditioned upon
21219185Sadrian *    including a substantially similar Disclaimer requirement for further
22219185Sadrian *    binary redistribution.
23219185Sadrian * 3. Neither the names of the above-listed copyright holders nor the names
24219185Sadrian *    of any contributors may be used to endorse or promote products derived
25219185Sadrian *    from this software without specific prior written permission.
26219185Sadrian *
27219185Sadrian * Alternatively, this software may be distributed under the terms of the
28219185Sadrian * GNU General Public License ("GPL") version 2 as published by the Free
29219185Sadrian * Software Foundation.
30219185Sadrian *
31219185Sadrian * NO WARRANTY
32219185Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33219185Sadrian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34219185Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35219185Sadrian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36219185Sadrian * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37219185Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38219185Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39219185Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40219185Sadrian * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41219185Sadrian * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42219185Sadrian * POSSIBILITY OF SUCH DAMAGES.
43219185Sadrian */
44219185Sadrian
45219185Sadrian#define __EXSTOREN_C__
46219185Sadrian
47219185Sadrian#include <contrib/dev/acpica/include/acpi.h>
48219185Sadrian#include <contrib/dev/acpica/include/accommon.h>
49219185Sadrian#include <contrib/dev/acpica/include/acinterp.h>
50219185Sadrian#include <contrib/dev/acpica/include/amlcode.h>
51219185Sadrian
52219185Sadrian
53219185Sadrian#define _COMPONENT          ACPI_EXECUTER
54219185Sadrian        ACPI_MODULE_NAME    ("exstoren")
55219185Sadrian
56219185Sadrian
57219185Sadrian/*******************************************************************************
58219185Sadrian *
59219185Sadrian * FUNCTION:    AcpiExResolveObject
60219185Sadrian *
61219185Sadrian * PARAMETERS:  SourceDescPtr       - Pointer to the source object
62219185Sadrian *              TargetType          - Current type of the target
63219185Sadrian *              WalkState           - Current walk state
64219185Sadrian *
65219185Sadrian * RETURN:      Status, resolved object in SourceDescPtr.
66219185Sadrian *
67219185Sadrian * DESCRIPTION: Resolve an object. If the object is a reference, dereference
68219185Sadrian *              it and return the actual object in the SourceDescPtr.
69219185Sadrian *
70219185Sadrian ******************************************************************************/
71219185Sadrian
72219185SadrianACPI_STATUS
73219185SadrianAcpiExResolveObject (
74219185Sadrian    ACPI_OPERAND_OBJECT     **SourceDescPtr,
75219185Sadrian    ACPI_OBJECT_TYPE        TargetType,
76219185Sadrian    ACPI_WALK_STATE         *WalkState)
77219185Sadrian{
78219185Sadrian    ACPI_OPERAND_OBJECT     *SourceDesc = *SourceDescPtr;
79219185Sadrian    ACPI_STATUS             Status = AE_OK;
80219185Sadrian
81219185Sadrian
82219185Sadrian    ACPI_FUNCTION_TRACE (ExResolveObject);
83219185Sadrian
84219185Sadrian
85219185Sadrian    /* Ensure we have a Target that can be stored to */
86219185Sadrian
87219185Sadrian    switch (TargetType)
88219185Sadrian    {
89219185Sadrian    case ACPI_TYPE_BUFFER_FIELD:
90219185Sadrian    case ACPI_TYPE_LOCAL_REGION_FIELD:
91219185Sadrian    case ACPI_TYPE_LOCAL_BANK_FIELD:
92219185Sadrian    case ACPI_TYPE_LOCAL_INDEX_FIELD:
93219185Sadrian        /*
94219185Sadrian         * These cases all require only Integers or values that
95219185Sadrian         * can be converted to Integers (Strings or Buffers)
96219185Sadrian         */
97219185Sadrian
98219185Sadrian    case ACPI_TYPE_INTEGER:
99219185Sadrian    case ACPI_TYPE_STRING:
100219185Sadrian    case ACPI_TYPE_BUFFER:
101219185Sadrian
102219185Sadrian        /*
103219185Sadrian         * Stores into a Field/Region or into a Integer/Buffer/String
104219185Sadrian         * are all essentially the same. This case handles the
105219185Sadrian         * "interchangeable" types Integer, String, and Buffer.
106219185Sadrian         */
107219185Sadrian        if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
108219185Sadrian        {
109219185Sadrian            /* Resolve a reference object first */
110219185Sadrian
111219185Sadrian            Status = AcpiExResolveToValue (SourceDescPtr, WalkState);
112219185Sadrian            if (ACPI_FAILURE (Status))
113219185Sadrian            {
114219185Sadrian                break;
115219185Sadrian            }
116219185Sadrian        }
117219185Sadrian
118219185Sadrian        /* For CopyObject, no further validation necessary */
119219185Sadrian
120219185Sadrian        if (WalkState->Opcode == AML_COPY_OP)
121219185Sadrian        {
122219185Sadrian            break;
123219185Sadrian        }
124219185Sadrian
125219185Sadrian        /* Must have a Integer, Buffer, or String */
126219185Sadrian
127219185Sadrian        if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER)    &&
128219185Sadrian            (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)     &&
129219185Sadrian            (SourceDesc->Common.Type != ACPI_TYPE_STRING)     &&
130219185Sadrian            !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
131219185Sadrian                    (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE)))
132219185Sadrian        {
133219185Sadrian            /* Conversion successful but still not a valid type */
134219185Sadrian
135219185Sadrian            ACPI_ERROR ((AE_INFO,
136219185Sadrian                "Cannot assign type %s to %s (must be type Int/Str/Buf)",
137219185Sadrian                AcpiUtGetObjectTypeName (SourceDesc),
138219185Sadrian                AcpiUtGetTypeName (TargetType)));
139219185Sadrian            Status = AE_AML_OPERAND_TYPE;
140219185Sadrian        }
141219185Sadrian        break;
142219185Sadrian
143219185Sadrian
144219185Sadrian    case ACPI_TYPE_LOCAL_ALIAS:
145219185Sadrian    case ACPI_TYPE_LOCAL_METHOD_ALIAS:
146219185Sadrian
147219185Sadrian        /*
148219185Sadrian         * All aliases should have been resolved earlier, during the
149219185Sadrian         * operand resolution phase.
150219185Sadrian         */
151219185Sadrian        ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object"));
152219185Sadrian        Status = AE_AML_INTERNAL;
153219185Sadrian        break;
154219185Sadrian
155219185Sadrian
156219185Sadrian    case ACPI_TYPE_PACKAGE:
157219185Sadrian    default:
158219185Sadrian
159219185Sadrian        /*
160219185Sadrian         * All other types than Alias and the various Fields come here,
161219185Sadrian         * including the untyped case - ACPI_TYPE_ANY.
162219185Sadrian         */
163219185Sadrian        break;
164219185Sadrian    }
165219185Sadrian
166219185Sadrian    return_ACPI_STATUS (Status);
167219185Sadrian}
168219185Sadrian
169219185Sadrian
170219185Sadrian/*******************************************************************************
171219185Sadrian *
172219185Sadrian * FUNCTION:    AcpiExStoreObjectToObject
173219185Sadrian *
174219185Sadrian * PARAMETERS:  SourceDesc          - Object to store
175219185Sadrian *              DestDesc            - Object to receive a copy of the source
176219185Sadrian *              NewDesc             - New object if DestDesc is obsoleted
177219185Sadrian *              WalkState           - Current walk state
178219185Sadrian *
179219185Sadrian * RETURN:      Status
180219185Sadrian *
181219185Sadrian * DESCRIPTION: "Store" an object to another object. This may include
182219185Sadrian *              converting the source type to the target type (implicit
183219185Sadrian *              conversion), and a copy of the value of the source to
184219185Sadrian *              the target.
185219185Sadrian *
186219185Sadrian *              The Assignment of an object to another (not named) object
187219185Sadrian *              is handled here.
188219185Sadrian *              The Source passed in will replace the current value (if any)
189219185Sadrian *              with the input value.
190219185Sadrian *
191219185Sadrian *              When storing into an object the data is converted to the
192219185Sadrian *              target object type then stored in the object. This means
193219185Sadrian *              that the target object type (for an initialized target) will
194219185Sadrian *              not be changed by a store operation.
195219185Sadrian *
196219185Sadrian *              This module allows destination types of Number, String,
197219185Sadrian *              Buffer, and Package.
198219185Sadrian *
199219185Sadrian *              Assumes parameters are already validated. NOTE: SourceDesc
200219185Sadrian *              resolution (from a reference object) must be performed by
201219185Sadrian *              the caller if necessary.
202219185Sadrian *
203219185Sadrian ******************************************************************************/
204219185Sadrian
205219185SadrianACPI_STATUS
206219185SadrianAcpiExStoreObjectToObject (
207219185Sadrian    ACPI_OPERAND_OBJECT     *SourceDesc,
208219185Sadrian    ACPI_OPERAND_OBJECT     *DestDesc,
209219185Sadrian    ACPI_OPERAND_OBJECT     **NewDesc,
210219185Sadrian    ACPI_WALK_STATE         *WalkState)
211219185Sadrian{
212219185Sadrian    ACPI_OPERAND_OBJECT     *ActualSrcDesc;
213219185Sadrian    ACPI_STATUS             Status = AE_OK;
214219185Sadrian
215219185Sadrian
216219185Sadrian    ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc);
217219185Sadrian
218219185Sadrian
219219185Sadrian    ActualSrcDesc = SourceDesc;
220219185Sadrian    if (!DestDesc)
221219185Sadrian    {
222219185Sadrian        /*
223219185Sadrian         * There is no destination object (An uninitialized node or
224219185Sadrian         * package element), so we can simply copy the source object
225219185Sadrian         * creating a new destination object
226219185Sadrian         */
227219185Sadrian        Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState);
228219185Sadrian        return_ACPI_STATUS (Status);
229219185Sadrian    }
230219185Sadrian
231219185Sadrian    if (SourceDesc->Common.Type != DestDesc->Common.Type)
232219185Sadrian    {
233219185Sadrian        /*
234219185Sadrian         * The source type does not match the type of the destination.
235219185Sadrian         * Perform the "implicit conversion" of the source to the current type
236219185Sadrian         * of the target as per the ACPI specification.
237219185Sadrian         *
238219185Sadrian         * If no conversion performed, ActualSrcDesc = SourceDesc.
239219185Sadrian         * Otherwise, ActualSrcDesc is a temporary object to hold the
240219185Sadrian         * converted object.
241219185Sadrian         */
242219185Sadrian        Status = AcpiExConvertToTargetType (DestDesc->Common.Type,
243219185Sadrian                        SourceDesc, &ActualSrcDesc, WalkState);
244219185Sadrian        if (ACPI_FAILURE (Status))
245219185Sadrian        {
246219185Sadrian            return_ACPI_STATUS (Status);
247219185Sadrian        }
248219185Sadrian
249219185Sadrian        if (SourceDesc == ActualSrcDesc)
250219185Sadrian        {
251219185Sadrian            /*
252219185Sadrian             * No conversion was performed. Return the SourceDesc as the
253219185Sadrian             * new object.
254219185Sadrian             */
255219185Sadrian            *NewDesc = SourceDesc;
256219185Sadrian            return_ACPI_STATUS (AE_OK);
257219185Sadrian        }
258219185Sadrian    }
259219185Sadrian
260219185Sadrian    /*
261219185Sadrian     * We now have two objects of identical types, and we can perform a
262219185Sadrian     * copy of the *value* of the source object.
263219185Sadrian     */
264219185Sadrian    switch (DestDesc->Common.Type)
265219185Sadrian    {
266219185Sadrian    case ACPI_TYPE_INTEGER:
267219185Sadrian
268219185Sadrian        DestDesc->Integer.Value = ActualSrcDesc->Integer.Value;
269219185Sadrian
270219185Sadrian        /* Truncate value if we are executing from a 32-bit ACPI table */
271219185Sadrian
272219185Sadrian        AcpiExTruncateFor32bitTable (DestDesc);
273219185Sadrian        break;
274219185Sadrian
275219185Sadrian    case ACPI_TYPE_STRING:
276219185Sadrian
277219185Sadrian        Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc);
278219185Sadrian        break;
279219185Sadrian
280219185Sadrian    case ACPI_TYPE_BUFFER:
281219185Sadrian
282219185Sadrian        Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc);
283219185Sadrian        break;
284219185Sadrian
285219185Sadrian    case ACPI_TYPE_PACKAGE:
286219185Sadrian
287219185Sadrian        Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc,
288219185Sadrian                    WalkState);
289219185Sadrian        break;
290219185Sadrian
291219185Sadrian    default:
292219185Sadrian        /*
293219185Sadrian         * All other types come here.
294219185Sadrian         */
295219185Sadrian        ACPI_WARNING ((AE_INFO, "Store into type %s not implemented",
296219185Sadrian            AcpiUtGetObjectTypeName (DestDesc)));
297219185Sadrian
298219185Sadrian        Status = AE_NOT_IMPLEMENTED;
299219185Sadrian        break;
300219185Sadrian    }
301219185Sadrian
302219185Sadrian    if (ActualSrcDesc != SourceDesc)
303219185Sadrian    {
304219185Sadrian        /* Delete the intermediate (temporary) source object */
305219185Sadrian
306219185Sadrian        AcpiUtRemoveReference (ActualSrcDesc);
307219185Sadrian    }
308219185Sadrian
309219185Sadrian    *NewDesc = DestDesc;
310219185Sadrian    return_ACPI_STATUS (Status);
311219185Sadrian}
312219185Sadrian