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