1 /******************************************************************************
2 *
3 * Module Name: exconvrt - Object conversion routines
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2004, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45 #include <acpi/acpi.h>
46 #include <acpi/acinterp.h>
47 #include <acpi/amlcode.h>
48
49
50 #define _COMPONENT ACPI_EXECUTER
51 ACPI_MODULE_NAME ("exconvrt")
52
53
54 /*******************************************************************************
55 *
56 * FUNCTION: acpi_ex_convert_to_integer
57 *
58 * PARAMETERS: obj_desc - Object to be converted. Must be an
59 * Integer, Buffer, or String
60 * result_desc - Where the new Integer object is returned
61 * walk_state - Current method state
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Convert an ACPI Object to an integer.
66 *
67 ******************************************************************************/
68
69 acpi_status
acpi_ex_convert_to_integer(union acpi_operand_object * obj_desc,union acpi_operand_object ** result_desc,struct acpi_walk_state * walk_state)70 acpi_ex_convert_to_integer (
71 union acpi_operand_object *obj_desc,
72 union acpi_operand_object **result_desc,
73 struct acpi_walk_state *walk_state)
74 {
75 u32 i;
76 union acpi_operand_object *ret_desc;
77 u32 count;
78 u8 *pointer;
79 acpi_integer result;
80 acpi_status status;
81
82
83 ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_integer", obj_desc);
84
85
86 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
87 case ACPI_TYPE_INTEGER:
88 *result_desc = obj_desc;
89 return_ACPI_STATUS (AE_OK);
90
91 case ACPI_TYPE_STRING:
92 pointer = (u8 *) obj_desc->string.pointer;
93 count = obj_desc->string.length;
94 break;
95
96 case ACPI_TYPE_BUFFER:
97 pointer = obj_desc->buffer.pointer;
98 count = obj_desc->buffer.length;
99 break;
100
101 default:
102 return_ACPI_STATUS (AE_TYPE);
103 }
104
105 /*
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
108 * strings.
109 *
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
113 */
114 result = 0;
115
116 /* Transfer no more than an integer's worth of data */
117
118 if (count > acpi_gbl_integer_byte_width) {
119 count = acpi_gbl_integer_byte_width;
120 }
121
122 /*
123 * String conversion is different than Buffer conversion
124 */
125 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
126 case ACPI_TYPE_STRING:
127
128 /*
129 * Convert string to an integer
130 * String must be hexadecimal as per the ACPI specification
131 */
132 status = acpi_ut_strtoul64 ((char *) pointer, 16, &result);
133 if (ACPI_FAILURE (status)) {
134 return_ACPI_STATUS (status);
135 }
136 break;
137
138
139 case ACPI_TYPE_BUFFER:
140
141 /*
142 * Buffer conversion - we simply grab enough raw data from the
143 * buffer to fill an integer
144 */
145 for (i = 0; i < count; i++) {
146 /*
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
150 */
151 result |= (((acpi_integer) pointer[i]) << (i * 8));
152 }
153 break;
154
155
156 default:
157 /* No other types can get here */
158 break;
159 }
160
161 /*
162 * Create a new integer
163 */
164 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
165 if (!ret_desc) {
166 return_ACPI_STATUS (AE_NO_MEMORY);
167 }
168
169 /* Save the Result */
170
171 ret_desc->integer.value = result;
172
173 /*
174 * If we are about to overwrite the original object on the operand stack,
175 * we must remove a reference on the original object because we are
176 * essentially removing it from the stack.
177 */
178 if (*result_desc == obj_desc) {
179 if (walk_state->opcode != AML_STORE_OP) {
180 acpi_ut_remove_reference (obj_desc);
181 }
182 }
183
184 *result_desc = ret_desc;
185 return_ACPI_STATUS (AE_OK);
186 }
187
188
189 /*******************************************************************************
190 *
191 * FUNCTION: acpi_ex_convert_to_buffer
192 *
193 * PARAMETERS: obj_desc - Object to be converted. Must be an
194 * Integer, Buffer, or String
195 * result_desc - Where the new buffer object is returned
196 * walk_state - Current method state
197 *
198 * RETURN: Status
199 *
200 * DESCRIPTION: Convert an ACPI Object to a Buffer
201 *
202 ******************************************************************************/
203
204 acpi_status
acpi_ex_convert_to_buffer(union acpi_operand_object * obj_desc,union acpi_operand_object ** result_desc,struct acpi_walk_state * walk_state)205 acpi_ex_convert_to_buffer (
206 union acpi_operand_object *obj_desc,
207 union acpi_operand_object **result_desc,
208 struct acpi_walk_state *walk_state)
209 {
210 union acpi_operand_object *ret_desc;
211 u32 i;
212 u8 *new_buf;
213
214
215 ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_buffer", obj_desc);
216
217
218 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
219 case ACPI_TYPE_BUFFER:
220
221 /* No conversion necessary */
222
223 *result_desc = obj_desc;
224 return_ACPI_STATUS (AE_OK);
225
226
227 case ACPI_TYPE_INTEGER:
228
229 /*
230 * Create a new Buffer object.
231 * Need enough space for one integer
232 */
233 ret_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
234 if (!ret_desc) {
235 return_ACPI_STATUS (AE_NO_MEMORY);
236 }
237
238 /* Copy the integer to the buffer */
239
240 new_buf = ret_desc->buffer.pointer;
241 for (i = 0; i < acpi_gbl_integer_byte_width; i++) {
242 new_buf[i] = (u8) (obj_desc->integer.value >> (i * 8));
243 }
244 break;
245
246
247 case ACPI_TYPE_STRING:
248
249 /*
250 * Create a new Buffer object
251 * Size will be the string length
252 */
253 ret_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length);
254 if (!ret_desc) {
255 return_ACPI_STATUS (AE_NO_MEMORY);
256 }
257
258 /* Copy the string to the buffer */
259
260 new_buf = ret_desc->buffer.pointer;
261 ACPI_STRNCPY ((char *) new_buf, (char *) obj_desc->string.pointer,
262 obj_desc->string.length);
263 break;
264
265
266 default:
267 return_ACPI_STATUS (AE_TYPE);
268 }
269
270 /* Mark buffer initialized */
271
272 ret_desc->common.flags |= AOPOBJ_DATA_VALID;
273
274 /*
275 * If we are about to overwrite the original object on the operand stack,
276 * we must remove a reference on the original object because we are
277 * essentially removing it from the stack.
278 */
279 if (*result_desc == obj_desc) {
280 if (walk_state->opcode != AML_STORE_OP) {
281 acpi_ut_remove_reference (obj_desc);
282 }
283 }
284
285 *result_desc = ret_desc;
286 return_ACPI_STATUS (AE_OK);
287 }
288
289
290 /*******************************************************************************
291 *
292 * FUNCTION: acpi_ex_convert_ascii
293 *
294 * PARAMETERS: Integer - Value to be converted
295 * Base - 10 or 16
296 * String - Where the string is returned
297 * data_width - Size of data item to be converted
298 *
299 * RETURN: Actual string length
300 *
301 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
302 *
303 ******************************************************************************/
304
305 u32
acpi_ex_convert_to_ascii(acpi_integer integer,u32 base,u8 * string,u8 data_width)306 acpi_ex_convert_to_ascii (
307 acpi_integer integer,
308 u32 base,
309 u8 *string,
310 u8 data_width)
311 {
312 u32 i;
313 u32 j;
314 u32 k = 0;
315 char hex_digit;
316 acpi_integer digit;
317 u32 remainder;
318 u32 length;
319 u8 leading_zero;
320
321
322 ACPI_FUNCTION_ENTRY ();
323
324
325 if (data_width < sizeof (acpi_integer)) {
326 leading_zero = FALSE;
327 length = data_width;
328 }
329 else {
330 leading_zero = TRUE;
331 length = sizeof (acpi_integer);
332 }
333
334 switch (base) {
335 case 10:
336
337 remainder = 0;
338 for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0; i--) {
339 /* Divide by nth factor of 10 */
340
341 digit = integer;
342 for (j = 0; j < i; j++) {
343 (void) acpi_ut_short_divide (&digit, 10, &digit, &remainder);
344 }
345
346 /* Create the decimal digit */
347
348 if (remainder != 0) {
349 leading_zero = FALSE;
350 }
351
352 if (!leading_zero) {
353 string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
354 k++;
355 }
356 }
357 break;
358
359
360 case 16:
361
362 /* Copy the integer to the buffer */
363
364 for (i = 0, j = ((length * 2) -1); i < (length * 2); i++, j--) {
365
366 hex_digit = acpi_ut_hex_to_ascii_char (integer, (j * 4));
367 if (hex_digit != ACPI_ASCII_ZERO) {
368 leading_zero = FALSE;
369 }
370
371 if (!leading_zero) {
372 string[k] = (u8) hex_digit;
373 k++;
374 }
375 }
376 break;
377
378
379 default:
380 break;
381 }
382
383 /*
384 * Since leading zeros are supressed, we must check for the case where
385 * the integer equals 0
386 *
387 * Finally, null terminate the string and return the length
388 */
389 if (!k) {
390 string [0] = ACPI_ASCII_ZERO;
391 k = 1;
392 }
393
394 string [k] = 0;
395 return (k);
396 }
397
398
399 /*******************************************************************************
400 *
401 * FUNCTION: acpi_ex_convert_to_string
402 *
403 * PARAMETERS: obj_desc - Object to be converted. Must be an
404 * Integer, Buffer, or String
405 * result_desc - Where the string object is returned
406 * Base - 10 or 16
407 * max_length - Max length of the returned string
408 * walk_state - Current method state
409 *
410 * RETURN: Status
411 *
412 * DESCRIPTION: Convert an ACPI Object to a string
413 *
414 ******************************************************************************/
415
416 acpi_status
acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,union acpi_operand_object ** result_desc,u32 base,u32 max_length,struct acpi_walk_state * walk_state)417 acpi_ex_convert_to_string (
418 union acpi_operand_object *obj_desc,
419 union acpi_operand_object **result_desc,
420 u32 base,
421 u32 max_length,
422 struct acpi_walk_state *walk_state)
423 {
424 union acpi_operand_object *ret_desc;
425 u8 *new_buf;
426 u8 *pointer;
427 u32 string_length;
428 u32 i;
429
430
431 ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc);
432
433
434 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
435 case ACPI_TYPE_STRING:
436
437 if (max_length >= obj_desc->string.length) {
438 *result_desc = obj_desc;
439 return_ACPI_STATUS (AE_OK);
440 }
441 else {
442 /* Must copy the string first and then truncate it */
443
444 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
445 }
446
447
448 case ACPI_TYPE_INTEGER:
449
450 string_length = acpi_gbl_integer_byte_width * 2;
451 if (base == 10) {
452 string_length = ACPI_MAX_DECIMAL_DIGITS;
453 }
454
455 /*
456 * Create a new String
457 */
458 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
459 if (!ret_desc) {
460 return_ACPI_STATUS (AE_NO_MEMORY);
461 }
462
463 /* Need enough space for one ASCII integer plus null terminator */
464
465 new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1);
466 if (!new_buf) {
467 ACPI_REPORT_ERROR
468 (("ex_convert_to_string: Buffer allocation failure\n"));
469 acpi_ut_remove_reference (ret_desc);
470 return_ACPI_STATUS (AE_NO_MEMORY);
471 }
472
473 /* Convert */
474
475 i = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, new_buf, sizeof (acpi_integer));
476
477 /* Null terminate at the correct place */
478
479 if (max_length < i) {
480 new_buf[max_length] = 0;
481 ret_desc->string.length = max_length;
482 }
483 else {
484 new_buf [i] = 0;
485 ret_desc->string.length = i;
486 }
487
488 ret_desc->buffer.pointer = new_buf;
489 break;
490
491
492 case ACPI_TYPE_BUFFER:
493
494 /* Find the string length */
495
496 pointer = obj_desc->buffer.pointer;
497 for (string_length = 0; string_length < obj_desc->buffer.length; string_length++) {
498 /* Exit on null terminator */
499
500 if (!pointer[string_length]) {
501 break;
502 }
503 }
504
505 if (max_length > ACPI_MAX_STRING_CONVERSION) {
506 if (string_length > ACPI_MAX_STRING_CONVERSION) {
507 return_ACPI_STATUS (AE_AML_STRING_LIMIT);
508 }
509 }
510
511 /*
512 * Create a new string object
513 */
514 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
515 if (!ret_desc) {
516 return_ACPI_STATUS (AE_NO_MEMORY);
517 }
518
519 /* String length is the lesser of the Max or the actual length */
520
521 if (max_length < string_length) {
522 string_length = max_length;
523 }
524
525 new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1);
526 if (!new_buf) {
527 ACPI_REPORT_ERROR
528 (("ex_convert_to_string: Buffer allocation failure\n"));
529 acpi_ut_remove_reference (ret_desc);
530 return_ACPI_STATUS (AE_NO_MEMORY);
531 }
532
533 /* Copy the appropriate number of buffer characters */
534
535 ACPI_MEMCPY (new_buf, pointer, string_length);
536
537 /* Null terminate */
538
539 new_buf [string_length] = 0;
540 ret_desc->buffer.pointer = new_buf;
541 ret_desc->string.length = string_length;
542 break;
543
544
545 default:
546 return_ACPI_STATUS (AE_TYPE);
547 }
548
549 /*
550 * If we are about to overwrite the original object on the operand stack,
551 * we must remove a reference on the original object because we are
552 * essentially removing it from the stack.
553 */
554 if (*result_desc == obj_desc) {
555 if (walk_state->opcode != AML_STORE_OP) {
556 acpi_ut_remove_reference (obj_desc);
557 }
558 }
559
560 *result_desc = ret_desc;
561 return_ACPI_STATUS (AE_OK);
562 }
563
564
565 /*******************************************************************************
566 *
567 * FUNCTION: acpi_ex_convert_to_target_type
568 *
569 * PARAMETERS: destination_type - Current type of the destination
570 * source_desc - Source object to be converted.
571 * result_desc - Where the converted object is returned
572 * walk_state - Current method state
573 *
574 * RETURN: Status
575 *
576 * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
577 *
578 ******************************************************************************/
579
580 acpi_status
acpi_ex_convert_to_target_type(acpi_object_type destination_type,union acpi_operand_object * source_desc,union acpi_operand_object ** result_desc,struct acpi_walk_state * walk_state)581 acpi_ex_convert_to_target_type (
582 acpi_object_type destination_type,
583 union acpi_operand_object *source_desc,
584 union acpi_operand_object **result_desc,
585 struct acpi_walk_state *walk_state)
586 {
587 acpi_status status = AE_OK;
588
589
590 ACPI_FUNCTION_TRACE ("ex_convert_to_target_type");
591
592
593 /* Default behavior */
594
595 *result_desc = source_desc;
596
597 /*
598 * If required by the target,
599 * perform implicit conversion on the source before we store it.
600 */
601 switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)) {
602 case ARGI_SIMPLE_TARGET:
603 case ARGI_FIXED_TARGET:
604 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
605
606 switch (destination_type) {
607 case ACPI_TYPE_LOCAL_REGION_FIELD:
608 /*
609 * Named field can always handle conversions
610 */
611 break;
612
613 default:
614 /* No conversion allowed for these types */
615
616 if (destination_type != ACPI_GET_OBJECT_TYPE (source_desc)) {
617 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
618 "Explicit operator, will store (%s) over existing type (%s)\n",
619 acpi_ut_get_object_type_name (source_desc),
620 acpi_ut_get_type_name (destination_type)));
621 status = AE_TYPE;
622 }
623 }
624 break;
625
626
627 case ARGI_TARGETREF:
628
629 switch (destination_type) {
630 case ACPI_TYPE_INTEGER:
631 case ACPI_TYPE_BUFFER_FIELD:
632 case ACPI_TYPE_LOCAL_BANK_FIELD:
633 case ACPI_TYPE_LOCAL_INDEX_FIELD:
634 /*
635 * These types require an Integer operand. We can convert
636 * a Buffer or a String to an Integer if necessary.
637 */
638 status = acpi_ex_convert_to_integer (source_desc, result_desc, walk_state);
639 break;
640
641
642 case ACPI_TYPE_STRING:
643
644 /*
645 * The operand must be a String. We can convert an
646 * Integer or Buffer if necessary
647 */
648 status = acpi_ex_convert_to_string (source_desc, result_desc, 16, ACPI_UINT32_MAX, walk_state);
649 break;
650
651
652 case ACPI_TYPE_BUFFER:
653
654 /*
655 * The operand must be a Buffer. We can convert an
656 * Integer or String if necessary
657 */
658 status = acpi_ex_convert_to_buffer (source_desc, result_desc, walk_state);
659 break;
660
661
662 default:
663 ACPI_REPORT_ERROR (("Bad destination type during conversion: %X\n",
664 destination_type));
665 status = AE_AML_INTERNAL;
666 break;
667 }
668 break;
669
670
671 case ARGI_REFERENCE:
672 /*
673 * create_xxxx_field cases - we are storing the field object into the name
674 */
675 break;
676
677
678 default:
679 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
680 "Unknown Target type ID 0x%X Op %s dest_type %s\n",
681 GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args),
682 walk_state->op_info->name, acpi_ut_get_type_name (destination_type)));
683
684 ACPI_REPORT_ERROR (("Bad Target Type (ARGI): %X\n",
685 GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)))
686 status = AE_AML_INTERNAL;
687 }
688
689 /*
690 * Source-to-Target conversion semantics:
691 *
692 * If conversion to the target type cannot be performed, then simply
693 * overwrite the target with the new object and type.
694 */
695 if (status == AE_TYPE) {
696 status = AE_OK;
697 }
698
699 return_ACPI_STATUS (status);
700 }
701
702
703