File: /usr/src/linux/drivers/acpi/executer/exconvrt.c

1     /******************************************************************************
2      *
3      * Module Name: exconvrt - Object conversion routines
4      *              $Revision: 22 $
5      *
6      *****************************************************************************/
7     
8     /*
9      *  Copyright (C) 2000, 2001 R. Byron Moore
10      *
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.
15      *
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.
20      *
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
24      */
25     
26     
27     #include "acpi.h"
28     #include "acparser.h"
29     #include "acnamesp.h"
30     #include "acinterp.h"
31     #include "acevents.h"
32     #include "amlcode.h"
33     #include "acdispat.h"
34     
35     
36     #define _COMPONENT          ACPI_EXECUTER
37     	 MODULE_NAME         ("exconvrt")
38     
39     
40     /*******************************************************************************
41      *
42      * FUNCTION:    Acpi_ex_convert_to_integer
43      *
44      * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
45      *                                Integer, Buffer, or String
46      *              Walk_state      - Current method state
47      *
48      * RETURN:      Status
49      *
50      * DESCRIPTION: Convert an ACPI Object to an integer.
51      *
52      ******************************************************************************/
53     
54     acpi_status
55     acpi_ex_convert_to_integer (
56     	acpi_operand_object     *obj_desc,
57     	acpi_operand_object     **result_desc,
58     	acpi_walk_state         *walk_state)
59     {
60     	u32                     i;
61     	acpi_operand_object     *ret_desc;
62     	u32                     count;
63     	char                    *pointer;
64     	acpi_integer            result;
65     	u32                     integer_size = sizeof (acpi_integer);
66     
67     
68     	FUNCTION_ENTRY ();
69     
70     
71     	switch (obj_desc->common.type) {
72     	case ACPI_TYPE_INTEGER:
73     		*result_desc = obj_desc;
74     		return (AE_OK);
75     
76     	case ACPI_TYPE_STRING:
77     		pointer = obj_desc->string.pointer;
78     		count   = obj_desc->string.length;
79     		break;
80     
81     	case ACPI_TYPE_BUFFER:
82     		pointer = (char *) obj_desc->buffer.pointer;
83     		count   = obj_desc->buffer.length;
84     		break;
85     
86     	default:
87     		return (AE_TYPE);
88     	}
89     
90     	/*
91     	 * Create a new integer
92     	 */
93     	ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
94     	if (!ret_desc) {
95     		return (AE_NO_MEMORY);
96     	}
97     
98     
99     	/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
100     
101     	if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
102     		/*
103     		 * We are running a method that exists in a 32-bit ACPI table.
104     		 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
105     		 */
106     		integer_size = sizeof (u32);
107     	}
108     
109     
110     	/*
111     	 * Convert the buffer/string to an integer.  Note that both buffers and
112     	 * strings are treated as raw data - we don't convert ascii to hex for
113     	 * strings.
114     	 *
115     	 * There are two terminating conditions for the loop:
116     	 * 1) The size of an integer has been reached, or
117     	 * 2) The end of the buffer or string has been reached
118     	 */
119     	result = 0;
120     
121     	/* Transfer no more than an integer's worth of data */
122     
123     	if (count > integer_size) {
124     		count = integer_size;
125     	}
126     
127     	/*
128     	 * String conversion is different than Buffer conversion
129     	 */
130     	switch (obj_desc->common.type) {
131     	case ACPI_TYPE_STRING:
132     
133     		/* TBD: Need to use 64-bit STRTOUL */
134     
135     		/*
136     		 * Convert string to an integer
137     		 * String must be hexadecimal as per the ACPI specification
138     		 */
139     		result = STRTOUL (pointer, NULL, 16);
140     		break;
141     
142     
143     	case ACPI_TYPE_BUFFER:
144     
145     		/*
146     		 * Buffer conversion - we simply grab enough raw data from the
147     		 * buffer to fill an integer
148     		 */
149     		for (i = 0; i < count; i++) {
150     			/*
151     			 * Get next byte and shift it into the Result.
152     			 * Little endian is used, meaning that the first byte of the buffer
153     			 * is the LSB of the integer
154     			 */
155     			result |= (((acpi_integer) pointer[i]) << (i * 8));
156     		}
157     
158     		break;
159     	}
160     
161     	/* Save the Result, delete original descriptor, store new descriptor */
162     
163     	ret_desc->integer.value = result;
164     
165     	if (*result_desc == obj_desc) {
166     		if (walk_state->opcode != AML_STORE_OP) {
167     			acpi_ut_remove_reference (obj_desc);
168     		}
169     	}
170     
171     	*result_desc = ret_desc;
172     	return (AE_OK);
173     }
174     
175     
176     /*******************************************************************************
177      *
178      * FUNCTION:    Acpi_ex_convert_to_buffer
179      *
180      * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
181      *                                Integer, Buffer, or String
182      *              Walk_state      - Current method state
183      *
184      * RETURN:      Status
185      *
186      * DESCRIPTION: Convert an ACPI Object to an Buffer
187      *
188      ******************************************************************************/
189     
190     acpi_status
191     acpi_ex_convert_to_buffer (
192     	acpi_operand_object     *obj_desc,
193     	acpi_operand_object     **result_desc,
194     	acpi_walk_state         *walk_state)
195     {
196     	acpi_operand_object     *ret_desc;
197     	u32                     i;
198     	u32                     integer_size = sizeof (acpi_integer);
199     	u8                      *new_buf;
200     
201     
202     	FUNCTION_ENTRY ();
203     
204     
205     	switch (obj_desc->common.type) {
206     	case ACPI_TYPE_INTEGER:
207     
208     		/*
209     		 * Create a new Buffer
210     		 */
211     		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
212     		if (!ret_desc) {
213     			return (AE_NO_MEMORY);
214     		}
215     
216     		/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
217     
218     		if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
219     			/*
220     			 * We are running a method that exists in a 32-bit ACPI table.
221     			 * Truncate the value to 32 bits by zeroing out the upper
222     			 * 32-bit field
223     			 */
224     			integer_size = sizeof (u32);
225     		}
226     
227     		/* Need enough space for one integers */
228     
229     		ret_desc->buffer.length = integer_size;
230     		new_buf = ACPI_MEM_CALLOCATE (integer_size);
231     		if (!new_buf) {
232     			REPORT_ERROR
233     				(("Ex_dyadic2_r/Concat_op: Buffer allocation failure\n"));
234     			acpi_ut_remove_reference (ret_desc);
235     			return (AE_NO_MEMORY);
236     		}
237     
238     		/* Copy the integer to the buffer */
239     
240     		for (i = 0; i < integer_size; i++) {
241     			new_buf[i] = (u8) (obj_desc->integer.value >> (i * 8));
242     		}
243     		ret_desc->buffer.pointer = new_buf;
244     
245     		/* Return the new buffer descriptor */
246     
247     		if (*result_desc == obj_desc) {
248     			if (walk_state->opcode != AML_STORE_OP) {
249     				acpi_ut_remove_reference (obj_desc);
250     			}
251     		}
252     
253     		*result_desc = ret_desc;
254     		break;
255     
256     
257     	case ACPI_TYPE_STRING:
258     		*result_desc = obj_desc;
259     		break;
260     
261     
262     	case ACPI_TYPE_BUFFER:
263     		*result_desc = obj_desc;
264     		break;
265     
266     
267     	default:
268     		return (AE_TYPE);
269     		break;
270        }
271     
272     	return (AE_OK);
273     }
274     
275     
276     /*******************************************************************************
277      *
278      * FUNCTION:    Acpi_ex_convert_ascii
279      *
280      * PARAMETERS:  Integer
281      *
282      * RETURN:      Actual string length
283      *
284      * DESCRIPTION: Convert an ACPI Integer to a hex string
285      *
286      ******************************************************************************/
287     
288     u32
289     acpi_ex_convert_to_ascii (
290     	acpi_integer            integer,
291     	u32                     base,
292     	u8                      *string)
293     {
294     	u32                     i;
295     	u32                     j;
296     	u32                     k = 0;
297     	u8                      hex_digit;
298     	acpi_integer            digit;
299     	u8                      leading_zero = TRUE;
300     	u32                     length = sizeof (acpi_integer);
301     
302     
303     	FUNCTION_ENTRY ();
304     
305     
306     	switch (base) {
307     	case 10:
308     
309     		for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0 ; i--) {
310     			/* Divide by nth factor of 10 */
311     
312     			digit = integer;
313     			for (j = 1; j < i; j++) {
314     				digit = ACPI_DIVIDE (digit, 10);
315     			}
316     
317     			/* Create the decimal digit */
318     
319     			if (digit != 0) {
320     				leading_zero = FALSE;
321     			}
322     
323     			if (!leading_zero) {
324     				string[k] = (u8) (ASCII_ZERO + ACPI_MODULO (digit, 10));
325     				k++;
326     			}
327     		}
328     		break;
329     
330     	case 16:
331     
332     		/* Copy the integer to the buffer */
333     
334     		for (i = 0, j = ((length * 2) -1); i < (length * 2); i++, j--) {
335     
336     			hex_digit = acpi_ut_hex_to_ascii_char (integer, (j * 4));
337     			if (hex_digit != ASCII_ZERO) {
338     				leading_zero = FALSE;
339     			}
340     
341     			if (!leading_zero) {
342     				string[k] = hex_digit;
343     				k++;
344     			}
345     		}
346     		break;
347     
348     	default:
349     		break;
350     	}
351     
352     	/*
353     	 * Since leading zeros are supressed, we must check for the case where
354     	 * the integer equals 0.
355     	 *
356     	 * Finally, null terminate the string and return the length
357     	 */
358     	if (!k) {
359     		string [0] = ASCII_ZERO;
360     		k = 1;
361     	}
362     	string [k] = 0;
363     
364     	return (k);
365     }
366     
367     
368     /*******************************************************************************
369      *
370      * FUNCTION:    Acpi_ex_convert_to_string
371      *
372      * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
373      *                                Integer, Buffer, or String
374      *              Walk_state      - Current method state
375      *
376      * RETURN:      Status
377      *
378      * DESCRIPTION: Convert an ACPI Object to a string
379      *
380      ******************************************************************************/
381     
382     acpi_status
383     acpi_ex_convert_to_string (
384     	acpi_operand_object     *obj_desc,
385     	acpi_operand_object     **result_desc,
386     	u32                     base,
387     	u32                     max_length,
388     	acpi_walk_state         *walk_state)
389     {
390     	acpi_operand_object     *ret_desc;
391     	u32                     i;
392     	u32                     index;
393     	u32                     string_length;
394     	u32                     integer_size = sizeof (acpi_integer);
395     	u8                      *new_buf;
396     	u8                      *pointer;
397     
398     
399     	FUNCTION_ENTRY ();
400     
401     
402     	switch (obj_desc->common.type) {
403     	case ACPI_TYPE_INTEGER:
404     
405     		/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
406     
407     		if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
408     			/*
409     			 * We are running a method that exists in a 32-bit ACPI table.
410     			 * Truncate the value to 32 bits by zeroing out the upper
411     			 * 32-bit field
412     			 */
413     			integer_size = sizeof (u32);
414     		}
415     
416     		string_length = integer_size * 2;
417     		if (base == 10) {
418     			string_length = ACPI_MAX_DECIMAL_DIGITS;
419     		}
420     
421     		/*
422     		 * Create a new String
423     		 */
424     		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
425     		if (!ret_desc) {
426     			return (AE_NO_MEMORY);
427     		}
428     
429     		/* Need enough space for one ASCII integer plus null terminator */
430     
431     		new_buf = ACPI_MEM_CALLOCATE (string_length + 1);
432     		if (!new_buf) {
433     			REPORT_ERROR
434     				(("Ex_convert_to_string: Buffer allocation failure\n"));
435     			acpi_ut_remove_reference (ret_desc);
436     			return (AE_NO_MEMORY);
437     		}
438     
439     
440     		/* Convert */
441     
442     		i = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, new_buf);
443     
444     		/* Null terminate at the correct place */
445     
446     		if (max_length < i) {
447     			new_buf[max_length] = 0;
448     			ret_desc->string.length = max_length;
449     		}
450     		else {
451     			new_buf [i] = 0;
452     			ret_desc->string.length = i;
453     		}
454     
455     		ret_desc->buffer.pointer = new_buf;
456     
457     		/* Return the new buffer descriptor */
458     
459     		if (*result_desc == obj_desc) {
460     			if (walk_state->opcode != AML_STORE_OP) {
461     				acpi_ut_remove_reference (obj_desc);
462     			}
463     		}
464     
465     		*result_desc = ret_desc;
466     		break;
467     
468     
469     	case ACPI_TYPE_BUFFER:
470     
471     		string_length = obj_desc->buffer.length * 3;
472     		if (base == 10) {
473     			string_length = obj_desc->buffer.length * 4;
474     		}
475     
476     		if (max_length > ACPI_MAX_STRING_CONVERSION) {
477     			if (string_length > ACPI_MAX_STRING_CONVERSION) {
478     				return (AE_AML_STRING_LIMIT);
479     			}
480     		}
481     
482     		/*
483     		 * Create a new string object
484     		 */
485     		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
486     		if (!ret_desc) {
487     			return (AE_NO_MEMORY);
488     		}
489     
490     		/* String length is the lesser of the Max or the actual length */
491     
492     		if (max_length < string_length) {
493     			string_length = max_length;
494     		}
495     
496     		new_buf = ACPI_MEM_CALLOCATE (string_length + 1);
497     		if (!new_buf) {
498     			REPORT_ERROR
499     				(("Ex_convert_to_string: Buffer allocation failure\n"));
500     			acpi_ut_remove_reference (ret_desc);
501     			return (AE_NO_MEMORY);
502     		}
503     
504     		/*
505     		 * Convert each byte of the buffer to two ASCII characters plus a space.
506     		 */
507     		pointer = obj_desc->buffer.pointer;
508     		index = 0;
509     		for (i = 0, index = 0; i < obj_desc->buffer.length; i++) {
510     			index = acpi_ex_convert_to_ascii (pointer[i], base, &new_buf[index]);
511     
512     			new_buf[index] = ' ';
513     			index++;
514     		}
515     
516     		/* Null terminate */
517     
518     		new_buf [index-1] = 0;
519     		ret_desc->buffer.pointer = new_buf;
520     		ret_desc->string.length = STRLEN ((char *) new_buf);
521     
522     
523     		/* Return the new buffer descriptor */
524     
525     		if (*result_desc == obj_desc) {
526     			if (walk_state->opcode != AML_STORE_OP) {
527     				acpi_ut_remove_reference (obj_desc);
528     			}
529     		}
530     
531     		*result_desc = ret_desc;
532     		break;
533     
534     
535     	case ACPI_TYPE_STRING:
536     
537     		if (max_length >= obj_desc->string.length) {
538     			*result_desc = obj_desc;
539     		}
540     
541     		else {
542     			/* Must copy the string first and then truncate it */
543     
544     			return (AE_NOT_IMPLEMENTED);
545     		}
546     		break;
547     
548     
549     	default:
550     		return (AE_TYPE);
551     		break;
552        }
553     
554     	return (AE_OK);
555     }
556     
557     
558     /*******************************************************************************
559      *
560      * FUNCTION:    Acpi_ex_convert_to_target_type
561      *
562      * PARAMETERS:  *Obj_desc       - Object to be converted.
563      *              Walk_state      - Current method state
564      *
565      * RETURN:      Status
566      *
567      * DESCRIPTION:
568      *
569      ******************************************************************************/
570     
571     acpi_status
572     acpi_ex_convert_to_target_type (
573     	acpi_object_type8       destination_type,
574     	acpi_operand_object     **obj_desc,
575     	acpi_walk_state         *walk_state)
576     {
577     	acpi_status             status = AE_OK;
578     
579     
580     	FUNCTION_TRACE ("Ex_convert_to_target_type");
581     
582     
583     	/*
584     	 * If required by the target,
585     	 * perform implicit conversion on the source before we store it.
586     	 */
587     	switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)) {
588     	case ARGI_SIMPLE_TARGET:
589     	case ARGI_FIXED_TARGET:
590     	case ARGI_INTEGER_REF:      /* Handles Increment, Decrement cases */
591     
592     		switch (destination_type) {
593     		case INTERNAL_TYPE_REGION_FIELD:
594     			/*
595     			 * Named field can always handle conversions
596     			 */
597     			break;
598     
599     		default:
600     			/* No conversion allowed for these types */
601     
602     			if (destination_type != (*obj_desc)->common.type) {
603     				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
604     					"Target does not allow conversion of type %s to %s\n",
605     					acpi_ut_get_type_name ((*obj_desc)->common.type),
606     					acpi_ut_get_type_name (destination_type)));
607     				status = AE_TYPE;
608     			}
609     		}
610     		break;
611     
612     
613     	case ARGI_TARGETREF:
614     
615     		switch (destination_type) {
616     		case ACPI_TYPE_INTEGER:
617     		case ACPI_TYPE_BUFFER_FIELD:
618     		case INTERNAL_TYPE_BANK_FIELD:
619     		case INTERNAL_TYPE_INDEX_FIELD:
620     			/*
621     			 * These types require an Integer operand.  We can convert
622     			 * a Buffer or a String to an Integer if necessary.
623     			 */
624     			status = acpi_ex_convert_to_integer (*obj_desc, obj_desc, walk_state);
625     			break;
626     
627     
628     		case ACPI_TYPE_STRING:
629     
630     			/*
631     			 * The operand must be a String.  We can convert an
632     			 * Integer or Buffer if necessary
633     			 */
634     			status = acpi_ex_convert_to_string (*obj_desc, obj_desc, 16, ACPI_UINT32_MAX, walk_state);
635     			break;
636     
637     
638     		case ACPI_TYPE_BUFFER:
639     
640     			/*
641     			 * The operand must be a String.  We can convert an
642     			 * Integer or Buffer if necessary
643     			 */
644     			status = acpi_ex_convert_to_buffer (*obj_desc, obj_desc, walk_state);
645     			break;
646     		}
647     		break;
648     
649     
650     	case ARGI_REFERENCE:
651     		/*
652     		 * Create_xxxx_field cases - we are storing the field object into the name
653     		 */
654     		break;
655     
656     
657     	default:
658     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
659     			"Unknown Target type ID 0x%X Op %s Dest_type %s\n",
660     			GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args),
661     			walk_state->op_info->name, acpi_ut_get_type_name (destination_type)));
662     
663     		status = AE_AML_INTERNAL;
664     	}
665     
666     
667     	/*
668     	 * Source-to-Target conversion semantics:
669     	 *
670     	 * If conversion to the target type cannot be performed, then simply
671     	 * overwrite the target with the new object and type.
672     	 */
673     	if (status == AE_TYPE) {
674     		status = AE_OK;
675     	}
676     
677     	return_ACPI_STATUS (status);
678     }
679     
680     
681