2 /******************************************************************************
4 * Module Name: amstorob - AML Interpreter object store support, store to object
7 *****************************************************************************/
10 * Copyright (C) 2000 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
37 #define _COMPONENT INTERPRETER
38 MODULE_NAME ("amstorob")
41 /*******************************************************************************
43 * FUNCTION: Acpi_aml_store_object_to_object
45 * PARAMETERS: *Val_desc - Value to be stored
46 * *Dest_desc - Object to receive the value
50 * DESCRIPTION: Store an object to another object.
52 * The Assignment of an object to another (not named) object
54 * The val passed in will replace the current value (if any)
55 * with the input value.
57 * When storing into an object the data is converted to the
58 * target object type then stored in the object. This means
59 * that the target object type (for an initialized target) will
60 * not be changed by a store operation.
62 * This module allows destination types of Number, String,
65 ******************************************************************************/
68 acpi_aml_store_object_to_object (
69 ACPI_OPERAND_OBJECT
*val_desc
,
70 ACPI_OPERAND_OBJECT
*dest_desc
,
71 ACPI_WALK_STATE
*walk_state
)
73 ACPI_STATUS status
= AE_OK
;
76 OBJECT_TYPE_INTERNAL destination_type
= dest_desc
->common
.type
;
80 * Assuming the parameters are valid!!!
82 ACPI_ASSERT((dest_desc
) && (val_desc
));
85 * First ensure we have a value that can be stored in the target
87 switch (destination_type
)
89 /* Type of Name's existing value */
91 case ACPI_TYPE_NUMBER
:
94 * These cases all require only number values or values that
95 * can be converted to numbers.
97 * If value is not a Number, try to resolve it to one.
100 if (val_desc
->common
.type
!= ACPI_TYPE_NUMBER
) {
102 * Initially not a number, convert
104 status
= acpi_aml_resolve_to_value (&val_desc
, walk_state
);
105 if (ACPI_SUCCESS (status
) &&
106 (val_desc
->common
.type
!= ACPI_TYPE_NUMBER
))
109 * Conversion successful but still not a number
111 status
= AE_AML_OPERAND_TYPE
;
117 case ACPI_TYPE_STRING
:
118 case ACPI_TYPE_BUFFER
:
121 * Storing into a Field in a region or into a buffer or into
122 * a string all is essentially the same.
124 * If value is not a valid type, try to resolve it to one.
127 if ((val_desc
->common
.type
!= ACPI_TYPE_NUMBER
) &&
128 (val_desc
->common
.type
!= ACPI_TYPE_BUFFER
) &&
129 (val_desc
->common
.type
!= ACPI_TYPE_STRING
))
132 * Initially not a valid type, convert
134 status
= acpi_aml_resolve_to_value (&val_desc
, walk_state
);
135 if (ACPI_SUCCESS (status
) &&
136 (val_desc
->common
.type
!= ACPI_TYPE_NUMBER
) &&
137 (val_desc
->common
.type
!= ACPI_TYPE_BUFFER
) &&
138 (val_desc
->common
.type
!= ACPI_TYPE_STRING
))
141 * Conversion successful but still not a valid type
143 status
= AE_AML_OPERAND_TYPE
;
152 * TBD: [Unhandled] What other combinations must be implemented?
154 status
= AE_NOT_IMPLEMENTED
;
158 /* Exit now if failure above */
160 if (ACPI_FAILURE (status
)) {
161 goto clean_up_and_bail_out
;
165 * Acpi_everything is ready to execute now, We have
166 * a value we can handle, just perform the update
169 switch (destination_type
)
172 case ACPI_TYPE_STRING
:
178 switch (val_desc
->common
.type
)
180 case ACPI_TYPE_NUMBER
:
181 buffer
= (u8
*) &val_desc
->number
.value
;
182 length
= sizeof (val_desc
->number
.value
);
185 case ACPI_TYPE_BUFFER
:
186 buffer
= (u8
*) val_desc
->buffer
.pointer
;
187 length
= val_desc
->buffer
.length
;
190 case ACPI_TYPE_STRING
:
191 buffer
= (u8
*) val_desc
->string
.pointer
;
192 length
= val_desc
->string
.length
;
197 * Setting a string value replaces the old string
200 if (length
< dest_desc
->string
.length
) {
202 * Zero fill, not willing to do pointer arithmetic for
203 * architecture independence. Just clear the whole thing
205 MEMSET(dest_desc
->string
.pointer
, 0, dest_desc
->string
.length
);
206 MEMCPY(dest_desc
->string
.pointer
, buffer
, length
);
210 * Free the current buffer, then allocate a buffer
211 * large enough to hold the value
213 if ( dest_desc
->string
.pointer
&&
214 !acpi_tb_system_table_pointer (dest_desc
->string
.pointer
))
217 * Only free if not a pointer into the DSDT
220 acpi_cm_free(dest_desc
->string
.pointer
);
223 dest_desc
->string
.pointer
= acpi_cm_allocate (length
+ 1);
224 dest_desc
->string
.length
= length
;
226 if (!dest_desc
->string
.pointer
) {
227 status
= AE_NO_MEMORY
;
228 goto clean_up_and_bail_out
;
231 MEMCPY(dest_desc
->string
.pointer
, buffer
, length
);
236 case ACPI_TYPE_BUFFER
:
239 * Perform the update to the buffer
242 switch (val_desc
->common
.type
)
244 case ACPI_TYPE_NUMBER
:
245 buffer
= (u8
*) &val_desc
->number
.value
;
246 length
= sizeof (val_desc
->number
.value
);
249 case ACPI_TYPE_BUFFER
:
250 buffer
= (u8
*) val_desc
->buffer
.pointer
;
251 length
= val_desc
->buffer
.length
;
254 case ACPI_TYPE_STRING
:
255 buffer
= (u8
*) val_desc
->string
.pointer
;
256 length
= val_desc
->string
.length
;
261 * If the buffer is uninitialized,
262 * memory needs to be allocated for the copy.
264 if(0 == dest_desc
->buffer
.length
) {
265 dest_desc
->buffer
.pointer
= acpi_cm_callocate(length
);
266 dest_desc
->buffer
.length
= length
;
268 if (!dest_desc
->buffer
.pointer
) {
269 status
= AE_NO_MEMORY
;
270 goto clean_up_and_bail_out
;
275 * Buffer is a static allocation,
276 * only place what will fit in the buffer.
278 if (length
<= dest_desc
->buffer
.length
) {
280 * Zero fill first, not willing to do pointer arithmetic for
281 * architecture independence. Just clear the whole thing
283 MEMSET(dest_desc
->buffer
.pointer
, 0, dest_desc
->buffer
.length
);
284 MEMCPY(dest_desc
->buffer
.pointer
, buffer
, length
);
288 * truncate, copy only what will fit
290 MEMCPY(dest_desc
->buffer
.pointer
, buffer
, dest_desc
->buffer
.length
);
294 case ACPI_TYPE_NUMBER
:
296 dest_desc
->number
.value
= val_desc
->number
.value
;
298 /* Truncate value if we are executing from a 32-bit ACPI table */
300 acpi_aml_truncate_for32bit_table (dest_desc
, walk_state
);
306 * All other types than Alias and the various Fields come here.
307 * Store Val_desc as the new value of the Name, and set
308 * the Name's type to that of the value being stored in it.
309 * Val_desc reference count is incremented by Attach_object.
312 status
= AE_NOT_IMPLEMENTED
;
316 clean_up_and_bail_out
: