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