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) { | |
4a90c7e8 | 253 | ACPI_REPORT_ERROR(("Null parameter\n")); |
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 | ||
4a90c7e8 | 293 | ACPI_REPORT_ERROR(("Target is not a Reference or Constant object - %s [%p]\n", acpi_ut_get_object_type_name(dest_desc), dest_desc)); |
1da177e4 | 294 | |
4be44fcd LB |
295 | ACPI_DUMP_STACK_ENTRY(source_desc); |
296 | ACPI_DUMP_STACK_ENTRY(dest_desc); | |
297 | ACPI_DUMP_OPERANDS(&dest_desc, ACPI_IMODE_EXECUTE, "ex_store", | |
298 | 2, | |
299 | "Target is not a Reference or Constant object"); | |
1da177e4 | 300 | |
4be44fcd | 301 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
1da177e4 LT |
302 | } |
303 | ||
304 | /* | |
305 | * Examine the Reference opcode. These cases are handled: | |
306 | * | |
307 | * 1) Store to Name (Change the object associated with a name) | |
308 | * 2) Store to an indexed area of a Buffer or Package | |
309 | * 3) Store to a Method Local or Arg | |
310 | * 4) Store to the debug object | |
311 | */ | |
312 | switch (ref_desc->reference.opcode) { | |
313 | case AML_NAME_OP: | |
314 | case AML_REF_OF_OP: | |
315 | ||
316 | /* Storing an object into a Name "container" */ | |
317 | ||
4be44fcd LB |
318 | status = acpi_ex_store_object_to_node(source_desc, |
319 | ref_desc->reference. | |
320 | object, walk_state, | |
321 | ACPI_IMPLICIT_CONVERSION); | |
1da177e4 LT |
322 | break; |
323 | ||
1da177e4 LT |
324 | case AML_INDEX_OP: |
325 | ||
326 | /* Storing to an Index (pointer into a packager or buffer) */ | |
327 | ||
4be44fcd LB |
328 | status = |
329 | acpi_ex_store_object_to_index(source_desc, ref_desc, | |
330 | walk_state); | |
1da177e4 LT |
331 | break; |
332 | ||
1da177e4 LT |
333 | case AML_LOCAL_OP: |
334 | case AML_ARG_OP: | |
335 | ||
336 | /* Store to a method local/arg */ | |
337 | ||
4be44fcd LB |
338 | status = |
339 | acpi_ds_store_object_to_local(ref_desc->reference.opcode, | |
340 | ref_desc->reference.offset, | |
341 | source_desc, walk_state); | |
1da177e4 LT |
342 | break; |
343 | ||
1da177e4 LT |
344 | case AML_DEBUG_OP: |
345 | ||
346 | /* | |
347 | * Storing to the Debug object causes the value stored to be | |
348 | * displayed and otherwise has no effect -- see ACPI Specification | |
349 | */ | |
4be44fcd LB |
350 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
351 | "**** Write to Debug Object: Object %p %s ****:\n\n", | |
352 | source_desc, | |
353 | acpi_ut_get_object_type_name(source_desc))); | |
1da177e4 | 354 | |
4be44fcd | 355 | acpi_ex_do_debug_object(source_desc, 0, 0); |
1da177e4 LT |
356 | break; |
357 | ||
1da177e4 LT |
358 | default: |
359 | ||
4a90c7e8 | 360 | ACPI_REPORT_ERROR(("Unknown Reference opcode %X\n", |
4be44fcd LB |
361 | ref_desc->reference.opcode)); |
362 | ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR); | |
1da177e4 LT |
363 | |
364 | status = AE_AML_INTERNAL; | |
365 | break; | |
366 | } | |
367 | ||
4be44fcd | 368 | return_ACPI_STATUS(status); |
1da177e4 LT |
369 | } |
370 | ||
1da177e4 LT |
371 | /******************************************************************************* |
372 | * | |
373 | * FUNCTION: acpi_ex_store_object_to_index | |
374 | * | |
375 | * PARAMETERS: *source_desc - Value to be stored | |
376 | * *dest_desc - Named object to receive the value | |
377 | * walk_state - Current walk state | |
378 | * | |
379 | * RETURN: Status | |
380 | * | |
381 | * DESCRIPTION: Store the object to indexed Buffer or Package element | |
382 | * | |
383 | ******************************************************************************/ | |
384 | ||
44f6c012 | 385 | static acpi_status |
4be44fcd LB |
386 | acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, |
387 | union acpi_operand_object *index_desc, | |
388 | struct acpi_walk_state *walk_state) | |
1da177e4 | 389 | { |
4be44fcd LB |
390 | acpi_status status = AE_OK; |
391 | union acpi_operand_object *obj_desc; | |
392 | union acpi_operand_object *new_desc; | |
393 | u8 value = 0; | |
394 | u32 i; | |
1da177e4 | 395 | |
4be44fcd | 396 | ACPI_FUNCTION_TRACE("ex_store_object_to_index"); |
1da177e4 LT |
397 | |
398 | /* | |
399 | * Destination must be a reference pointer, and | |
400 | * must point to either a buffer or a package | |
401 | */ | |
402 | switch (index_desc->reference.target_type) { | |
403 | case ACPI_TYPE_PACKAGE: | |
404 | /* | |
405 | * Storing to a package element. Copy the object and replace | |
406 | * any existing object with the new object. No implicit | |
407 | * conversion is performed. | |
408 | * | |
409 | * The object at *(index_desc->Reference.Where) is the | |
410 | * element within the package that is to be modified. | |
411 | * The parent package object is at index_desc->Reference.Object | |
412 | */ | |
413 | obj_desc = *(index_desc->reference.where); | |
414 | ||
4be44fcd LB |
415 | status = |
416 | acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, | |
417 | walk_state); | |
418 | if (ACPI_FAILURE(status)) { | |
419 | return_ACPI_STATUS(status); | |
1da177e4 LT |
420 | } |
421 | ||
422 | if (obj_desc) { | |
423 | /* Decrement reference count by the ref count of the parent package */ | |
424 | ||
4be44fcd LB |
425 | for (i = 0; i < ((union acpi_operand_object *) |
426 | index_desc->reference.object)->common. | |
427 | reference_count; i++) { | |
428 | acpi_ut_remove_reference(obj_desc); | |
1da177e4 LT |
429 | } |
430 | } | |
431 | ||
432 | *(index_desc->reference.where) = new_desc; | |
433 | ||
44f6c012 | 434 | /* Increment ref count by the ref count of the parent package-1 */ |
1da177e4 | 435 | |
4be44fcd LB |
436 | for (i = 1; i < ((union acpi_operand_object *) |
437 | index_desc->reference.object)->common. | |
438 | reference_count; i++) { | |
439 | acpi_ut_add_reference(new_desc); | |
1da177e4 LT |
440 | } |
441 | ||
442 | break; | |
443 | ||
1da177e4 LT |
444 | case ACPI_TYPE_BUFFER_FIELD: |
445 | ||
446 | /* | |
447 | * Store into a Buffer or String (not actually a real buffer_field) | |
448 | * at a location defined by an Index. | |
449 | * | |
450 | * The first 8-bit element of the source object is written to the | |
451 | * 8-bit Buffer location defined by the Index destination object, | |
452 | * according to the ACPI 2.0 specification. | |
453 | */ | |
454 | ||
455 | /* | |
456 | * Make sure the target is a Buffer or String. An error should | |
457 | * not happen here, since the reference_object was constructed | |
458 | * by the INDEX_OP code. | |
459 | */ | |
460 | obj_desc = index_desc->reference.object; | |
4be44fcd LB |
461 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) && |
462 | (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) { | |
463 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | |
1da177e4 LT |
464 | } |
465 | ||
466 | /* | |
467 | * The assignment of the individual elements will be slightly | |
468 | * different for each source type. | |
469 | */ | |
4be44fcd | 470 | switch (ACPI_GET_OBJECT_TYPE(source_desc)) { |
1da177e4 LT |
471 | case ACPI_TYPE_INTEGER: |
472 | ||
473 | /* Use the least-significant byte of the integer */ | |
474 | ||
475 | value = (u8) (source_desc->integer.value); | |
476 | break; | |
477 | ||
478 | case ACPI_TYPE_BUFFER: | |
479 | case ACPI_TYPE_STRING: | |
480 | ||
481 | /* Note: Takes advantage of common string/buffer fields */ | |
482 | ||
483 | value = source_desc->buffer.pointer[0]; | |
484 | break; | |
485 | ||
486 | default: | |
487 | ||
488 | /* All other types are invalid */ | |
489 | ||
4a90c7e8 | 490 | ACPI_REPORT_ERROR(("Source must be Integer/Buffer/String type, not %s\n", acpi_ut_get_object_type_name(source_desc))); |
4be44fcd | 491 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
1da177e4 LT |
492 | } |
493 | ||
494 | /* Store the source value into the target buffer byte */ | |
495 | ||
496 | obj_desc->buffer.pointer[index_desc->reference.offset] = value; | |
497 | break; | |
498 | ||
1da177e4 | 499 | default: |
4a90c7e8 | 500 | ACPI_REPORT_ERROR(("Target is not a Package or buffer_field\n")); |
1da177e4 LT |
501 | status = AE_AML_OPERAND_TYPE; |
502 | break; | |
503 | } | |
504 | ||
4be44fcd | 505 | return_ACPI_STATUS(status); |
1da177e4 LT |
506 | } |
507 | ||
1da177e4 LT |
508 | /******************************************************************************* |
509 | * | |
510 | * FUNCTION: acpi_ex_store_object_to_node | |
511 | * | |
512 | * PARAMETERS: source_desc - Value to be stored | |
513 | * Node - Named object to receive the value | |
514 | * walk_state - Current walk state | |
515 | * implicit_conversion - Perform implicit conversion (yes/no) | |
516 | * | |
517 | * RETURN: Status | |
518 | * | |
519 | * DESCRIPTION: Store the object to the named object. | |
520 | * | |
521 | * The Assignment of an object to a named object is handled here | |
522 | * The value passed in will replace the current value (if any) | |
523 | * with the input value. | |
524 | * | |
525 | * When storing into an object the data is converted to the | |
526 | * target object type then stored in the object. This means | |
527 | * that the target object type (for an initialized target) will | |
528 | * not be changed by a store operation. | |
529 | * | |
530 | * Assumes parameters are already validated. | |
531 | * | |
532 | ******************************************************************************/ | |
533 | ||
534 | acpi_status | |
4be44fcd LB |
535 | acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, |
536 | struct acpi_namespace_node *node, | |
537 | struct acpi_walk_state *walk_state, | |
538 | u8 implicit_conversion) | |
1da177e4 | 539 | { |
4be44fcd LB |
540 | acpi_status status = AE_OK; |
541 | union acpi_operand_object *target_desc; | |
542 | union acpi_operand_object *new_desc; | |
543 | acpi_object_type target_type; | |
1da177e4 | 544 | |
4be44fcd | 545 | ACPI_FUNCTION_TRACE_PTR("ex_store_object_to_node", source_desc); |
1da177e4 | 546 | |
44f6c012 RM |
547 | /* Get current type of the node, and object attached to Node */ |
548 | ||
4be44fcd LB |
549 | target_type = acpi_ns_get_type(node); |
550 | target_desc = acpi_ns_get_attached_object(node); | |
1da177e4 | 551 | |
4be44fcd LB |
552 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n", |
553 | source_desc, | |
554 | acpi_ut_get_object_type_name(source_desc), node, | |
555 | acpi_ut_get_type_name(target_type))); | |
1da177e4 LT |
556 | |
557 | /* | |
558 | * Resolve the source object to an actual value | |
559 | * (If it is a reference object) | |
560 | */ | |
4be44fcd LB |
561 | status = acpi_ex_resolve_object(&source_desc, target_type, walk_state); |
562 | if (ACPI_FAILURE(status)) { | |
563 | return_ACPI_STATUS(status); | |
1da177e4 LT |
564 | } |
565 | ||
566 | /* If no implicit conversion, drop into the default case below */ | |
567 | ||
6f42ccf2 | 568 | if ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) { |
1da177e4 LT |
569 | /* Force execution of default (no implicit conversion) */ |
570 | ||
571 | target_type = ACPI_TYPE_ANY; | |
572 | } | |
573 | ||
44f6c012 RM |
574 | /* Do the actual store operation */ |
575 | ||
1da177e4 LT |
576 | switch (target_type) { |
577 | case ACPI_TYPE_BUFFER_FIELD: | |
578 | case ACPI_TYPE_LOCAL_REGION_FIELD: | |
579 | case ACPI_TYPE_LOCAL_BANK_FIELD: | |
580 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | |
581 | ||
44f6c012 RM |
582 | /* For fields, copy the source data to the target field. */ |
583 | ||
4be44fcd LB |
584 | status = acpi_ex_write_data_to_field(source_desc, target_desc, |
585 | &walk_state->result_obj); | |
1da177e4 LT |
586 | break; |
587 | ||
1da177e4 LT |
588 | case ACPI_TYPE_INTEGER: |
589 | case ACPI_TYPE_STRING: | |
590 | case ACPI_TYPE_BUFFER: | |
591 | ||
592 | /* | |
593 | * These target types are all of type Integer/String/Buffer, and | |
594 | * therefore support implicit conversion before the store. | |
595 | * | |
596 | * Copy and/or convert the source object to a new target object | |
597 | */ | |
4be44fcd LB |
598 | status = |
599 | acpi_ex_store_object_to_object(source_desc, target_desc, | |
600 | &new_desc, walk_state); | |
601 | if (ACPI_FAILURE(status)) { | |
602 | return_ACPI_STATUS(status); | |
1da177e4 LT |
603 | } |
604 | ||
605 | if (new_desc != target_desc) { | |
606 | /* | |
607 | * Store the new new_desc as the new value of the Name, and set | |
608 | * the Name's type to that of the value being stored in it. | |
609 | * source_desc reference count is incremented by attach_object. | |
610 | * | |
611 | * Note: This may change the type of the node if an explicit store | |
612 | * has been performed such that the node/object type has been | |
613 | * changed. | |
614 | */ | |
4be44fcd LB |
615 | status = |
616 | acpi_ns_attach_object(node, new_desc, | |
617 | new_desc->common.type); | |
618 | ||
619 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | |
620 | "Store %s into %s via Convert/Attach\n", | |
621 | acpi_ut_get_object_type_name | |
622 | (source_desc), | |
623 | acpi_ut_get_object_type_name | |
624 | (new_desc))); | |
1da177e4 LT |
625 | } |
626 | break; | |
627 | ||
1da177e4 LT |
628 | default: |
629 | ||
4be44fcd LB |
630 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
631 | "Storing %s (%p) directly into node (%p) with no implicit conversion\n", | |
632 | acpi_ut_get_object_type_name(source_desc), | |
633 | source_desc, node)); | |
1da177e4 LT |
634 | |
635 | /* No conversions for all other types. Just attach the source object */ | |
636 | ||
4be44fcd LB |
637 | status = acpi_ns_attach_object(node, source_desc, |
638 | ACPI_GET_OBJECT_TYPE | |
639 | (source_desc)); | |
1da177e4 LT |
640 | break; |
641 | } | |
642 | ||
4be44fcd | 643 | return_ACPI_STATUS(status); |
1da177e4 | 644 | } |