1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc  *
3433d6423SLionel Sambuc  * Module Name: exstoren - AML Interpreter object store support,
4433d6423SLionel Sambuc  *                        Store to Node (namespace object)
5433d6423SLionel Sambuc  *
6433d6423SLionel Sambuc  *****************************************************************************/
7433d6423SLionel Sambuc 
8*29492bb7SDavid van Moolenbroek /*
9*29492bb7SDavid van Moolenbroek  * Copyright (C) 2000 - 2014, Intel Corp.
10433d6423SLionel Sambuc  * All rights reserved.
11433d6423SLionel Sambuc  *
12*29492bb7SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
13*29492bb7SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
14*29492bb7SDavid van Moolenbroek  * are met:
15*29492bb7SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
16*29492bb7SDavid van Moolenbroek  *    notice, this list of conditions, and the following disclaimer,
17*29492bb7SDavid van Moolenbroek  *    without modification.
18*29492bb7SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19*29492bb7SDavid van Moolenbroek  *    substantially similar to the "NO WARRANTY" disclaimer below
20*29492bb7SDavid van Moolenbroek  *    ("Disclaimer") and any redistribution must be conditioned upon
21*29492bb7SDavid van Moolenbroek  *    including a substantially similar Disclaimer requirement for further
22*29492bb7SDavid van Moolenbroek  *    binary redistribution.
23*29492bb7SDavid van Moolenbroek  * 3. Neither the names of the above-listed copyright holders nor the names
24*29492bb7SDavid van Moolenbroek  *    of any contributors may be used to endorse or promote products derived
25*29492bb7SDavid van Moolenbroek  *    from this software without specific prior written permission.
26433d6423SLionel Sambuc  *
27*29492bb7SDavid van Moolenbroek  * Alternatively, this software may be distributed under the terms of the
28*29492bb7SDavid van Moolenbroek  * GNU General Public License ("GPL") version 2 as published by the Free
29*29492bb7SDavid van Moolenbroek  * Software Foundation.
30433d6423SLionel Sambuc  *
31*29492bb7SDavid van Moolenbroek  * NO WARRANTY
32*29492bb7SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33*29492bb7SDavid van Moolenbroek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34*29492bb7SDavid van Moolenbroek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35*29492bb7SDavid van Moolenbroek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36*29492bb7SDavid van Moolenbroek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37*29492bb7SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38*29492bb7SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39*29492bb7SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40*29492bb7SDavid van Moolenbroek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41*29492bb7SDavid van Moolenbroek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42*29492bb7SDavid van Moolenbroek  * POSSIBILITY OF SUCH DAMAGES.
43*29492bb7SDavid van Moolenbroek  */
44433d6423SLionel Sambuc 
45433d6423SLionel Sambuc #include "acpi.h"
46433d6423SLionel Sambuc #include "accommon.h"
47433d6423SLionel Sambuc #include "acinterp.h"
48433d6423SLionel Sambuc #include "amlcode.h"
49433d6423SLionel Sambuc 
50433d6423SLionel Sambuc 
51433d6423SLionel Sambuc #define _COMPONENT          ACPI_EXECUTER
52433d6423SLionel Sambuc         ACPI_MODULE_NAME    ("exstoren")
53433d6423SLionel Sambuc 
54433d6423SLionel Sambuc 
55433d6423SLionel Sambuc /*******************************************************************************
56433d6423SLionel Sambuc  *
57433d6423SLionel Sambuc  * FUNCTION:    AcpiExResolveObject
58433d6423SLionel Sambuc  *
59433d6423SLionel Sambuc  * PARAMETERS:  SourceDescPtr       - Pointer to the source object
60433d6423SLionel Sambuc  *              TargetType          - Current type of the target
61433d6423SLionel Sambuc  *              WalkState           - Current walk state
62433d6423SLionel Sambuc  *
63433d6423SLionel Sambuc  * RETURN:      Status, resolved object in SourceDescPtr.
64433d6423SLionel Sambuc  *
65433d6423SLionel Sambuc  * DESCRIPTION: Resolve an object. If the object is a reference, dereference
66433d6423SLionel Sambuc  *              it and return the actual object in the SourceDescPtr.
67433d6423SLionel Sambuc  *
68433d6423SLionel Sambuc  ******************************************************************************/
69433d6423SLionel Sambuc 
70433d6423SLionel Sambuc ACPI_STATUS
AcpiExResolveObject(ACPI_OPERAND_OBJECT ** SourceDescPtr,ACPI_OBJECT_TYPE TargetType,ACPI_WALK_STATE * WalkState)71433d6423SLionel Sambuc AcpiExResolveObject (
72433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **SourceDescPtr,
73433d6423SLionel Sambuc     ACPI_OBJECT_TYPE        TargetType,
74433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState)
75433d6423SLionel Sambuc {
76433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceDesc = *SourceDescPtr;
77433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
78433d6423SLionel Sambuc 
79433d6423SLionel Sambuc 
80433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (ExResolveObject);
81433d6423SLionel Sambuc 
82433d6423SLionel Sambuc 
83433d6423SLionel Sambuc     /* Ensure we have a Target that can be stored to */
84433d6423SLionel Sambuc 
85433d6423SLionel Sambuc     switch (TargetType)
86433d6423SLionel Sambuc     {
87433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER_FIELD:
88433d6423SLionel Sambuc     case ACPI_TYPE_LOCAL_REGION_FIELD:
89433d6423SLionel Sambuc     case ACPI_TYPE_LOCAL_BANK_FIELD:
90433d6423SLionel Sambuc     case ACPI_TYPE_LOCAL_INDEX_FIELD:
91433d6423SLionel Sambuc         /*
92433d6423SLionel Sambuc          * These cases all require only Integers or values that
93433d6423SLionel Sambuc          * can be converted to Integers (Strings or Buffers)
94433d6423SLionel Sambuc          */
95433d6423SLionel Sambuc     case ACPI_TYPE_INTEGER:
96433d6423SLionel Sambuc     case ACPI_TYPE_STRING:
97433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER:
98433d6423SLionel Sambuc         /*
99433d6423SLionel Sambuc          * Stores into a Field/Region or into a Integer/Buffer/String
100433d6423SLionel Sambuc          * are all essentially the same. This case handles the
101433d6423SLionel Sambuc          * "interchangeable" types Integer, String, and Buffer.
102433d6423SLionel Sambuc          */
103433d6423SLionel Sambuc         if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
104433d6423SLionel Sambuc         {
105433d6423SLionel Sambuc             /* Resolve a reference object first */
106433d6423SLionel Sambuc 
107433d6423SLionel Sambuc             Status = AcpiExResolveToValue (SourceDescPtr, WalkState);
108433d6423SLionel Sambuc             if (ACPI_FAILURE (Status))
109433d6423SLionel Sambuc             {
110433d6423SLionel Sambuc                 break;
111433d6423SLionel Sambuc             }
112433d6423SLionel Sambuc         }
113433d6423SLionel Sambuc 
114433d6423SLionel Sambuc         /* For CopyObject, no further validation necessary */
115433d6423SLionel Sambuc 
116433d6423SLionel Sambuc         if (WalkState->Opcode == AML_COPY_OP)
117433d6423SLionel Sambuc         {
118433d6423SLionel Sambuc             break;
119433d6423SLionel Sambuc         }
120433d6423SLionel Sambuc 
121433d6423SLionel Sambuc         /* Must have a Integer, Buffer, or String */
122433d6423SLionel Sambuc 
123433d6423SLionel Sambuc         if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER)    &&
124433d6423SLionel Sambuc             (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)     &&
125433d6423SLionel Sambuc             (SourceDesc->Common.Type != ACPI_TYPE_STRING)     &&
126433d6423SLionel Sambuc             !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
127433d6423SLionel Sambuc                     (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE)))
128433d6423SLionel Sambuc         {
129433d6423SLionel Sambuc             /* Conversion successful but still not a valid type */
130433d6423SLionel Sambuc 
131433d6423SLionel Sambuc             ACPI_ERROR ((AE_INFO,
132433d6423SLionel Sambuc                 "Cannot assign type %s to %s (must be type Int/Str/Buf)",
133433d6423SLionel Sambuc                 AcpiUtGetObjectTypeName (SourceDesc),
134433d6423SLionel Sambuc                 AcpiUtGetTypeName (TargetType)));
135433d6423SLionel Sambuc             Status = AE_AML_OPERAND_TYPE;
136433d6423SLionel Sambuc         }
137433d6423SLionel Sambuc         break;
138433d6423SLionel Sambuc 
139433d6423SLionel Sambuc     case ACPI_TYPE_LOCAL_ALIAS:
140433d6423SLionel Sambuc     case ACPI_TYPE_LOCAL_METHOD_ALIAS:
141433d6423SLionel Sambuc         /*
142433d6423SLionel Sambuc          * All aliases should have been resolved earlier, during the
143433d6423SLionel Sambuc          * operand resolution phase.
144433d6423SLionel Sambuc          */
145433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object"));
146433d6423SLionel Sambuc         Status = AE_AML_INTERNAL;
147433d6423SLionel Sambuc         break;
148433d6423SLionel Sambuc 
149433d6423SLionel Sambuc     case ACPI_TYPE_PACKAGE:
150433d6423SLionel Sambuc     default:
151433d6423SLionel Sambuc         /*
152433d6423SLionel Sambuc          * All other types than Alias and the various Fields come here,
153433d6423SLionel Sambuc          * including the untyped case - ACPI_TYPE_ANY.
154433d6423SLionel Sambuc          */
155433d6423SLionel Sambuc         break;
156433d6423SLionel Sambuc     }
157433d6423SLionel Sambuc 
158433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
159433d6423SLionel Sambuc }
160433d6423SLionel Sambuc 
161433d6423SLionel Sambuc 
162433d6423SLionel Sambuc /*******************************************************************************
163433d6423SLionel Sambuc  *
164433d6423SLionel Sambuc  * FUNCTION:    AcpiExStoreObjectToObject
165433d6423SLionel Sambuc  *
166433d6423SLionel Sambuc  * PARAMETERS:  SourceDesc          - Object to store
167433d6423SLionel Sambuc  *              DestDesc            - Object to receive a copy of the source
168433d6423SLionel Sambuc  *              NewDesc             - New object if DestDesc is obsoleted
169433d6423SLionel Sambuc  *              WalkState           - Current walk state
170433d6423SLionel Sambuc  *
171433d6423SLionel Sambuc  * RETURN:      Status
172433d6423SLionel Sambuc  *
173433d6423SLionel Sambuc  * DESCRIPTION: "Store" an object to another object. This may include
174433d6423SLionel Sambuc  *              converting the source type to the target type (implicit
175433d6423SLionel Sambuc  *              conversion), and a copy of the value of the source to
176433d6423SLionel Sambuc  *              the target.
177433d6423SLionel Sambuc  *
178433d6423SLionel Sambuc  *              The Assignment of an object to another (not named) object
179433d6423SLionel Sambuc  *              is handled here.
180433d6423SLionel Sambuc  *              The Source passed in will replace the current value (if any)
181433d6423SLionel Sambuc  *              with the input value.
182433d6423SLionel Sambuc  *
183433d6423SLionel Sambuc  *              When storing into an object the data is converted to the
184433d6423SLionel Sambuc  *              target object type then stored in the object. This means
185433d6423SLionel Sambuc  *              that the target object type (for an initialized target) will
186433d6423SLionel Sambuc  *              not be changed by a store operation.
187433d6423SLionel Sambuc  *
188433d6423SLionel Sambuc  *              This module allows destination types of Number, String,
189433d6423SLionel Sambuc  *              Buffer, and Package.
190433d6423SLionel Sambuc  *
191433d6423SLionel Sambuc  *              Assumes parameters are already validated. NOTE: SourceDesc
192433d6423SLionel Sambuc  *              resolution (from a reference object) must be performed by
193433d6423SLionel Sambuc  *              the caller if necessary.
194433d6423SLionel Sambuc  *
195433d6423SLionel Sambuc  ******************************************************************************/
196433d6423SLionel Sambuc 
197433d6423SLionel Sambuc ACPI_STATUS
AcpiExStoreObjectToObject(ACPI_OPERAND_OBJECT * SourceDesc,ACPI_OPERAND_OBJECT * DestDesc,ACPI_OPERAND_OBJECT ** NewDesc,ACPI_WALK_STATE * WalkState)198433d6423SLionel Sambuc AcpiExStoreObjectToObject (
199433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *SourceDesc,
200433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *DestDesc,
201433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **NewDesc,
202433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState)
203433d6423SLionel Sambuc {
204433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ActualSrcDesc;
205433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
206433d6423SLionel Sambuc 
207433d6423SLionel Sambuc 
208433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc);
209433d6423SLionel Sambuc 
210433d6423SLionel Sambuc 
211433d6423SLionel Sambuc     ActualSrcDesc = SourceDesc;
212433d6423SLionel Sambuc     if (!DestDesc)
213433d6423SLionel Sambuc     {
214433d6423SLionel Sambuc         /*
215433d6423SLionel Sambuc          * There is no destination object (An uninitialized node or
216433d6423SLionel Sambuc          * package element), so we can simply copy the source object
217433d6423SLionel Sambuc          * creating a new destination object
218433d6423SLionel Sambuc          */
219433d6423SLionel Sambuc         Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState);
220433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
221433d6423SLionel Sambuc     }
222433d6423SLionel Sambuc 
223433d6423SLionel Sambuc     if (SourceDesc->Common.Type != DestDesc->Common.Type)
224433d6423SLionel Sambuc     {
225433d6423SLionel Sambuc         /*
226433d6423SLionel Sambuc          * The source type does not match the type of the destination.
227433d6423SLionel Sambuc          * Perform the "implicit conversion" of the source to the current type
228433d6423SLionel Sambuc          * of the target as per the ACPI specification.
229433d6423SLionel Sambuc          *
230433d6423SLionel Sambuc          * If no conversion performed, ActualSrcDesc = SourceDesc.
231433d6423SLionel Sambuc          * Otherwise, ActualSrcDesc is a temporary object to hold the
232433d6423SLionel Sambuc          * converted object.
233433d6423SLionel Sambuc          */
234433d6423SLionel Sambuc         Status = AcpiExConvertToTargetType (DestDesc->Common.Type,
235433d6423SLionel Sambuc                         SourceDesc, &ActualSrcDesc, WalkState);
236433d6423SLionel Sambuc         if (ACPI_FAILURE (Status))
237433d6423SLionel Sambuc         {
238433d6423SLionel Sambuc             return_ACPI_STATUS (Status);
239433d6423SLionel Sambuc         }
240433d6423SLionel Sambuc 
241433d6423SLionel Sambuc         if (SourceDesc == ActualSrcDesc)
242433d6423SLionel Sambuc         {
243433d6423SLionel Sambuc             /*
244433d6423SLionel Sambuc              * No conversion was performed. Return the SourceDesc as the
245433d6423SLionel Sambuc              * new object.
246433d6423SLionel Sambuc              */
247433d6423SLionel Sambuc             *NewDesc = SourceDesc;
248433d6423SLionel Sambuc             return_ACPI_STATUS (AE_OK);
249433d6423SLionel Sambuc         }
250433d6423SLionel Sambuc     }
251433d6423SLionel Sambuc 
252433d6423SLionel Sambuc     /*
253433d6423SLionel Sambuc      * We now have two objects of identical types, and we can perform a
254433d6423SLionel Sambuc      * copy of the *value* of the source object.
255433d6423SLionel Sambuc      */
256433d6423SLionel Sambuc     switch (DestDesc->Common.Type)
257433d6423SLionel Sambuc     {
258433d6423SLionel Sambuc     case ACPI_TYPE_INTEGER:
259433d6423SLionel Sambuc 
260433d6423SLionel Sambuc         DestDesc->Integer.Value = ActualSrcDesc->Integer.Value;
261433d6423SLionel Sambuc 
262433d6423SLionel Sambuc         /* Truncate value if we are executing from a 32-bit ACPI table */
263433d6423SLionel Sambuc 
264*29492bb7SDavid van Moolenbroek         (void) AcpiExTruncateFor32bitTable (DestDesc);
265433d6423SLionel Sambuc         break;
266433d6423SLionel Sambuc 
267433d6423SLionel Sambuc     case ACPI_TYPE_STRING:
268433d6423SLionel Sambuc 
269433d6423SLionel Sambuc         Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc);
270433d6423SLionel Sambuc         break;
271433d6423SLionel Sambuc 
272433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER:
273433d6423SLionel Sambuc 
274433d6423SLionel Sambuc         Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc);
275433d6423SLionel Sambuc         break;
276433d6423SLionel Sambuc 
277433d6423SLionel Sambuc     case ACPI_TYPE_PACKAGE:
278433d6423SLionel Sambuc 
279433d6423SLionel Sambuc         Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc,
280433d6423SLionel Sambuc                     WalkState);
281433d6423SLionel Sambuc         break;
282433d6423SLionel Sambuc 
283433d6423SLionel Sambuc     default:
284433d6423SLionel Sambuc         /*
285433d6423SLionel Sambuc          * All other types come here.
286433d6423SLionel Sambuc          */
287433d6423SLionel Sambuc         ACPI_WARNING ((AE_INFO, "Store into type %s not implemented",
288433d6423SLionel Sambuc             AcpiUtGetObjectTypeName (DestDesc)));
289433d6423SLionel Sambuc 
290433d6423SLionel Sambuc         Status = AE_NOT_IMPLEMENTED;
291433d6423SLionel Sambuc         break;
292433d6423SLionel Sambuc     }
293433d6423SLionel Sambuc 
294433d6423SLionel Sambuc     if (ActualSrcDesc != SourceDesc)
295433d6423SLionel Sambuc     {
296433d6423SLionel Sambuc         /* Delete the intermediate (temporary) source object */
297433d6423SLionel Sambuc 
298433d6423SLionel Sambuc         AcpiUtRemoveReference (ActualSrcDesc);
299433d6423SLionel Sambuc     }
300433d6423SLionel Sambuc 
301433d6423SLionel Sambuc     *NewDesc = DestDesc;
302433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
303433d6423SLionel Sambuc }
304