1 
2 /******************************************************************************
3  *
4  * Module Name: exstoren - AML Interpreter object store support,
5  *                        Store to Node (namespace object)
6  *
7  *****************************************************************************/
8 
9 /*
10  * Copyright (C) 2000 - 2004, R. Byron Moore
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions, and the following disclaimer,
18  *    without modification.
19  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
20  *    substantially similar to the "NO WARRANTY" disclaimer below
21  *    ("Disclaimer") and any redistribution must be conditioned upon
22  *    including a substantially similar Disclaimer requirement for further
23  *    binary redistribution.
24  * 3. Neither the names of the above-listed copyright holders nor the names
25  *    of any contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * Alternatively, this software may be distributed under the terms of the
29  * GNU General Public License ("GPL") version 2 as published by the Free
30  * Software Foundation.
31  *
32  * NO WARRANTY
33  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
36  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43  * POSSIBILITY OF SUCH DAMAGES.
44  */
45 
46 
47 #include <acpi/acpi.h>
48 #include <acpi/acinterp.h>
49 #include <acpi/amlcode.h>
50 
51 
52 #define _COMPONENT          ACPI_EXECUTER
53 	 ACPI_MODULE_NAME    ("exstoren")
54 
55 
56 /*******************************************************************************
57  *
58  * FUNCTION:    acpi_ex_resolve_object
59  *
60  * PARAMETERS:  source_desc_ptr     - Pointer to the source object
61  *              target_type         - Current type of the target
62  *              walk_state          - Current walk state
63  *
64  * RETURN:      Status, resolved object in source_desc_ptr.
65  *
66  * DESCRIPTION: Resolve an object.  If the object is a reference, dereference
67  *              it and return the actual object in the source_desc_ptr.
68  *
69  ******************************************************************************/
70 
71 acpi_status
acpi_ex_resolve_object(union acpi_operand_object ** source_desc_ptr,acpi_object_type target_type,struct acpi_walk_state * walk_state)72 acpi_ex_resolve_object (
73 	union acpi_operand_object       **source_desc_ptr,
74 	acpi_object_type                target_type,
75 	struct acpi_walk_state          *walk_state)
76 {
77 	union acpi_operand_object       *source_desc = *source_desc_ptr;
78 	acpi_status                     status = AE_OK;
79 
80 
81 	ACPI_FUNCTION_TRACE ("ex_resolve_object");
82 
83 
84 	/*
85 	 * Ensure we have a Target that can be stored to
86 	 */
87 	switch (target_type) {
88 	case ACPI_TYPE_BUFFER_FIELD:
89 	case ACPI_TYPE_LOCAL_REGION_FIELD:
90 	case ACPI_TYPE_LOCAL_BANK_FIELD:
91 	case ACPI_TYPE_LOCAL_INDEX_FIELD:
92 		/*
93 		 * These cases all require only Integers or values that
94 		 * can be converted to Integers (Strings or Buffers)
95 		 */
96 
97 	case ACPI_TYPE_INTEGER:
98 	case ACPI_TYPE_STRING:
99 	case ACPI_TYPE_BUFFER:
100 
101 		/*
102 		 * Stores into a Field/Region or into a Integer/Buffer/String
103 		 * are all essentially the same.  This case handles the
104 		 * "interchangeable" types Integer, String, and Buffer.
105 		 */
106 		if (ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
107 			/* Resolve a reference object first */
108 
109 			status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state);
110 			if (ACPI_FAILURE (status)) {
111 				break;
112 			}
113 		}
114 
115 		/* For copy_object, no further validation necessary */
116 
117 		if (walk_state->opcode == AML_COPY_OP) {
118 			break;
119 		}
120 
121 		/*
122 		 * Must have a Integer, Buffer, or String
123 		 */
124 		if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER)   &&
125 			(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER)    &&
126 			(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING)    &&
127 			!((ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) && (source_desc->reference.opcode == AML_LOAD_OP))) {
128 			/*
129 			 * Conversion successful but still not a valid type
130 			 */
131 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
132 				"Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
133 				acpi_ut_get_object_type_name (source_desc),
134 				acpi_ut_get_type_name (target_type)));
135 			status = AE_AML_OPERAND_TYPE;
136 		}
137 		break;
138 
139 
140 	case ACPI_TYPE_LOCAL_ALIAS:
141 	case ACPI_TYPE_LOCAL_METHOD_ALIAS:
142 
143 		/*
144 		 * Aliases are resolved by acpi_ex_prep_operands
145 		 */
146 		ACPI_REPORT_ERROR (("Store into Alias - should never happen\n"));
147 		status = AE_AML_INTERNAL;
148 		break;
149 
150 
151 	case ACPI_TYPE_PACKAGE:
152 	default:
153 
154 		/*
155 		 * All other types than Alias and the various Fields come here,
156 		 * including the untyped case - ACPI_TYPE_ANY.
157 		 */
158 		break;
159 	}
160 
161 	return_ACPI_STATUS (status);
162 }
163 
164 
165 /*******************************************************************************
166  *
167  * FUNCTION:    acpi_ex_store_object_to_object
168  *
169  * PARAMETERS:  source_desc         - Object to store
170  *              dest_desc           - Object to receive a copy of the source
171  *              new_desc            - New object if dest_desc is obsoleted
172  *              walk_state          - Current walk state
173  *
174  * RETURN:      Status
175  *
176  * DESCRIPTION: "Store" an object to another object.  This may include
177  *              converting the source type to the target type (implicit
178  *              conversion), and a copy of the value of the source to
179  *              the target.
180  *
181  *              The Assignment of an object to another (not named) object
182  *              is handled here.
183  *              The Source passed in will replace the current value (if any)
184  *              with the input value.
185  *
186  *              When storing into an object the data is converted to the
187  *              target object type then stored in the object.  This means
188  *              that the target object type (for an initialized target) will
189  *              not be changed by a store operation.
190  *
191  *              This module allows destination types of Number, String,
192  *              Buffer, and Package.
193  *
194  *              Assumes parameters are already validated.  NOTE: source_desc
195  *              resolution (from a reference object) must be performed by
196  *              the caller if necessary.
197  *
198  ******************************************************************************/
199 
200 acpi_status
acpi_ex_store_object_to_object(union acpi_operand_object * source_desc,union acpi_operand_object * dest_desc,union acpi_operand_object ** new_desc,struct acpi_walk_state * walk_state)201 acpi_ex_store_object_to_object (
202 	union acpi_operand_object       *source_desc,
203 	union acpi_operand_object       *dest_desc,
204 	union acpi_operand_object       **new_desc,
205 	struct acpi_walk_state          *walk_state)
206 {
207 	union acpi_operand_object       *actual_src_desc;
208 	acpi_status                     status = AE_OK;
209 
210 
211 	ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc);
212 
213 
214 	actual_src_desc = source_desc;
215 	if (!dest_desc) {
216 		/*
217 		 * There is no destination object (An uninitialized node or
218 		 * package element), so we can simply copy the source object
219 		 * creating a new destination object
220 		 */
221 		status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, new_desc, walk_state);
222 		return_ACPI_STATUS (status);
223 	}
224 
225 	if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
226 		/*
227 		 * The source type does not match the type of the destination.
228 		 * Perform the "implicit conversion" of the source to the current type
229 		 * of the target as per the ACPI specification.
230 		 *
231 		 * If no conversion performed, actual_src_desc = source_desc.
232 		 * Otherwise, actual_src_desc is a temporary object to hold the
233 		 * converted object.
234 		 */
235 		status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc), source_desc,
236 				  &actual_src_desc, walk_state);
237 		if (ACPI_FAILURE (status)) {
238 			return_ACPI_STATUS (status);
239 		}
240 
241 		if (source_desc == actual_src_desc) {
242 			/*
243 			 * No conversion was performed.  Return the source_desc as the
244 			 * new object.
245 			 */
246 			*new_desc = source_desc;
247 			return_ACPI_STATUS (AE_OK);
248 		}
249 	}
250 
251 	/*
252 	 * We now have two objects of identical types, and we can perform a
253 	 * copy of the *value* of the source object.
254 	 */
255 	switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
256 	case ACPI_TYPE_INTEGER:
257 
258 		dest_desc->integer.value = actual_src_desc->integer.value;
259 
260 		/* Truncate value if we are executing from a 32-bit ACPI table */
261 
262 		acpi_ex_truncate_for32bit_table (dest_desc);
263 		break;
264 
265 	case ACPI_TYPE_STRING:
266 
267 		status = acpi_ex_store_string_to_string (actual_src_desc, dest_desc);
268 		break;
269 
270 	case ACPI_TYPE_BUFFER:
271 
272 		status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc);
273 		break;
274 
275 	case ACPI_TYPE_PACKAGE:
276 
277 		status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc, walk_state);
278 		break;
279 
280 	default:
281 		/*
282 		 * All other types come here.
283 		 */
284 		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into type %s not implemented\n",
285 			acpi_ut_get_object_type_name (dest_desc)));
286 
287 		status = AE_NOT_IMPLEMENTED;
288 		break;
289 	}
290 
291 	if (actual_src_desc != source_desc) {
292 		/* Delete the intermediate (temporary) source object */
293 
294 		acpi_ut_remove_reference (actual_src_desc);
295 	}
296 
297 	*new_desc = dest_desc;
298 	return_ACPI_STATUS (status);
299 }
300 
301 
302