2 /******************************************************************************
4 * Module Name: amstore - AML Interpreter object store support
7 *****************************************************************************/
10 * Copyright (C) 2000, 2001 R. Byron Moore
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #define _COMPONENT ACPI_EXECUTER
32 MODULE_NAME ("amstore")
35 /*******************************************************************************
37 * FUNCTION: Acpi_aml_exec_store
39 * PARAMETERS: *Val_desc - Value to be stored
40 * *Dest_desc - Where to store it 0 Must be (ACPI_HANDLE)
41 * or an ACPI_OPERAND_OBJECT of type
42 * Reference; if the latter the descriptor
43 * will be either reused or deleted.
47 * DESCRIPTION: Store the value described by Val_desc into the location
48 * described by Dest_desc. Called by various interpreter
49 * functions to store the result of an operation into
50 * the destination operand.
52 ******************************************************************************/
56 ACPI_OPERAND_OBJECT
*val_desc
,
57 ACPI_OPERAND_OBJECT
*dest_desc
,
58 ACPI_WALK_STATE
*walk_state
)
60 ACPI_STATUS status
= AE_OK
;
61 ACPI_OPERAND_OBJECT
*ref_desc
= dest_desc
;
64 /* Validate parameters */
66 if (!val_desc
|| !dest_desc
) {
67 return (AE_AML_NO_OPERAND
);
70 /* Dest_desc can be either a namespace node or an ACPI object */
72 if (VALID_DESCRIPTOR_TYPE (dest_desc
, ACPI_DESC_TYPE_NAMED
)) {
74 * Dest is a namespace node,
75 * Storing an object into a Name "container"
77 status
= acpi_aml_store_object_to_node (val_desc
,
78 (ACPI_NAMESPACE_NODE
*) dest_desc
, walk_state
);
80 /* All done, that's it */
86 /* Destination object must be an object of type Reference */
88 if (dest_desc
->common
.type
!= INTERNAL_TYPE_REFERENCE
) {
89 /* Destination is not an Reference */
91 return (AE_AML_OPERAND_TYPE
);
96 * Examine the Reference opcode. These cases are handled:
98 * 1) Store to Name (Change the object associated with a name)
99 * 2) Store to an indexed area of a Buffer or Package
100 * 3) Store to a Method Local or Arg
101 * 4) Store to the debug object
102 * 5) Store to a constant -- a noop
105 switch (ref_desc
->reference
.opcode
) {
109 /* Storing an object into a Name "container" */
111 status
= acpi_aml_store_object_to_node (val_desc
, ref_desc
->reference
.object
,
118 /* Storing to an Index (pointer into a packager or buffer) */
120 status
= acpi_aml_store_object_to_index (val_desc
, ref_desc
, walk_state
);
127 /* Store to a method local/arg */
129 status
= acpi_ds_store_object_to_local (ref_desc
->reference
.opcode
,
130 ref_desc
->reference
.offset
, val_desc
, walk_state
);
137 * Storing to the Debug object causes the value stored to be
138 * displayed and otherwise has no effect -- see ACPI Specification
140 * TBD: print known object types "prettier".
151 * Storing to a constant is a no-op -- see ACPI Specification
152 * Delete the reference descriptor, however
159 /* TBD: [Restructure] use object dump routine !! */
161 status
= AE_AML_INTERNAL
;
164 } /* switch (Ref_desc->Reference.Opcode) */
167 /* Always delete the reference descriptor object */
170 acpi_cm_remove_reference (ref_desc
);
177 /*******************************************************************************
179 * FUNCTION: Acpi_aml_store_object_to_index
181 * PARAMETERS: *Val_desc - Value to be stored
182 * *Node - Named object to receive the value
186 * DESCRIPTION: Store the object to the named object.
188 ******************************************************************************/
191 acpi_aml_store_object_to_index (
192 ACPI_OPERAND_OBJECT
*val_desc
,
193 ACPI_OPERAND_OBJECT
*dest_desc
,
194 ACPI_WALK_STATE
*walk_state
)
196 ACPI_STATUS status
= AE_OK
;
197 ACPI_OPERAND_OBJECT
*obj_desc
;
204 * Destination must be a reference pointer, and
205 * must point to either a buffer or a package
208 switch (dest_desc
->reference
.target_type
) {
209 case ACPI_TYPE_PACKAGE
:
211 * Storing to a package element is not simple. The source must be
212 * evaluated and converted to the type of the destination and then the
213 * source is copied into the destination - we can't just point to the
216 if (dest_desc
->reference
.target_type
== ACPI_TYPE_PACKAGE
) {
218 * The object at *(Dest_desc->Reference.Where) is the
219 * element within the package that is to be modified.
221 obj_desc
= *(dest_desc
->reference
.where
);
224 * If the Destination element is a package, we will delete
225 * that object and construct a new one.
227 * TBD: [Investigate] Should both the src and dest be required
229 * && (Val_desc->Common.Type == ACPI_TYPE_PACKAGE)
231 if (obj_desc
->common
.type
== ACPI_TYPE_PACKAGE
) {
233 * Take away the reference for being part of a package and
236 acpi_cm_remove_reference (obj_desc
);
237 acpi_cm_remove_reference (obj_desc
);
245 * If the Obj_desc is NULL, it means that an uninitialized package
246 * element has been used as a destination (this is OK), therefore,
247 * we must create the destination element to match the type of the
248 * source element NOTE: Val_desc can be of any type.
250 obj_desc
= acpi_cm_create_internal_object (val_desc
->common
.type
);
252 return (AE_NO_MEMORY
);
256 * If the source is a package, copy the source to the new dest
258 if (ACPI_TYPE_PACKAGE
== obj_desc
->common
.type
) {
259 status
= acpi_cm_copy_ipackage_to_ipackage (val_desc
, obj_desc
, walk_state
);
260 if (ACPI_FAILURE (status
)) {
261 acpi_cm_remove_reference (obj_desc
);
267 * Install the new descriptor into the package and add a
268 * reference to the newly created descriptor for now being
269 * part of the parent package
272 *(dest_desc
->reference
.where
) = obj_desc
;
273 acpi_cm_add_reference (obj_desc
);
276 if (ACPI_TYPE_PACKAGE
!= obj_desc
->common
.type
) {
278 * The destination element is not a package, so we need to
279 * convert the contents of the source (Val_desc) and copy into
280 * the destination (Obj_desc)
282 status
= acpi_aml_store_object_to_object (val_desc
, obj_desc
,
284 if (ACPI_FAILURE (status
)) {
286 * An error occurrered when copying the internal object
287 * so delete the reference.
289 return (AE_AML_OPERAND_TYPE
);
296 case ACPI_TYPE_BUFFER_FIELD
:
298 * Storing into a buffer at a location defined by an Index.
300 * Each 8-bit element of the source object is written to the
301 * 8-bit Buffer Field of the Index destination object.
305 * Set the Obj_desc to the destination object and type check.
307 obj_desc
= dest_desc
->reference
.object
;
308 if (obj_desc
->common
.type
!= ACPI_TYPE_BUFFER
) {
309 return (AE_AML_OPERAND_TYPE
);
313 * The assignment of the individual elements will be slightly
314 * different for each source type.
317 switch (val_desc
->common
.type
) {
319 * If the type is Integer, assign bytewise
320 * This loop to assign each of the elements is somewhat
321 * backward because of the Big Endian-ness of IA-64
323 case ACPI_TYPE_INTEGER
:
324 length
= sizeof (ACPI_INTEGER
);
325 for (i
= length
; i
!= 0; i
--) {
326 value
= (u8
)(val_desc
->integer
.value
>> (MUL_8 (i
- 1)));
327 obj_desc
->buffer
.pointer
[dest_desc
->reference
.offset
] = value
;
332 * If the type is Buffer, the Length is in the structure.
333 * Just loop through the elements and assign each one in turn.
335 case ACPI_TYPE_BUFFER
:
336 length
= val_desc
->buffer
.length
;
337 for (i
= 0; i
< length
; i
++) {
338 value
= *(val_desc
->buffer
.pointer
+ i
);
339 obj_desc
->buffer
.pointer
[dest_desc
->reference
.offset
] = value
;
344 * If the type is String, the Length is in the structure.
345 * Just loop through the elements and assign each one in turn.
347 case ACPI_TYPE_STRING
:
348 length
= val_desc
->string
.length
;
349 for (i
= 0; i
< length
; i
++) {
350 value
= *(val_desc
->string
.pointer
+ i
);
351 obj_desc
->buffer
.pointer
[dest_desc
->reference
.offset
] = value
;
356 * If source is not a valid type so return an error.
359 status
= AE_AML_OPERAND_TYPE
;
366 status
= AE_AML_OPERAND_TYPE
;
375 /*******************************************************************************
377 * FUNCTION: Acpi_aml_store_object_to_node
379 * PARAMETERS: *Source_desc - Value to be stored
380 * *Node - Named object to receive the value
384 * DESCRIPTION: Store the object to the named object.
386 * The Assignment of an object to a named object is handled here
387 * The val passed in will replace the current value (if any)
388 * with the input value.
390 * When storing into an object the data is converted to the
391 * target object type then stored in the object. This means
392 * that the target object type (for an initialized target) will
393 * not be changed by a store operation.
395 * NOTE: the global lock is acquired early. This will result
396 * in the global lock being held a bit longer. Also, if the
397 * function fails during set up we may get the lock when we
398 * don't really need it. I don't think we care.
400 ******************************************************************************/
403 acpi_aml_store_object_to_node (
404 ACPI_OPERAND_OBJECT
*source_desc
,
405 ACPI_NAMESPACE_NODE
*node
,
406 ACPI_WALK_STATE
*walk_state
)
408 ACPI_STATUS status
= AE_OK
;
409 ACPI_OPERAND_OBJECT
*target_desc
;
410 OBJECT_TYPE_INTERNAL target_type
= ACPI_TYPE_ANY
;
414 * Assuming the parameters were already validated
416 ACPI_ASSERT((node
) && (source_desc
));
420 * Get current type of the node, and object attached to Node
422 target_type
= acpi_ns_get_type (node
);
423 target_desc
= acpi_ns_get_attached_object (node
);
427 * Resolve the source object to an actual value
428 * (If it is a reference object)
430 status
= acpi_aml_resolve_object (&source_desc
, target_type
, walk_state
);
431 if (ACPI_FAILURE (status
)) {
437 * Do the actual store operation
439 switch (target_type
) {
440 case INTERNAL_TYPE_DEF_FIELD
:
442 /* Raw data copy for target types Integer/String/Buffer */
444 status
= acpi_aml_copy_data_to_named_field (source_desc
, node
);
448 case ACPI_TYPE_INTEGER
:
449 case ACPI_TYPE_STRING
:
450 case ACPI_TYPE_BUFFER
:
451 case INTERNAL_TYPE_BANK_FIELD
:
452 case INTERNAL_TYPE_INDEX_FIELD
:
453 case ACPI_TYPE_FIELD_UNIT
:
456 * These target types are all of type Integer/String/Buffer, and
457 * therefore support implicit conversion before the store.
459 * Copy and/or convert the source object to a new target object
461 status
= acpi_aml_store_object (source_desc
, target_type
, &target_desc
, walk_state
);
462 if (ACPI_FAILURE (status
)) {
467 * Store the new Target_desc as the new value of the Name, and set
468 * the Name's type to that of the value being stored in it.
469 * Source_desc reference count is incremented by Attach_object.
471 status
= acpi_ns_attach_object (node
, target_desc
, target_type
);
477 /* No conversions for all other types. Just attach the source object */
479 status
= acpi_ns_attach_object (node
, source_desc
, source_desc
->common
.type
);
489 /*******************************************************************************
491 * FUNCTION: Acpi_aml_store_object_to_object
493 * PARAMETERS: *Source_desc - Value to be stored
494 * *Dest_desc - Object to receive the value
498 * DESCRIPTION: Store an object to another object.
500 * The Assignment of an object to another (not named) object
502 * The val passed in will replace the current value (if any)
503 * with the input value.
505 * When storing into an object the data is converted to the
506 * target object type then stored in the object. This means
507 * that the target object type (for an initialized target) will
508 * not be changed by a store operation.
510 * This module allows destination types of Number, String,
513 ******************************************************************************/
516 acpi_aml_store_object_to_object (
517 ACPI_OPERAND_OBJECT
*source_desc
,
518 ACPI_OPERAND_OBJECT
*dest_desc
,
519 ACPI_WALK_STATE
*walk_state
)
521 ACPI_STATUS status
= AE_OK
;
522 OBJECT_TYPE_INTERNAL destination_type
= dest_desc
->common
.type
;
526 * Assuming the parameters are valid!
528 ACPI_ASSERT((dest_desc
) && (source_desc
));
532 * From this interface, we only support Integers/Strings/Buffers
534 switch (destination_type
) {
535 case ACPI_TYPE_INTEGER
:
536 case ACPI_TYPE_STRING
:
537 case ACPI_TYPE_BUFFER
:
541 return (AE_NOT_IMPLEMENTED
);
546 * Resolve the source object to an actual value
547 * (If it is a reference object)
549 status
= acpi_aml_resolve_object (&source_desc
, destination_type
, walk_state
);
550 if (ACPI_FAILURE (status
)) {
556 * Copy and/or convert the source object to the destination object
558 status
= acpi_aml_store_object (source_desc
, destination_type
, &dest_desc
, walk_state
);