]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | |
2 | /****************************************************************************** | |
3 | * | |
4 | * Module Name: exstore - AML Interpreter object store support | |
5 | * | |
6 | *****************************************************************************/ | |
7 | ||
8 | /* | |
4a90c7e8 | 9 | * Copyright (C) 2000 - 2006, R. Byron Moore |
1da177e4 LT |
10 | * All rights reserved. |
11 | * | |
12 | * Redistribution and use in source and binary forms, with or without | |
13 | * modification, are permitted provided that the following conditions | |
14 | * are met: | |
15 | * 1. Redistributions of source code must retain the above copyright | |
16 | * notice, this list of conditions, and the following disclaimer, | |
17 | * without modification. | |
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | |
19 | * substantially similar to the "NO WARRANTY" disclaimer below | |
20 | * ("Disclaimer") and any redistribution must be conditioned upon | |
21 | * including a substantially similar Disclaimer requirement for further | |
22 | * binary redistribution. | |
23 | * 3. Neither the names of the above-listed copyright holders nor the names | |
24 | * of any contributors may be used to endorse or promote products derived | |
25 | * from this software without specific prior written permission. | |
26 | * | |
27 | * Alternatively, this software may be distributed under the terms of the | |
28 | * GNU General Public License ("GPL") version 2 as published by the Free | |
29 | * Software Foundation. | |
30 | * | |
31 | * NO WARRANTY | |
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | |
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
42 | * POSSIBILITY OF SUCH DAMAGES. | |
43 | */ | |
44 | ||
1da177e4 LT |
45 | #include <acpi/acpi.h> |
46 | #include <acpi/acdispat.h> | |
47 | #include <acpi/acinterp.h> | |
48 | #include <acpi/amlcode.h> | |
49 | #include <acpi/acnamesp.h> | |
44f6c012 | 50 | #include <acpi/acparser.h> |
1da177e4 | 51 | |
1da177e4 | 52 | #define _COMPONENT ACPI_EXECUTER |
4be44fcd | 53 | ACPI_MODULE_NAME("exstore") |
1da177e4 | 54 | |
44f6c012 | 55 | /* Local prototypes */ |
44f6c012 | 56 | static void |
4be44fcd LB |
57 | acpi_ex_do_debug_object(union acpi_operand_object *source_desc, |
58 | u32 level, u32 index); | |
44f6c012 RM |
59 | |
60 | static acpi_status | |
4be44fcd LB |
61 | acpi_ex_store_object_to_index(union acpi_operand_object *val_desc, |
62 | union acpi_operand_object *dest_desc, | |
63 | struct acpi_walk_state *walk_state); | |
44f6c012 RM |
64 | |
65 | /******************************************************************************* | |
66 | * | |
67 | * FUNCTION: acpi_ex_do_debug_object | |
68 | * | |
69 | * PARAMETERS: source_desc - Value to be stored | |
70 | * Level - Indentation level (used for packages) | |
71 | * Index - Current package element, zero if not pkg | |
72 | * | |
73 | * RETURN: None | |
74 | * | |
75 | * DESCRIPTION: Handles stores to the Debug Object. | |
76 | * | |
77 | ******************************************************************************/ | |
78 | ||
79 | static void | |
4be44fcd LB |
80 | acpi_ex_do_debug_object(union acpi_operand_object *source_desc, |
81 | u32 level, u32 index) | |
44f6c012 | 82 | { |
4be44fcd | 83 | u32 i; |
44f6c012 | 84 | |
4be44fcd | 85 | ACPI_FUNCTION_TRACE_PTR("ex_do_debug_object", source_desc); |
44f6c012 | 86 | |
4be44fcd LB |
87 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s", |
88 | level, " ")); | |
44f6c012 RM |
89 | |
90 | /* Display index for package output only */ | |
91 | ||
92 | if (index > 0) { | |
4be44fcd LB |
93 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, |
94 | "(%.2u) ", index - 1)); | |
44f6c012 RM |
95 | } |
96 | ||
97 | if (!source_desc) { | |
4be44fcd | 98 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n")); |
44f6c012 RM |
99 | return_VOID; |
100 | } | |
101 | ||
4be44fcd LB |
102 | if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) { |
103 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s: ", | |
104 | acpi_ut_get_object_type_name | |
105 | (source_desc))); | |
44f6c012 | 106 | |
4be44fcd LB |
107 | if (!acpi_ut_valid_internal_object(source_desc)) { |
108 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | |
109 | "%p, Invalid Internal Object!\n", | |
110 | source_desc)); | |
111 | return_VOID; | |
44f6c012 | 112 | } |
4be44fcd LB |
113 | } else if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == |
114 | ACPI_DESC_TYPE_NAMED) { | |
115 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s: %p\n", | |
116 | acpi_ut_get_type_name(((struct | |
117 | acpi_namespace_node | |
118 | *)source_desc)-> | |
119 | type), | |
120 | source_desc)); | |
44f6c012 | 121 | return_VOID; |
4be44fcd | 122 | } else { |
44f6c012 RM |
123 | return_VOID; |
124 | } | |
125 | ||
4be44fcd | 126 | switch (ACPI_GET_OBJECT_TYPE(source_desc)) { |
44f6c012 RM |
127 | case ACPI_TYPE_INTEGER: |
128 | ||
129 | /* Output correct integer width */ | |
130 | ||
131 | if (acpi_gbl_integer_byte_width == 4) { | |
4be44fcd LB |
132 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n", |
133 | (u32) source_desc->integer. | |
134 | value)); | |
135 | } else { | |
136 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | |
137 | "0x%8.8X%8.8X\n", | |
138 | ACPI_FORMAT_UINT64(source_desc-> | |
139 | integer. | |
140 | value))); | |
44f6c012 RM |
141 | } |
142 | break; | |
143 | ||
144 | case ACPI_TYPE_BUFFER: | |
145 | ||
4be44fcd LB |
146 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]\n", |
147 | (u32) source_desc->buffer.length)); | |
148 | ACPI_DUMP_BUFFER(source_desc->buffer.pointer, | |
149 | (source_desc->buffer.length < | |
150 | 32) ? source_desc->buffer.length : 32); | |
44f6c012 RM |
151 | break; |
152 | ||
153 | case ACPI_TYPE_STRING: | |
154 | ||
4be44fcd LB |
155 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n", |
156 | source_desc->string.length, | |
157 | source_desc->string.pointer)); | |
44f6c012 RM |
158 | break; |
159 | ||
160 | case ACPI_TYPE_PACKAGE: | |
161 | ||
4be44fcd LB |
162 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, |
163 | "[0x%.2X Elements]\n", | |
164 | source_desc->package.count)); | |
44f6c012 RM |
165 | |
166 | /* Output the entire contents of the package */ | |
167 | ||
168 | for (i = 0; i < source_desc->package.count; i++) { | |
4be44fcd LB |
169 | acpi_ex_do_debug_object(source_desc->package. |
170 | elements[i], level + 4, i + 1); | |
44f6c012 RM |
171 | } |
172 | break; | |
173 | ||
174 | case ACPI_TYPE_LOCAL_REFERENCE: | |
175 | ||
176 | if (source_desc->reference.opcode == AML_INDEX_OP) { | |
4be44fcd LB |
177 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, |
178 | "[%s, 0x%X]\n", | |
179 | acpi_ps_get_opcode_name | |
180 | (source_desc->reference.opcode), | |
181 | source_desc->reference.offset)); | |
182 | } else { | |
183 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]\n", | |
184 | acpi_ps_get_opcode_name | |
185 | (source_desc->reference.opcode))); | |
44f6c012 | 186 | } |
44f6c012 RM |
187 | |
188 | if (source_desc->reference.object) { | |
4be44fcd LB |
189 | if (ACPI_GET_DESCRIPTOR_TYPE |
190 | (source_desc->reference.object) == | |
191 | ACPI_DESC_TYPE_NAMED) { | |
192 | acpi_ex_do_debug_object(((struct | |
193 | acpi_namespace_node *) | |
194 | source_desc->reference. | |
195 | object)->object, | |
196 | level + 4, 0); | |
197 | } else { | |
198 | acpi_ex_do_debug_object(source_desc->reference. | |
199 | object, level + 4, 0); | |
44f6c012 | 200 | } |
4be44fcd LB |
201 | } else if (source_desc->reference.node) { |
202 | acpi_ex_do_debug_object((source_desc->reference.node)-> | |
203 | object, level + 4, 0); | |
44f6c012 RM |
204 | } |
205 | break; | |
206 | ||
207 | default: | |
208 | ||
4be44fcd LB |
209 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p %s\n", |
210 | source_desc, | |
211 | acpi_ut_get_object_type_name | |
212 | (source_desc))); | |
44f6c012 RM |
213 | break; |
214 | } | |
215 | ||
4be44fcd | 216 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "\n")); |
44f6c012 RM |
217 | return_VOID; |
218 | } | |
219 | ||
1da177e4 LT |
220 | /******************************************************************************* |
221 | * | |
222 | * FUNCTION: acpi_ex_store | |
223 | * | |
224 | * PARAMETERS: *source_desc - Value to be stored | |
225 | * *dest_desc - Where to store it. Must be an NS node | |
226 | * or an union acpi_operand_object of type | |
227 | * Reference; | |
228 | * walk_state - Current walk state | |
229 | * | |
230 | * RETURN: Status | |
231 | * | |
232 | * DESCRIPTION: Store the value described by source_desc into the location | |
233 | * described by dest_desc. Called by various interpreter | |
234 | * functions to store the result of an operation into | |
235 | * the destination operand -- not just simply the actual "Store" | |
236 | * ASL operator. | |
237 | * | |
238 | ******************************************************************************/ | |
239 | ||
240 | acpi_status | |
4be44fcd LB |
241 | acpi_ex_store(union acpi_operand_object *source_desc, |
242 | union acpi_operand_object *dest_desc, | |
243 | struct acpi_walk_state *walk_state) | |
1da177e4 | 244 | { |
4be44fcd LB |
245 | acpi_status status = AE_OK; |
246 | union acpi_operand_object *ref_desc = dest_desc; | |
1da177e4 | 247 | |
4be44fcd | 248 | ACPI_FUNCTION_TRACE_PTR("ex_store", dest_desc); |
1da177e4 LT |
249 | |
250 | /* Validate parameters */ | |
251 | ||
252 | if (!source_desc || !dest_desc) { | |
b8e4d893 | 253 | ACPI_ERROR((AE_INFO, "Null parameter")); |
4be44fcd | 254 | return_ACPI_STATUS(AE_AML_NO_OPERAND); |
1da177e4 LT |
255 | } |
256 | ||
257 | /* dest_desc can be either a namespace node or an ACPI object */ | |
258 | ||
4be44fcd | 259 | if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) { |
1da177e4 LT |
260 | /* |
261 | * Dest is a namespace node, | |
262 | * Storing an object into a Named node. | |
263 | */ | |
4be44fcd LB |
264 | status = acpi_ex_store_object_to_node(source_desc, |
265 | (struct | |
266 | acpi_namespace_node *) | |
267 | dest_desc, walk_state, | |
268 | ACPI_IMPLICIT_CONVERSION); | |
1da177e4 | 269 | |
4be44fcd | 270 | return_ACPI_STATUS(status); |
1da177e4 LT |
271 | } |
272 | ||
273 | /* Destination object must be a Reference or a Constant object */ | |
274 | ||
4be44fcd | 275 | switch (ACPI_GET_OBJECT_TYPE(dest_desc)) { |
1da177e4 LT |
276 | case ACPI_TYPE_LOCAL_REFERENCE: |
277 | break; | |
278 | ||
279 | case ACPI_TYPE_INTEGER: | |
280 | ||
281 | /* Allow stores to Constants -- a Noop as per ACPI spec */ | |
282 | ||
283 | if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) { | |
4be44fcd | 284 | return_ACPI_STATUS(AE_OK); |
1da177e4 LT |
285 | } |
286 | ||
287 | /*lint -fallthrough */ | |
288 | ||
289 | default: | |
290 | ||
291 | /* Destination is not a Reference object */ | |
292 | ||
b8e4d893 BM |
293 | ACPI_ERROR((AE_INFO, |
294 | "Target is not a Reference or Constant object - %s [%p]", | |
295 | acpi_ut_get_object_type_name(dest_desc), | |
296 | dest_desc)); | |
1da177e4 | 297 | |
4be44fcd LB |
298 | ACPI_DUMP_STACK_ENTRY(source_desc); |
299 | ACPI_DUMP_STACK_ENTRY(dest_desc); | |
300 | ACPI_DUMP_OPERANDS(&dest_desc, ACPI_IMODE_EXECUTE, "ex_store", | |
301 | 2, | |
302 | "Target is not a Reference or Constant object"); | |
1da177e4 | 303 | |
4be44fcd | 304 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
1da177e4 LT |
305 | } |
306 | ||
307 | /* | |
308 | * Examine the Reference opcode. These cases are handled: | |
309 | * | |
310 | * 1) Store to Name (Change the object associated with a name) | |
311 | * 2) Store to an indexed area of a Buffer or Package | |
312 | * 3) Store to a Method Local or Arg | |
313 | * 4) Store to the debug object | |
314 | */ | |
315 | switch (ref_desc->reference.opcode) { | |
316 | case AML_NAME_OP: | |
317 | case AML_REF_OF_OP: | |
318 | ||
319 | /* Storing an object into a Name "container" */ | |
320 | ||
4be44fcd LB |
321 | status = acpi_ex_store_object_to_node(source_desc, |
322 | ref_desc->reference. | |
323 | object, walk_state, | |
324 | ACPI_IMPLICIT_CONVERSION); | |
1da177e4 LT |
325 | break; |
326 | ||
1da177e4 LT |
327 | case AML_INDEX_OP: |
328 | ||
329 | /* Storing to an Index (pointer into a packager or buffer) */ | |
330 | ||
4be44fcd LB |
331 | status = |
332 | acpi_ex_store_object_to_index(source_desc, ref_desc, | |
333 | walk_state); | |
1da177e4 LT |
334 | break; |
335 | ||
1da177e4 LT |
336 | case AML_LOCAL_OP: |
337 | case AML_ARG_OP: | |
338 | ||
339 | /* Store to a method local/arg */ | |
340 | ||
4be44fcd LB |
341 | status = |
342 | acpi_ds_store_object_to_local(ref_desc->reference.opcode, | |
343 | ref_desc->reference.offset, | |
344 | source_desc, walk_state); | |
1da177e4 LT |
345 | break; |
346 | ||
1da177e4 LT |
347 | case AML_DEBUG_OP: |
348 | ||
349 | /* | |
350 | * Storing to the Debug object causes the value stored to be | |
351 | * displayed and otherwise has no effect -- see ACPI Specification | |
352 | */ | |
4be44fcd LB |
353 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
354 | "**** Write to Debug Object: Object %p %s ****:\n\n", | |
355 | source_desc, | |
356 | acpi_ut_get_object_type_name(source_desc))); | |
1da177e4 | 357 | |
4be44fcd | 358 | acpi_ex_do_debug_object(source_desc, 0, 0); |
1da177e4 LT |
359 | break; |
360 | ||
1da177e4 LT |
361 | default: |
362 | ||
b8e4d893 BM |
363 | ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X", |
364 | ref_desc->reference.opcode)); | |
4be44fcd | 365 | ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR); |
1da177e4 LT |
366 | |
367 | status = AE_AML_INTERNAL; | |
368 | break; | |
369 | } | |
370 | ||
4be44fcd | 371 | return_ACPI_STATUS(status); |
1da177e4 LT |
372 | } |
373 | ||
1da177e4 LT |
374 | /******************************************************************************* |
375 | * | |
376 | * FUNCTION: acpi_ex_store_object_to_index | |
377 | * | |
378 | * PARAMETERS: *source_desc - Value to be stored | |
379 | * *dest_desc - Named object to receive the value | |
380 | * walk_state - Current walk state | |
381 | * | |
382 | * RETURN: Status | |
383 | * | |
384 | * DESCRIPTION: Store the object to indexed Buffer or Package element | |
385 | * | |
386 | ******************************************************************************/ | |
387 | ||
44f6c012 | 388 | static acpi_status |
4be44fcd LB |
389 | acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, |
390 | union acpi_operand_object *index_desc, | |
391 | struct acpi_walk_state *walk_state) | |
1da177e4 | 392 | { |
4be44fcd LB |
393 | acpi_status status = AE_OK; |
394 | union acpi_operand_object *obj_desc; | |
395 | union acpi_operand_object *new_desc; | |
396 | u8 value = 0; | |
397 | u32 i; | |
1da177e4 | 398 | |
4be44fcd | 399 | ACPI_FUNCTION_TRACE("ex_store_object_to_index"); |
1da177e4 LT |
400 | |
401 | /* | |
402 | * Destination must be a reference pointer, and | |
403 | * must point to either a buffer or a package | |
404 | */ | |
405 | switch (index_desc->reference.target_type) { | |
406 | case ACPI_TYPE_PACKAGE: | |
407 | /* | |
408 | * Storing to a package element. Copy the object and replace | |
409 | * any existing object with the new object. No implicit | |
410 | * conversion is performed. | |
411 | * | |
412 | * The object at *(index_desc->Reference.Where) is the | |
413 | * element within the package that is to be modified. | |
414 | * The parent package object is at index_desc->Reference.Object | |
415 | */ | |
416 | obj_desc = *(index_desc->reference.where); | |
417 | ||
4be44fcd LB |
418 | status = |
419 | acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, | |
420 | walk_state); | |
421 | if (ACPI_FAILURE(status)) { | |
422 | return_ACPI_STATUS(status); | |
1da177e4 LT |
423 | } |
424 | ||
425 | if (obj_desc) { | |
52fc0b02 | 426 | |
1da177e4 LT |
427 | /* Decrement reference count by the ref count of the parent package */ |
428 | ||
4be44fcd LB |
429 | for (i = 0; i < ((union acpi_operand_object *) |
430 | index_desc->reference.object)->common. | |
431 | reference_count; i++) { | |
432 | acpi_ut_remove_reference(obj_desc); | |
1da177e4 LT |
433 | } |
434 | } | |
435 | ||
436 | *(index_desc->reference.where) = new_desc; | |
437 | ||
44f6c012 | 438 | /* Increment ref count by the ref count of the parent package-1 */ |
1da177e4 | 439 | |
4be44fcd LB |
440 | for (i = 1; i < ((union acpi_operand_object *) |
441 | index_desc->reference.object)->common. | |
442 | reference_count; i++) { | |
443 | acpi_ut_add_reference(new_desc); | |
1da177e4 LT |
444 | } |
445 | ||
446 | break; | |
447 | ||
1da177e4 LT |
448 | case ACPI_TYPE_BUFFER_FIELD: |
449 | ||
450 | /* | |
451 | * Store into a Buffer or String (not actually a real buffer_field) | |
452 | * at a location defined by an Index. | |
453 | * | |
454 | * The first 8-bit element of the source object is written to the | |
455 | * 8-bit Buffer location defined by the Index destination object, | |
456 | * according to the ACPI 2.0 specification. | |
457 | */ | |
458 | ||
459 | /* | |
460 | * Make sure the target is a Buffer or String. An error should | |
461 | * not happen here, since the reference_object was constructed | |
462 | * by the INDEX_OP code. | |
463 | */ | |
464 | obj_desc = index_desc->reference.object; | |
4be44fcd LB |
465 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) && |
466 | (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) { | |
467 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | |
1da177e4 LT |
468 | } |
469 | ||
470 | /* | |
471 | * The assignment of the individual elements will be slightly | |
472 | * different for each source type. | |
473 | */ | |
4be44fcd | 474 | switch (ACPI_GET_OBJECT_TYPE(source_desc)) { |
1da177e4 LT |
475 | case ACPI_TYPE_INTEGER: |
476 | ||
477 | /* Use the least-significant byte of the integer */ | |
478 | ||
479 | value = (u8) (source_desc->integer.value); | |
480 | break; | |
481 | ||
482 | case ACPI_TYPE_BUFFER: | |
483 | case ACPI_TYPE_STRING: | |
484 | ||
485 | /* Note: Takes advantage of common string/buffer fields */ | |
486 | ||
487 | value = source_desc->buffer.pointer[0]; | |
488 | break; | |
489 | ||
490 | default: | |
491 | ||
492 | /* All other types are invalid */ | |
493 | ||
b8e4d893 BM |
494 | ACPI_ERROR((AE_INFO, |
495 | "Source must be Integer/Buffer/String type, not %s", | |
496 | acpi_ut_get_object_type_name(source_desc))); | |
4be44fcd | 497 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
1da177e4 LT |
498 | } |
499 | ||
500 | /* Store the source value into the target buffer byte */ | |
501 | ||
502 | obj_desc->buffer.pointer[index_desc->reference.offset] = value; | |
503 | break; | |
504 | ||
1da177e4 | 505 | default: |
b8e4d893 BM |
506 | ACPI_ERROR((AE_INFO, |
507 | "Target is not a Package or buffer_field")); | |
1da177e4 LT |
508 | status = AE_AML_OPERAND_TYPE; |
509 | break; | |
510 | } | |
511 | ||
4be44fcd | 512 | return_ACPI_STATUS(status); |
1da177e4 LT |
513 | } |
514 | ||
1da177e4 LT |
515 | /******************************************************************************* |
516 | * | |
517 | * FUNCTION: acpi_ex_store_object_to_node | |
518 | * | |
519 | * PARAMETERS: source_desc - Value to be stored | |
520 | * Node - Named object to receive the value | |
521 | * walk_state - Current walk state | |
522 | * implicit_conversion - Perform implicit conversion (yes/no) | |
523 | * | |
524 | * RETURN: Status | |
525 | * | |
526 | * DESCRIPTION: Store the object to the named object. | |
527 | * | |
528 | * The Assignment of an object to a named object is handled here | |
529 | * The value passed in will replace the current value (if any) | |
530 | * with the input value. | |
531 | * | |
532 | * When storing into an object the data is converted to the | |
533 | * target object type then stored in the object. This means | |
534 | * that the target object type (for an initialized target) will | |
535 | * not be changed by a store operation. | |
536 | * | |
537 | * Assumes parameters are already validated. | |
538 | * | |
539 | ******************************************************************************/ | |
540 | ||
541 | acpi_status | |
4be44fcd LB |
542 | acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, |
543 | struct acpi_namespace_node *node, | |
544 | struct acpi_walk_state *walk_state, | |
545 | u8 implicit_conversion) | |
1da177e4 | 546 | { |
4be44fcd LB |
547 | acpi_status status = AE_OK; |
548 | union acpi_operand_object *target_desc; | |
549 | union acpi_operand_object *new_desc; | |
550 | acpi_object_type target_type; | |
1da177e4 | 551 | |
4be44fcd | 552 | ACPI_FUNCTION_TRACE_PTR("ex_store_object_to_node", source_desc); |
1da177e4 | 553 | |
44f6c012 RM |
554 | /* Get current type of the node, and object attached to Node */ |
555 | ||
4be44fcd LB |
556 | target_type = acpi_ns_get_type(node); |
557 | target_desc = acpi_ns_get_attached_object(node); | |
1da177e4 | 558 | |
4be44fcd LB |
559 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n", |
560 | source_desc, | |
561 | acpi_ut_get_object_type_name(source_desc), node, | |
562 | acpi_ut_get_type_name(target_type))); | |
1da177e4 LT |
563 | |
564 | /* | |
565 | * Resolve the source object to an actual value | |
566 | * (If it is a reference object) | |
567 | */ | |
4be44fcd LB |
568 | status = acpi_ex_resolve_object(&source_desc, target_type, walk_state); |
569 | if (ACPI_FAILURE(status)) { | |
570 | return_ACPI_STATUS(status); | |
1da177e4 LT |
571 | } |
572 | ||
573 | /* If no implicit conversion, drop into the default case below */ | |
574 | ||
6f42ccf2 | 575 | if ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) { |
52fc0b02 | 576 | |
1da177e4 LT |
577 | /* Force execution of default (no implicit conversion) */ |
578 | ||
579 | target_type = ACPI_TYPE_ANY; | |
580 | } | |
581 | ||
44f6c012 RM |
582 | /* Do the actual store operation */ |
583 | ||
1da177e4 LT |
584 | switch (target_type) { |
585 | case ACPI_TYPE_BUFFER_FIELD: | |
586 | case ACPI_TYPE_LOCAL_REGION_FIELD: | |
587 | case ACPI_TYPE_LOCAL_BANK_FIELD: | |
588 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | |
589 | ||
44f6c012 RM |
590 | /* For fields, copy the source data to the target field. */ |
591 | ||
4be44fcd LB |
592 | status = acpi_ex_write_data_to_field(source_desc, target_desc, |
593 | &walk_state->result_obj); | |
1da177e4 LT |
594 | break; |
595 | ||
1da177e4 LT |
596 | case ACPI_TYPE_INTEGER: |
597 | case ACPI_TYPE_STRING: | |
598 | case ACPI_TYPE_BUFFER: | |
599 | ||
600 | /* | |
601 | * These target types are all of type Integer/String/Buffer, and | |
602 | * therefore support implicit conversion before the store. | |
603 | * | |
604 | * Copy and/or convert the source object to a new target object | |
605 | */ | |
4be44fcd LB |
606 | status = |
607 | acpi_ex_store_object_to_object(source_desc, target_desc, | |
608 | &new_desc, walk_state); | |
609 | if (ACPI_FAILURE(status)) { | |
610 | return_ACPI_STATUS(status); | |
1da177e4 LT |
611 | } |
612 | ||
613 | if (new_desc != target_desc) { | |
614 | /* | |
615 | * Store the new new_desc as the new value of the Name, and set | |
616 | * the Name's type to that of the value being stored in it. | |
617 | * source_desc reference count is incremented by attach_object. | |
618 | * | |
619 | * Note: This may change the type of the node if an explicit store | |
620 | * has been performed such that the node/object type has been | |
621 | * changed. | |
622 | */ | |
4be44fcd LB |
623 | status = |
624 | acpi_ns_attach_object(node, new_desc, | |
625 | new_desc->common.type); | |
626 | ||
627 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | |
628 | "Store %s into %s via Convert/Attach\n", | |
629 | acpi_ut_get_object_type_name | |
630 | (source_desc), | |
631 | acpi_ut_get_object_type_name | |
632 | (new_desc))); | |
1da177e4 LT |
633 | } |
634 | break; | |
635 | ||
1da177e4 LT |
636 | default: |
637 | ||
4be44fcd LB |
638 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
639 | "Storing %s (%p) directly into node (%p) with no implicit conversion\n", | |
640 | acpi_ut_get_object_type_name(source_desc), | |
641 | source_desc, node)); | |
1da177e4 LT |
642 | |
643 | /* No conversions for all other types. Just attach the source object */ | |
644 | ||
4be44fcd LB |
645 | status = acpi_ns_attach_object(node, source_desc, |
646 | ACPI_GET_OBJECT_TYPE | |
647 | (source_desc)); | |
1da177e4 LT |
648 | break; |
649 | } | |
650 | ||
4be44fcd | 651 | return_ACPI_STATUS(status); |
1da177e4 | 652 | } |