1 /******************************************************************************
3 * Module Name: amconvrt - Object conversion routines
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #define _COMPONENT ACPI_EXECUTER
37 MODULE_NAME ("amconvrt")
40 /*******************************************************************************
42 * FUNCTION: Acpi_aml_convert_to_integer
44 * PARAMETERS: *Obj_desc - Object to be converted. Must be an
45 * Integer, Buffer, or String
46 * Walk_state - Current method state
50 * DESCRIPTION: Convert an ACPI Object to an integer.
52 ******************************************************************************/
55 acpi_aml_convert_to_integer (
56 ACPI_OPERAND_OBJECT **obj_desc,
57 ACPI_WALK_STATE *walk_state)
60 ACPI_OPERAND_OBJECT *ret_desc;
64 u32 integer_size = sizeof (ACPI_INTEGER);
67 switch ((*obj_desc)->common.type) {
68 case ACPI_TYPE_INTEGER:
71 case ACPI_TYPE_STRING:
72 pointer = (*obj_desc)->string.pointer;
73 count = (*obj_desc)->string.length;
76 case ACPI_TYPE_BUFFER:
77 pointer = (char *) (*obj_desc)->buffer.pointer;
78 count = (*obj_desc)->buffer.length;
86 * Create a new integer
88 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
90 return (AE_NO_MEMORY);
94 /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
96 if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
98 * We are running a method that exists in a 32-bit ACPI table.
99 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
101 integer_size = sizeof (u32);
106 * Convert the buffer/string to an integer. Note that both buffers and
107 * strings are treated as raw data - we don't convert ascii to hex for
110 * There are two terminating conditions for the loop:
111 * 1) The size of an integer has been reached, or
112 * 2) The end of the buffer or string has been reached
116 /* Transfer no more than an integer's worth of data */
118 if (count > integer_size) {
119 count = integer_size;
123 * String conversion is different than Buffer conversion
125 switch ((*obj_desc)->common.type) {
126 case ACPI_TYPE_STRING:
128 /* TBD: Need to use 64-bit STRTOUL */
131 * Convert string to an integer
132 * String must be hexadecimal as per the ACPI specification
135 result = STRTOUL (pointer, NULL, 16);
139 case ACPI_TYPE_BUFFER:
142 * Buffer conversion - we simply grab enough raw data from the
143 * buffer to fill an integer
145 for (i = 0; i < count; i++) {
147 * Get next byte and shift it into the Result.
148 * Little endian is used, meaning that the first byte of the buffer
149 * is the LSB of the integer
151 result |= (((ACPI_INTEGER) pointer[i]) << (i * 8));
157 /* Save the Result, delete original descriptor, store new descriptor */
159 ret_desc->integer.value = result;
161 if (walk_state->opcode != AML_STORE_OP) {
162 acpi_cm_remove_reference (*obj_desc);
165 *obj_desc = ret_desc;
171 /*******************************************************************************
173 * FUNCTION: Acpi_aml_convert_to_buffer
175 * PARAMETERS: *Obj_desc - Object to be converted. Must be an
176 * Integer, Buffer, or String
177 * Walk_state - Current method state
181 * DESCRIPTION: Convert an ACPI Object to an Buffer
183 ******************************************************************************/
186 acpi_aml_convert_to_buffer (
187 ACPI_OPERAND_OBJECT **obj_desc,
188 ACPI_WALK_STATE *walk_state)
190 ACPI_OPERAND_OBJECT *ret_desc;
192 u32 integer_size = sizeof (ACPI_INTEGER);
196 switch ((*obj_desc)->common.type) {
197 case ACPI_TYPE_INTEGER:
200 * Create a new Buffer
202 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER);
204 return (AE_NO_MEMORY);
207 /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
209 if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
211 * We are running a method that exists in a 32-bit ACPI table.
212 * Truncate the value to 32 bits by zeroing out the upper
215 integer_size = sizeof (u32);
218 /* Need enough space for one integers */
220 ret_desc->buffer.length = integer_size;
221 new_buf = acpi_cm_callocate (integer_size);
224 (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
225 acpi_cm_remove_reference (ret_desc);
226 return (AE_NO_MEMORY);
229 /* Copy the integer to the buffer */
231 for (i = 0; i < integer_size; i++) {
232 new_buf[i] = (u8) ((*obj_desc)->integer.value >> (i * 8));
234 ret_desc->buffer.pointer = new_buf;
236 /* Return the new buffer descriptor */
238 if (walk_state->opcode != AML_STORE_OP) {
239 acpi_cm_remove_reference (*obj_desc);
241 *obj_desc = ret_desc;
245 case ACPI_TYPE_STRING:
249 case ACPI_TYPE_BUFFER:
262 /*******************************************************************************
264 * FUNCTION: Acpi_aml_convert_to_string
266 * PARAMETERS: *Obj_desc - Object to be converted. Must be an
267 * Integer, Buffer, or String
268 * Walk_state - Current method state
272 * DESCRIPTION: Convert an ACPI Object to a string
274 ******************************************************************************/
277 acpi_aml_convert_to_string (
278 ACPI_OPERAND_OBJECT **obj_desc,
279 ACPI_WALK_STATE *walk_state)
281 ACPI_OPERAND_OBJECT *ret_desc;
284 u32 integer_size = sizeof (ACPI_INTEGER);
289 switch ((*obj_desc)->common.type) {
290 case ACPI_TYPE_INTEGER:
293 * Create a new String
295 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING);
297 return (AE_NO_MEMORY);
300 /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
302 if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
304 * We are running a method that exists in a 32-bit ACPI table.
305 * Truncate the value to 32 bits by zeroing out the upper
308 integer_size = sizeof (u32);
311 /* Need enough space for one ASCII integer plus null terminator */
313 ret_desc->string.length = (integer_size * 2) + 1;
314 new_buf = acpi_cm_callocate (ret_desc->string.length);
317 (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
318 acpi_cm_remove_reference (ret_desc);
319 return (AE_NO_MEMORY);
322 /* Copy the integer to the buffer */
324 for (i = 0; i < (integer_size * 2); i++) {
325 new_buf[i] = acpi_gbl_hex_to_ascii [((*obj_desc)->integer.value >> (i * 4)) & 0xF];
331 ret_desc->buffer.pointer = new_buf;
333 /* Return the new buffer descriptor */
335 if (walk_state->opcode != AML_STORE_OP) {
336 acpi_cm_remove_reference (*obj_desc);
338 *obj_desc = ret_desc;
343 case ACPI_TYPE_BUFFER:
345 if (((*obj_desc)->buffer.length * 3) > ACPI_MAX_STRING_CONVERSION) {
346 return (AE_AML_STRING_LIMIT);
350 * Create a new String
352 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING);
354 return (AE_NO_MEMORY);
357 /* Need enough space for one ASCII integer plus null terminator */
359 ret_desc->string.length = (*obj_desc)->buffer.length * 3;
360 new_buf = acpi_cm_callocate (ret_desc->string.length + 1);
363 (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
364 acpi_cm_remove_reference (ret_desc);
365 return (AE_NO_MEMORY);
369 * Convert each byte of the buffer to two ASCII characters plus a space.
371 pointer = (*obj_desc)->buffer.pointer;
373 for (i = 0; i < (*obj_desc)->buffer.length; i++) {
374 new_buf[index + 0] = acpi_gbl_hex_to_ascii [pointer[i] & 0x0F];
375 new_buf[index + 1] = acpi_gbl_hex_to_ascii [(pointer[i] >> 4) & 0x0F];
376 new_buf[index + 2] = ' ';
383 ret_desc->buffer.pointer = new_buf;
385 /* Return the new buffer descriptor */
387 if (walk_state->opcode != AML_STORE_OP) {
388 acpi_cm_remove_reference (*obj_desc);
390 *obj_desc = ret_desc;
394 case ACPI_TYPE_STRING:
407 /*******************************************************************************
409 * FUNCTION: Acpi_aml_convert_to_target_type
411 * PARAMETERS: *Obj_desc - Object to be converted.
412 * Walk_state - Current method state
418 ******************************************************************************/
421 acpi_aml_convert_to_target_type (
422 OBJECT_TYPE_INTERNAL destination_type,
423 ACPI_OPERAND_OBJECT **obj_desc,
424 ACPI_WALK_STATE *walk_state)
426 ACPI_STATUS status = AE_OK;
430 * If required by the target,
431 * perform implicit conversion on the source before we store it.
434 switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)) {
435 case ARGI_SIMPLE_TARGET:
436 case ARGI_FIXED_TARGET:
437 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
439 switch (destination_type) {
440 case INTERNAL_TYPE_DEF_FIELD:
442 * Named field can always handle conversions
447 /* No conversion allowed for these types */
449 if (destination_type != (*obj_desc)->common.type) {
458 switch (destination_type) {
459 case ACPI_TYPE_INTEGER:
460 case ACPI_TYPE_FIELD_UNIT:
461 case INTERNAL_TYPE_BANK_FIELD:
462 case INTERNAL_TYPE_INDEX_FIELD:
464 * These types require an Integer operand. We can convert
465 * a Buffer or a String to an Integer if necessary.
467 status = acpi_aml_convert_to_integer (obj_desc, walk_state);
471 case ACPI_TYPE_STRING:
474 * The operand must be a String. We can convert an
475 * Integer or Buffer if necessary
477 status = acpi_aml_convert_to_string (obj_desc, walk_state);
481 case ACPI_TYPE_BUFFER:
484 * The operand must be a String. We can convert an
485 * Integer or Buffer if necessary
487 status = acpi_aml_convert_to_buffer (obj_desc, walk_state);
495 * Create_xxxx_field cases - we are storing the field object into the name
501 status = AE_AML_INTERNAL;
506 * Source-to-Target conversion semantics:
508 * If conversion to the target type cannot be performed, then simply
509 * overwrite the target with the new object and type.
511 if (status == AE_TYPE) {