blob: 912889ed45ed29295c9ca2564593b4078841cdec [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001
2/******************************************************************************
3 *
4 * Module Name: exstore - AML Interpreter object store support
5 *
6 *****************************************************************************/
7
8/*
Bob Moore6c9deb72007-02-02 19:48:24 +03009 * Copyright (C) 2000 - 2007, R. Byron Moore
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 * 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <acpi/acpi.h>
46#include <acpi/acdispat.h>
47#include <acpi/acinterp.h>
48#include <acpi/amlcode.h>
49#include <acpi/acnamesp.h>
Robert Moore44f6c012005-04-18 22:49:35 -040050#include <acpi/acparser.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#define _COMPONENT ACPI_EXECUTER
Len Brown4be44fc2005-08-05 00:44:28 -040053ACPI_MODULE_NAME("exstore")
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Robert Moore44f6c012005-04-18 22:49:35 -040055/* Local prototypes */
Robert Moore44f6c012005-04-18 22:49:35 -040056static void
Len Brown4be44fc2005-08-05 00:44:28 -040057acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
58 u32 level, u32 index);
Robert Moore44f6c012005-04-18 22:49:35 -040059
60static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -040061acpi_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);
Robert Moore44f6c012005-04-18 22:49:35 -040064
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
79static void
Len Brown4be44fc2005-08-05 00:44:28 -040080acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
81 u32 level, u32 index)
Robert Moore44f6c012005-04-18 22:49:35 -040082{
Len Brown4be44fc2005-08-05 00:44:28 -040083 u32 i;
Robert Moore44f6c012005-04-18 22:49:35 -040084
Bob Mooreb229cf92006-04-21 17:15:00 -040085 ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);
Robert Moore44f6c012005-04-18 22:49:35 -040086
Len Brown4be44fc2005-08-05 00:44:28 -040087 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
88 level, " "));
Robert Moore44f6c012005-04-18 22:49:35 -040089
90 /* Display index for package output only */
91
92 if (index > 0) {
Len Brown4be44fc2005-08-05 00:44:28 -040093 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
94 "(%.2u) ", index - 1));
Robert Moore44f6c012005-04-18 22:49:35 -040095 }
96
97 if (!source_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -040098 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n"));
Robert Moore44f6c012005-04-18 22:49:35 -040099 return_VOID;
100 }
101
Len Brown4be44fc2005-08-05 00:44:28 -0400102 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)));
Robert Moore44f6c012005-04-18 22:49:35 -0400106
Len Brown4be44fc2005-08-05 00:44:28 -0400107 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;
Robert Moore44f6c012005-04-18 22:49:35 -0400112 }
Len Brown4be44fc2005-08-05 00:44:28 -0400113 } 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));
Robert Moore44f6c012005-04-18 22:49:35 -0400121 return_VOID;
Len Brown4be44fc2005-08-05 00:44:28 -0400122 } else {
Robert Moore44f6c012005-04-18 22:49:35 -0400123 return_VOID;
124 }
125
Bob Moore61ce4212008-04-10 19:06:39 +0400126 /* source_desc is of type ACPI_DESC_TYPE_OPERAND */
127
Len Brown4be44fc2005-08-05 00:44:28 -0400128 switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
Robert Moore44f6c012005-04-18 22:49:35 -0400129 case ACPI_TYPE_INTEGER:
130
131 /* Output correct integer width */
132
133 if (acpi_gbl_integer_byte_width == 4) {
Len Brown4be44fc2005-08-05 00:44:28 -0400134 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
135 (u32) source_desc->integer.
136 value));
137 } else {
138 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
139 "0x%8.8X%8.8X\n",
140 ACPI_FORMAT_UINT64(source_desc->
141 integer.
142 value)));
Robert Moore44f6c012005-04-18 22:49:35 -0400143 }
144 break;
145
146 case ACPI_TYPE_BUFFER:
147
Len Brown4be44fc2005-08-05 00:44:28 -0400148 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]\n",
149 (u32) source_desc->buffer.length));
150 ACPI_DUMP_BUFFER(source_desc->buffer.pointer,
151 (source_desc->buffer.length <
Bob Moore422f4f92008-04-10 19:06:37 +0400152 256) ? source_desc->buffer.length : 256);
Robert Moore44f6c012005-04-18 22:49:35 -0400153 break;
154
155 case ACPI_TYPE_STRING:
156
Len Brown4be44fc2005-08-05 00:44:28 -0400157 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
158 source_desc->string.length,
159 source_desc->string.pointer));
Robert Moore44f6c012005-04-18 22:49:35 -0400160 break;
161
162 case ACPI_TYPE_PACKAGE:
163
Len Brown4be44fc2005-08-05 00:44:28 -0400164 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
165 "[0x%.2X Elements]\n",
166 source_desc->package.count));
Robert Moore44f6c012005-04-18 22:49:35 -0400167
168 /* Output the entire contents of the package */
169
170 for (i = 0; i < source_desc->package.count; i++) {
Len Brown4be44fc2005-08-05 00:44:28 -0400171 acpi_ex_do_debug_object(source_desc->package.
172 elements[i], level + 4, i + 1);
Robert Moore44f6c012005-04-18 22:49:35 -0400173 }
174 break;
175
176 case ACPI_TYPE_LOCAL_REFERENCE:
177
178 if (source_desc->reference.opcode == AML_INDEX_OP) {
Len Brown4be44fc2005-08-05 00:44:28 -0400179 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
180 "[%s, 0x%X]\n",
181 acpi_ps_get_opcode_name
182 (source_desc->reference.opcode),
183 source_desc->reference.offset));
184 } else {
Bob Moore61ce4212008-04-10 19:06:39 +0400185 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]",
Len Brown4be44fc2005-08-05 00:44:28 -0400186 acpi_ps_get_opcode_name
187 (source_desc->reference.opcode)));
Robert Moore44f6c012005-04-18 22:49:35 -0400188 }
Robert Moore44f6c012005-04-18 22:49:35 -0400189
Bob Moore61ce4212008-04-10 19:06:39 +0400190 if (source_desc->reference.opcode == AML_LOAD_OP) { /* Load and load_table */
191 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
192 " Table OwnerId %X\n",
193 source_desc->reference.object));
194 break;
195 }
196
197 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "\n"));
Robert Moore44f6c012005-04-18 22:49:35 -0400198 if (source_desc->reference.object) {
Len Brown4be44fc2005-08-05 00:44:28 -0400199 if (ACPI_GET_DESCRIPTOR_TYPE
200 (source_desc->reference.object) ==
201 ACPI_DESC_TYPE_NAMED) {
202 acpi_ex_do_debug_object(((struct
203 acpi_namespace_node *)
204 source_desc->reference.
205 object)->object,
206 level + 4, 0);
207 } else {
208 acpi_ex_do_debug_object(source_desc->reference.
209 object, level + 4, 0);
Robert Moore44f6c012005-04-18 22:49:35 -0400210 }
Len Brown4be44fc2005-08-05 00:44:28 -0400211 } else if (source_desc->reference.node) {
212 acpi_ex_do_debug_object((source_desc->reference.node)->
213 object, level + 4, 0);
Robert Moore44f6c012005-04-18 22:49:35 -0400214 }
215 break;
216
217 default:
218
Len Brown4be44fc2005-08-05 00:44:28 -0400219 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p %s\n",
220 source_desc,
221 acpi_ut_get_object_type_name
222 (source_desc)));
Robert Moore44f6c012005-04-18 22:49:35 -0400223 break;
224 }
225
Len Brown4be44fc2005-08-05 00:44:28 -0400226 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "\n"));
Robert Moore44f6c012005-04-18 22:49:35 -0400227 return_VOID;
228}
229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230/*******************************************************************************
231 *
232 * FUNCTION: acpi_ex_store
233 *
234 * PARAMETERS: *source_desc - Value to be stored
235 * *dest_desc - Where to store it. Must be an NS node
236 * or an union acpi_operand_object of type
237 * Reference;
238 * walk_state - Current walk state
239 *
240 * RETURN: Status
241 *
242 * DESCRIPTION: Store the value described by source_desc into the location
243 * described by dest_desc. Called by various interpreter
244 * functions to store the result of an operation into
245 * the destination operand -- not just simply the actual "Store"
246 * ASL operator.
247 *
248 ******************************************************************************/
249
250acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400251acpi_ex_store(union acpi_operand_object *source_desc,
252 union acpi_operand_object *dest_desc,
253 struct acpi_walk_state *walk_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254{
Len Brown4be44fc2005-08-05 00:44:28 -0400255 acpi_status status = AE_OK;
256 union acpi_operand_object *ref_desc = dest_desc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257
Bob Mooreb229cf92006-04-21 17:15:00 -0400258 ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
260 /* Validate parameters */
261
262 if (!source_desc || !dest_desc) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500263 ACPI_ERROR((AE_INFO, "Null parameter"));
Len Brown4be44fc2005-08-05 00:44:28 -0400264 return_ACPI_STATUS(AE_AML_NO_OPERAND);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 }
266
267 /* dest_desc can be either a namespace node or an ACPI object */
268
Len Brown4be44fc2005-08-05 00:44:28 -0400269 if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 /*
271 * Dest is a namespace node,
272 * Storing an object into a Named node.
273 */
Len Brown4be44fc2005-08-05 00:44:28 -0400274 status = acpi_ex_store_object_to_node(source_desc,
275 (struct
276 acpi_namespace_node *)
277 dest_desc, walk_state,
278 ACPI_IMPLICIT_CONVERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279
Len Brown4be44fc2005-08-05 00:44:28 -0400280 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 }
282
283 /* Destination object must be a Reference or a Constant object */
284
Len Brown4be44fc2005-08-05 00:44:28 -0400285 switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 case ACPI_TYPE_LOCAL_REFERENCE:
287 break;
288
289 case ACPI_TYPE_INTEGER:
290
291 /* Allow stores to Constants -- a Noop as per ACPI spec */
292
293 if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
Len Brown4be44fc2005-08-05 00:44:28 -0400294 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 }
296
297 /*lint -fallthrough */
298
299 default:
300
301 /* Destination is not a Reference object */
302
Bob Mooreb8e4d892006-01-27 16:43:00 -0500303 ACPI_ERROR((AE_INFO,
304 "Target is not a Reference or Constant object - %s [%p]",
305 acpi_ut_get_object_type_name(dest_desc),
306 dest_desc));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307
Len Brown4be44fc2005-08-05 00:44:28 -0400308 ACPI_DUMP_STACK_ENTRY(source_desc);
309 ACPI_DUMP_STACK_ENTRY(dest_desc);
Bob Mooreb229cf92006-04-21 17:15:00 -0400310 ACPI_DUMP_OPERANDS(&dest_desc, ACPI_IMODE_EXECUTE, "ExStore",
Len Brown4be44fc2005-08-05 00:44:28 -0400311 2,
312 "Target is not a Reference or Constant object");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313
Len Brown4be44fc2005-08-05 00:44:28 -0400314 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 }
316
317 /*
318 * Examine the Reference opcode. These cases are handled:
319 *
320 * 1) Store to Name (Change the object associated with a name)
321 * 2) Store to an indexed area of a Buffer or Package
322 * 3) Store to a Method Local or Arg
323 * 4) Store to the debug object
324 */
325 switch (ref_desc->reference.opcode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 case AML_REF_OF_OP:
327
328 /* Storing an object into a Name "container" */
329
Len Brown4be44fc2005-08-05 00:44:28 -0400330 status = acpi_ex_store_object_to_node(source_desc,
331 ref_desc->reference.
332 object, walk_state,
333 ACPI_IMPLICIT_CONVERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 break;
335
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 case AML_INDEX_OP:
337
338 /* Storing to an Index (pointer into a packager or buffer) */
339
Len Brown4be44fc2005-08-05 00:44:28 -0400340 status =
341 acpi_ex_store_object_to_index(source_desc, ref_desc,
342 walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 break;
344
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 case AML_LOCAL_OP:
346 case AML_ARG_OP:
347
348 /* Store to a method local/arg */
349
Len Brown4be44fc2005-08-05 00:44:28 -0400350 status =
351 acpi_ds_store_object_to_local(ref_desc->reference.opcode,
352 ref_desc->reference.offset,
353 source_desc, walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 break;
355
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 case AML_DEBUG_OP:
357
358 /*
359 * Storing to the Debug object causes the value stored to be
360 * displayed and otherwise has no effect -- see ACPI Specification
361 */
Len Brown4be44fc2005-08-05 00:44:28 -0400362 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
363 "**** Write to Debug Object: Object %p %s ****:\n\n",
364 source_desc,
365 acpi_ut_get_object_type_name(source_desc)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366
Len Brown4be44fc2005-08-05 00:44:28 -0400367 acpi_ex_do_debug_object(source_desc, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 break;
369
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 default:
371
Bob Mooreb8e4d892006-01-27 16:43:00 -0500372 ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X",
373 ref_desc->reference.opcode));
Len Brown4be44fc2005-08-05 00:44:28 -0400374 ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
376 status = AE_AML_INTERNAL;
377 break;
378 }
379
Len Brown4be44fc2005-08-05 00:44:28 -0400380 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381}
382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383/*******************************************************************************
384 *
385 * FUNCTION: acpi_ex_store_object_to_index
386 *
387 * PARAMETERS: *source_desc - Value to be stored
388 * *dest_desc - Named object to receive the value
389 * walk_state - Current walk state
390 *
391 * RETURN: Status
392 *
393 * DESCRIPTION: Store the object to indexed Buffer or Package element
394 *
395 ******************************************************************************/
396
Robert Moore44f6c012005-04-18 22:49:35 -0400397static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400398acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
399 union acpi_operand_object *index_desc,
400 struct acpi_walk_state *walk_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401{
Len Brown4be44fc2005-08-05 00:44:28 -0400402 acpi_status status = AE_OK;
403 union acpi_operand_object *obj_desc;
404 union acpi_operand_object *new_desc;
405 u8 value = 0;
406 u32 i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Bob Mooreb229cf92006-04-21 17:15:00 -0400408 ACPI_FUNCTION_TRACE(ex_store_object_to_index);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
410 /*
411 * Destination must be a reference pointer, and
412 * must point to either a buffer or a package
413 */
414 switch (index_desc->reference.target_type) {
415 case ACPI_TYPE_PACKAGE:
416 /*
417 * Storing to a package element. Copy the object and replace
418 * any existing object with the new object. No implicit
419 * conversion is performed.
420 *
421 * The object at *(index_desc->Reference.Where) is the
422 * element within the package that is to be modified.
423 * The parent package object is at index_desc->Reference.Object
424 */
425 obj_desc = *(index_desc->reference.where);
426
Len Brown4be44fc2005-08-05 00:44:28 -0400427 status =
428 acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc,
429 walk_state);
430 if (ACPI_FAILURE(status)) {
431 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 }
433
434 if (obj_desc) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400435
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 /* Decrement reference count by the ref count of the parent package */
437
Len Brown4be44fc2005-08-05 00:44:28 -0400438 for (i = 0; i < ((union acpi_operand_object *)
439 index_desc->reference.object)->common.
440 reference_count; i++) {
441 acpi_ut_remove_reference(obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 }
443 }
444
445 *(index_desc->reference.where) = new_desc;
446
Robert Moore44f6c012005-04-18 22:49:35 -0400447 /* Increment ref count by the ref count of the parent package-1 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448
Len Brown4be44fc2005-08-05 00:44:28 -0400449 for (i = 1; i < ((union acpi_operand_object *)
450 index_desc->reference.object)->common.
451 reference_count; i++) {
452 acpi_ut_add_reference(new_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 }
454
455 break;
456
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 case ACPI_TYPE_BUFFER_FIELD:
458
459 /*
460 * Store into a Buffer or String (not actually a real buffer_field)
461 * at a location defined by an Index.
462 *
463 * The first 8-bit element of the source object is written to the
464 * 8-bit Buffer location defined by the Index destination object,
465 * according to the ACPI 2.0 specification.
466 */
467
468 /*
469 * Make sure the target is a Buffer or String. An error should
470 * not happen here, since the reference_object was constructed
471 * by the INDEX_OP code.
472 */
473 obj_desc = index_desc->reference.object;
Len Brown4be44fc2005-08-05 00:44:28 -0400474 if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) &&
475 (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) {
476 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 }
478
479 /*
480 * The assignment of the individual elements will be slightly
481 * different for each source type.
482 */
Len Brown4be44fc2005-08-05 00:44:28 -0400483 switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 case ACPI_TYPE_INTEGER:
485
486 /* Use the least-significant byte of the integer */
487
488 value = (u8) (source_desc->integer.value);
489 break;
490
491 case ACPI_TYPE_BUFFER:
492 case ACPI_TYPE_STRING:
493
494 /* Note: Takes advantage of common string/buffer fields */
495
496 value = source_desc->buffer.pointer[0];
497 break;
498
499 default:
500
501 /* All other types are invalid */
502
Bob Mooreb8e4d892006-01-27 16:43:00 -0500503 ACPI_ERROR((AE_INFO,
504 "Source must be Integer/Buffer/String type, not %s",
505 acpi_ut_get_object_type_name(source_desc)));
Len Brown4be44fc2005-08-05 00:44:28 -0400506 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 }
508
509 /* Store the source value into the target buffer byte */
510
511 obj_desc->buffer.pointer[index_desc->reference.offset] = value;
512 break;
513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 default:
Bob Mooreb229cf92006-04-21 17:15:00 -0400515 ACPI_ERROR((AE_INFO, "Target is not a Package or BufferField"));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 status = AE_AML_OPERAND_TYPE;
517 break;
518 }
519
Len Brown4be44fc2005-08-05 00:44:28 -0400520 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521}
522
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523/*******************************************************************************
524 *
525 * FUNCTION: acpi_ex_store_object_to_node
526 *
527 * PARAMETERS: source_desc - Value to be stored
528 * Node - Named object to receive the value
529 * walk_state - Current walk state
530 * implicit_conversion - Perform implicit conversion (yes/no)
531 *
532 * RETURN: Status
533 *
534 * DESCRIPTION: Store the object to the named object.
535 *
536 * The Assignment of an object to a named object is handled here
537 * The value passed in will replace the current value (if any)
538 * with the input value.
539 *
540 * When storing into an object the data is converted to the
541 * target object type then stored in the object. This means
542 * that the target object type (for an initialized target) will
543 * not be changed by a store operation.
544 *
545 * Assumes parameters are already validated.
546 *
547 ******************************************************************************/
548
549acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400550acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
551 struct acpi_namespace_node *node,
552 struct acpi_walk_state *walk_state,
553 u8 implicit_conversion)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554{
Len Brown4be44fc2005-08-05 00:44:28 -0400555 acpi_status status = AE_OK;
556 union acpi_operand_object *target_desc;
557 union acpi_operand_object *new_desc;
558 acpi_object_type target_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559
Bob Mooreb229cf92006-04-21 17:15:00 -0400560 ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
Robert Moore44f6c012005-04-18 22:49:35 -0400562 /* Get current type of the node, and object attached to Node */
563
Len Brown4be44fc2005-08-05 00:44:28 -0400564 target_type = acpi_ns_get_type(node);
565 target_desc = acpi_ns_get_attached_object(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
Len Brown4be44fc2005-08-05 00:44:28 -0400567 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
568 source_desc,
569 acpi_ut_get_object_type_name(source_desc), node,
570 acpi_ut_get_type_name(target_type)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
572 /*
573 * Resolve the source object to an actual value
574 * (If it is a reference object)
575 */
Len Brown4be44fc2005-08-05 00:44:28 -0400576 status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
577 if (ACPI_FAILURE(status)) {
578 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 }
580
581 /* If no implicit conversion, drop into the default case below */
582
Robert Moore6f42ccf2005-05-13 00:00:00 -0400583 if ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400584
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 /* Force execution of default (no implicit conversion) */
586
587 target_type = ACPI_TYPE_ANY;
588 }
589
Robert Moore44f6c012005-04-18 22:49:35 -0400590 /* Do the actual store operation */
591
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 switch (target_type) {
593 case ACPI_TYPE_BUFFER_FIELD:
594 case ACPI_TYPE_LOCAL_REGION_FIELD:
595 case ACPI_TYPE_LOCAL_BANK_FIELD:
596 case ACPI_TYPE_LOCAL_INDEX_FIELD:
597
Robert Moore44f6c012005-04-18 22:49:35 -0400598 /* For fields, copy the source data to the target field. */
599
Len Brown4be44fc2005-08-05 00:44:28 -0400600 status = acpi_ex_write_data_to_field(source_desc, target_desc,
601 &walk_state->result_obj);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 break;
603
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 case ACPI_TYPE_INTEGER:
605 case ACPI_TYPE_STRING:
606 case ACPI_TYPE_BUFFER:
607
608 /*
609 * These target types are all of type Integer/String/Buffer, and
610 * therefore support implicit conversion before the store.
611 *
612 * Copy and/or convert the source object to a new target object
613 */
Len Brown4be44fc2005-08-05 00:44:28 -0400614 status =
615 acpi_ex_store_object_to_object(source_desc, target_desc,
616 &new_desc, walk_state);
617 if (ACPI_FAILURE(status)) {
618 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 }
620
621 if (new_desc != target_desc) {
622 /*
623 * Store the new new_desc as the new value of the Name, and set
624 * the Name's type to that of the value being stored in it.
625 * source_desc reference count is incremented by attach_object.
626 *
627 * Note: This may change the type of the node if an explicit store
628 * has been performed such that the node/object type has been
629 * changed.
630 */
Len Brown4be44fc2005-08-05 00:44:28 -0400631 status =
632 acpi_ns_attach_object(node, new_desc,
633 new_desc->common.type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
Len Brown4be44fc2005-08-05 00:44:28 -0400635 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
636 "Store %s into %s via Convert/Attach\n",
637 acpi_ut_get_object_type_name
638 (source_desc),
639 acpi_ut_get_object_type_name
640 (new_desc)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 }
642 break;
643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 default:
645
Len Brown4be44fc2005-08-05 00:44:28 -0400646 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
647 "Storing %s (%p) directly into node (%p) with no implicit conversion\n",
648 acpi_ut_get_object_type_name(source_desc),
649 source_desc, node));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
651 /* No conversions for all other types. Just attach the source object */
652
Len Brown4be44fc2005-08-05 00:44:28 -0400653 status = acpi_ns_attach_object(node, source_desc,
654 ACPI_GET_OBJECT_TYPE
655 (source_desc));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 break;
657 }
658
Len Brown4be44fc2005-08-05 00:44:28 -0400659 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660}