xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/exconvrt.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Module Name: exconvrt - Object conversion routines
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2000 - 2020, Intel Corp.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *****************************************************************************/
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <acpi/acpi.h>
11*4882a593Smuzhiyun #include "accommon.h"
12*4882a593Smuzhiyun #include "acinterp.h"
13*4882a593Smuzhiyun #include "amlcode.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #define _COMPONENT          ACPI_EXECUTER
16*4882a593Smuzhiyun ACPI_MODULE_NAME("exconvrt")
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun /* Local prototypes */
19*4882a593Smuzhiyun static u32
20*4882a593Smuzhiyun acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length);
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun /*******************************************************************************
23*4882a593Smuzhiyun  *
24*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_convert_to_integer
25*4882a593Smuzhiyun  *
26*4882a593Smuzhiyun  * PARAMETERS:  obj_desc            - Object to be converted. Must be an
27*4882a593Smuzhiyun  *                                    Integer, Buffer, or String
28*4882a593Smuzhiyun  *              result_desc         - Where the new Integer object is returned
29*4882a593Smuzhiyun  *              implicit_conversion - Used for string conversion
30*4882a593Smuzhiyun  *
31*4882a593Smuzhiyun  * RETURN:      Status
32*4882a593Smuzhiyun  *
33*4882a593Smuzhiyun  * DESCRIPTION: Convert an ACPI Object to an integer.
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  ******************************************************************************/
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun acpi_status
acpi_ex_convert_to_integer(union acpi_operand_object * obj_desc,union acpi_operand_object ** result_desc,u32 implicit_conversion)38*4882a593Smuzhiyun acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
39*4882a593Smuzhiyun 			   union acpi_operand_object **result_desc,
40*4882a593Smuzhiyun 			   u32 implicit_conversion)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	union acpi_operand_object *return_desc;
43*4882a593Smuzhiyun 	u8 *pointer;
44*4882a593Smuzhiyun 	u64 result;
45*4882a593Smuzhiyun 	u32 i;
46*4882a593Smuzhiyun 	u32 count;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	switch (obj_desc->common.type) {
51*4882a593Smuzhiyun 	case ACPI_TYPE_INTEGER:
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 		/* No conversion necessary */
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 		*result_desc = obj_desc;
56*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_OK);
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	case ACPI_TYPE_BUFFER:
59*4882a593Smuzhiyun 	case ACPI_TYPE_STRING:
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 		/* Note: Takes advantage of common buffer/string fields */
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 		pointer = obj_desc->buffer.pointer;
64*4882a593Smuzhiyun 		count = obj_desc->buffer.length;
65*4882a593Smuzhiyun 		break;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	default:
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_TYPE);
70*4882a593Smuzhiyun 	}
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	/*
73*4882a593Smuzhiyun 	 * Convert the buffer/string to an integer. Note that both buffers and
74*4882a593Smuzhiyun 	 * strings are treated as raw data - we don't convert ascii to hex for
75*4882a593Smuzhiyun 	 * strings.
76*4882a593Smuzhiyun 	 *
77*4882a593Smuzhiyun 	 * There are two terminating conditions for the loop:
78*4882a593Smuzhiyun 	 * 1) The size of an integer has been reached, or
79*4882a593Smuzhiyun 	 * 2) The end of the buffer or string has been reached
80*4882a593Smuzhiyun 	 */
81*4882a593Smuzhiyun 	result = 0;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	/* String conversion is different than Buffer conversion */
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	switch (obj_desc->common.type) {
86*4882a593Smuzhiyun 	case ACPI_TYPE_STRING:
87*4882a593Smuzhiyun 		/*
88*4882a593Smuzhiyun 		 * Convert string to an integer - for most cases, the string must be
89*4882a593Smuzhiyun 		 * hexadecimal as per the ACPI specification. The only exception (as
90*4882a593Smuzhiyun 		 * of ACPI 3.0) is that the to_integer() operator allows both decimal
91*4882a593Smuzhiyun 		 * and hexadecimal strings (hex prefixed with "0x").
92*4882a593Smuzhiyun 		 *
93*4882a593Smuzhiyun 		 * Explicit conversion is used only by to_integer.
94*4882a593Smuzhiyun 		 * All other string-to-integer conversions are implicit conversions.
95*4882a593Smuzhiyun 		 */
96*4882a593Smuzhiyun 		if (implicit_conversion) {
97*4882a593Smuzhiyun 			result =
98*4882a593Smuzhiyun 			    acpi_ut_implicit_strtoul64(ACPI_CAST_PTR
99*4882a593Smuzhiyun 						       (char, pointer));
100*4882a593Smuzhiyun 		} else {
101*4882a593Smuzhiyun 			result =
102*4882a593Smuzhiyun 			    acpi_ut_explicit_strtoul64(ACPI_CAST_PTR
103*4882a593Smuzhiyun 						       (char, pointer));
104*4882a593Smuzhiyun 		}
105*4882a593Smuzhiyun 		break;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	case ACPI_TYPE_BUFFER:
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 		/* Check for zero-length buffer */
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 		if (!count) {
112*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
113*4882a593Smuzhiyun 		}
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 		/* Transfer no more than an integer's worth of data */
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 		if (count > acpi_gbl_integer_byte_width) {
118*4882a593Smuzhiyun 			count = acpi_gbl_integer_byte_width;
119*4882a593Smuzhiyun 		}
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 		/*
122*4882a593Smuzhiyun 		 * Convert buffer to an integer - we simply grab enough raw data
123*4882a593Smuzhiyun 		 * from the buffer to fill an integer
124*4882a593Smuzhiyun 		 */
125*4882a593Smuzhiyun 		for (i = 0; i < count; i++) {
126*4882a593Smuzhiyun 			/*
127*4882a593Smuzhiyun 			 * Get next byte and shift it into the Result.
128*4882a593Smuzhiyun 			 * Little endian is used, meaning that the first byte of the buffer
129*4882a593Smuzhiyun 			 * is the LSB of the integer
130*4882a593Smuzhiyun 			 */
131*4882a593Smuzhiyun 			result |= (((u64) pointer[i]) << (i * 8));
132*4882a593Smuzhiyun 		}
133*4882a593Smuzhiyun 		break;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	default:
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 		/* No other types can get here */
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 		break;
140*4882a593Smuzhiyun 	}
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	/* Create a new integer */
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	return_desc = acpi_ut_create_integer_object(result);
145*4882a593Smuzhiyun 	if (!return_desc) {
146*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NO_MEMORY);
147*4882a593Smuzhiyun 	}
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
150*4882a593Smuzhiyun 			  ACPI_FORMAT_UINT64(result)));
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	/* Save the Result */
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	(void)acpi_ex_truncate_for32bit_table(return_desc);
155*4882a593Smuzhiyun 	*result_desc = return_desc;
156*4882a593Smuzhiyun 	return_ACPI_STATUS(AE_OK);
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun /*******************************************************************************
160*4882a593Smuzhiyun  *
161*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_convert_to_buffer
162*4882a593Smuzhiyun  *
163*4882a593Smuzhiyun  * PARAMETERS:  obj_desc        - Object to be converted. Must be an
164*4882a593Smuzhiyun  *                                Integer, Buffer, or String
165*4882a593Smuzhiyun  *              result_desc     - Where the new buffer object is returned
166*4882a593Smuzhiyun  *
167*4882a593Smuzhiyun  * RETURN:      Status
168*4882a593Smuzhiyun  *
169*4882a593Smuzhiyun  * DESCRIPTION: Convert an ACPI Object to a Buffer
170*4882a593Smuzhiyun  *
171*4882a593Smuzhiyun  ******************************************************************************/
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun acpi_status
acpi_ex_convert_to_buffer(union acpi_operand_object * obj_desc,union acpi_operand_object ** result_desc)174*4882a593Smuzhiyun acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
175*4882a593Smuzhiyun 			  union acpi_operand_object **result_desc)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	union acpi_operand_object *return_desc;
178*4882a593Smuzhiyun 	u8 *new_buf;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	switch (obj_desc->common.type) {
183*4882a593Smuzhiyun 	case ACPI_TYPE_BUFFER:
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 		/* No conversion necessary */
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 		*result_desc = obj_desc;
188*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_OK);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	case ACPI_TYPE_INTEGER:
191*4882a593Smuzhiyun 		/*
192*4882a593Smuzhiyun 		 * Create a new Buffer object.
193*4882a593Smuzhiyun 		 * Need enough space for one integer
194*4882a593Smuzhiyun 		 */
195*4882a593Smuzhiyun 		return_desc =
196*4882a593Smuzhiyun 		    acpi_ut_create_buffer_object(acpi_gbl_integer_byte_width);
197*4882a593Smuzhiyun 		if (!return_desc) {
198*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_NO_MEMORY);
199*4882a593Smuzhiyun 		}
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 		/* Copy the integer to the buffer, LSB first */
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 		new_buf = return_desc->buffer.pointer;
204*4882a593Smuzhiyun 		memcpy(new_buf, &obj_desc->integer.value,
205*4882a593Smuzhiyun 		       acpi_gbl_integer_byte_width);
206*4882a593Smuzhiyun 		break;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	case ACPI_TYPE_STRING:
209*4882a593Smuzhiyun 		/*
210*4882a593Smuzhiyun 		 * Create a new Buffer object
211*4882a593Smuzhiyun 		 * Size will be the string length
212*4882a593Smuzhiyun 		 *
213*4882a593Smuzhiyun 		 * NOTE: Add one to the string length to include the null terminator.
214*4882a593Smuzhiyun 		 * The ACPI spec is unclear on this subject, but there is existing
215*4882a593Smuzhiyun 		 * ASL/AML code that depends on the null being transferred to the new
216*4882a593Smuzhiyun 		 * buffer.
217*4882a593Smuzhiyun 		 */
218*4882a593Smuzhiyun 		return_desc = acpi_ut_create_buffer_object((acpi_size)
219*4882a593Smuzhiyun 							   obj_desc->string.
220*4882a593Smuzhiyun 							   length + 1);
221*4882a593Smuzhiyun 		if (!return_desc) {
222*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_NO_MEMORY);
223*4882a593Smuzhiyun 		}
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 		/* Copy the string to the buffer */
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 		new_buf = return_desc->buffer.pointer;
228*4882a593Smuzhiyun 		strncpy((char *)new_buf, (char *)obj_desc->string.pointer,
229*4882a593Smuzhiyun 			obj_desc->string.length);
230*4882a593Smuzhiyun 		break;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	default:
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_TYPE);
235*4882a593Smuzhiyun 	}
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	/* Mark buffer initialized */
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	return_desc->common.flags |= AOPOBJ_DATA_VALID;
240*4882a593Smuzhiyun 	*result_desc = return_desc;
241*4882a593Smuzhiyun 	return_ACPI_STATUS(AE_OK);
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun /*******************************************************************************
245*4882a593Smuzhiyun  *
246*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_convert_to_ascii
247*4882a593Smuzhiyun  *
248*4882a593Smuzhiyun  * PARAMETERS:  integer         - Value to be converted
249*4882a593Smuzhiyun  *              base            - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
250*4882a593Smuzhiyun  *              string          - Where the string is returned
251*4882a593Smuzhiyun  *              data_width      - Size of data item to be converted, in bytes
252*4882a593Smuzhiyun  *
253*4882a593Smuzhiyun  * RETURN:      Actual string length
254*4882a593Smuzhiyun  *
255*4882a593Smuzhiyun  * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
256*4882a593Smuzhiyun  *
257*4882a593Smuzhiyun  ******************************************************************************/
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun static u32
acpi_ex_convert_to_ascii(u64 integer,u16 base,u8 * string,u8 data_width)260*4882a593Smuzhiyun acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun 	u64 digit;
263*4882a593Smuzhiyun 	u32 i;
264*4882a593Smuzhiyun 	u32 j;
265*4882a593Smuzhiyun 	u32 k = 0;
266*4882a593Smuzhiyun 	u32 hex_length;
267*4882a593Smuzhiyun 	u32 decimal_length;
268*4882a593Smuzhiyun 	u32 remainder;
269*4882a593Smuzhiyun 	u8 supress_zeros;
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	ACPI_FUNCTION_ENTRY();
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	switch (base) {
274*4882a593Smuzhiyun 	case 10:
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 		/* Setup max length for the decimal number */
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 		switch (data_width) {
279*4882a593Smuzhiyun 		case 1:
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 			decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
282*4882a593Smuzhiyun 			break;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 		case 4:
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 			decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
287*4882a593Smuzhiyun 			break;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 		case 8:
290*4882a593Smuzhiyun 		default:
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 			decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
293*4882a593Smuzhiyun 			break;
294*4882a593Smuzhiyun 		}
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 		supress_zeros = TRUE;	/* No leading zeros */
297*4882a593Smuzhiyun 		remainder = 0;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 		for (i = decimal_length; i > 0; i--) {
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 			/* Divide by nth factor of 10 */
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 			digit = integer;
304*4882a593Smuzhiyun 			for (j = 0; j < i; j++) {
305*4882a593Smuzhiyun 				(void)acpi_ut_short_divide(digit, 10, &digit,
306*4882a593Smuzhiyun 							   &remainder);
307*4882a593Smuzhiyun 			}
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 			/* Handle leading zeros */
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 			if (remainder != 0) {
312*4882a593Smuzhiyun 				supress_zeros = FALSE;
313*4882a593Smuzhiyun 			}
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 			if (!supress_zeros) {
316*4882a593Smuzhiyun 				string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
317*4882a593Smuzhiyun 				k++;
318*4882a593Smuzhiyun 			}
319*4882a593Smuzhiyun 		}
320*4882a593Smuzhiyun 		break;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	case 16:
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 		/* hex_length: 2 ascii hex chars per data byte */
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 		hex_length = (data_width * 2);
327*4882a593Smuzhiyun 		for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 			/* Get one hex digit, most significant digits first */
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 			string[k] = (u8)
332*4882a593Smuzhiyun 			    acpi_ut_hex_to_ascii_char(integer, ACPI_MUL_4(j));
333*4882a593Smuzhiyun 			k++;
334*4882a593Smuzhiyun 		}
335*4882a593Smuzhiyun 		break;
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	default:
338*4882a593Smuzhiyun 		return (0);
339*4882a593Smuzhiyun 	}
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	/*
342*4882a593Smuzhiyun 	 * Since leading zeros are suppressed, we must check for the case where
343*4882a593Smuzhiyun 	 * the integer equals 0
344*4882a593Smuzhiyun 	 *
345*4882a593Smuzhiyun 	 * Finally, null terminate the string and return the length
346*4882a593Smuzhiyun 	 */
347*4882a593Smuzhiyun 	if (!k) {
348*4882a593Smuzhiyun 		string[0] = ACPI_ASCII_ZERO;
349*4882a593Smuzhiyun 		k = 1;
350*4882a593Smuzhiyun 	}
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	string[k] = 0;
353*4882a593Smuzhiyun 	return ((u32) k);
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun /*******************************************************************************
357*4882a593Smuzhiyun  *
358*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_convert_to_string
359*4882a593Smuzhiyun  *
360*4882a593Smuzhiyun  * PARAMETERS:  obj_desc        - Object to be converted. Must be an
361*4882a593Smuzhiyun  *                                Integer, Buffer, or String
362*4882a593Smuzhiyun  *              result_desc     - Where the string object is returned
363*4882a593Smuzhiyun  *              type            - String flags (base and conversion type)
364*4882a593Smuzhiyun  *
365*4882a593Smuzhiyun  * RETURN:      Status
366*4882a593Smuzhiyun  *
367*4882a593Smuzhiyun  * DESCRIPTION: Convert an ACPI Object to a string. Supports both implicit
368*4882a593Smuzhiyun  *              and explicit conversions and related rules.
369*4882a593Smuzhiyun  *
370*4882a593Smuzhiyun  ******************************************************************************/
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun acpi_status
acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,union acpi_operand_object ** result_desc,u32 type)373*4882a593Smuzhiyun acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
374*4882a593Smuzhiyun 			  union acpi_operand_object ** result_desc, u32 type)
375*4882a593Smuzhiyun {
376*4882a593Smuzhiyun 	union acpi_operand_object *return_desc;
377*4882a593Smuzhiyun 	u8 *new_buf;
378*4882a593Smuzhiyun 	u32 i;
379*4882a593Smuzhiyun 	u32 string_length = 0;
380*4882a593Smuzhiyun 	u16 base = 16;
381*4882a593Smuzhiyun 	u8 separator = ',';
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	switch (obj_desc->common.type) {
386*4882a593Smuzhiyun 	case ACPI_TYPE_STRING:
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 		/* No conversion necessary */
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 		*result_desc = obj_desc;
391*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_OK);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	case ACPI_TYPE_INTEGER:
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 		switch (type) {
396*4882a593Smuzhiyun 		case ACPI_EXPLICIT_CONVERT_DECIMAL:
397*4882a593Smuzhiyun 			/*
398*4882a593Smuzhiyun 			 * From to_decimal_string, integer source.
399*4882a593Smuzhiyun 			 *
400*4882a593Smuzhiyun 			 * Make room for the maximum decimal number size
401*4882a593Smuzhiyun 			 */
402*4882a593Smuzhiyun 			string_length = ACPI_MAX_DECIMAL_DIGITS;
403*4882a593Smuzhiyun 			base = 10;
404*4882a593Smuzhiyun 			break;
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 		default:
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun 			/* Two hex string characters for each integer byte */
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 			string_length = ACPI_MUL_2(acpi_gbl_integer_byte_width);
411*4882a593Smuzhiyun 			break;
412*4882a593Smuzhiyun 		}
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 		/*
415*4882a593Smuzhiyun 		 * Create a new String
416*4882a593Smuzhiyun 		 * Need enough space for one ASCII integer (plus null terminator)
417*4882a593Smuzhiyun 		 */
418*4882a593Smuzhiyun 		return_desc =
419*4882a593Smuzhiyun 		    acpi_ut_create_string_object((acpi_size)string_length);
420*4882a593Smuzhiyun 		if (!return_desc) {
421*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_NO_MEMORY);
422*4882a593Smuzhiyun 		}
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 		new_buf = return_desc->buffer.pointer;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 		/* Convert integer to string */
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 		string_length =
429*4882a593Smuzhiyun 		    acpi_ex_convert_to_ascii(obj_desc->integer.value, base,
430*4882a593Smuzhiyun 					     new_buf,
431*4882a593Smuzhiyun 					     acpi_gbl_integer_byte_width);
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 		/* Null terminate at the correct place */
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 		return_desc->string.length = string_length;
436*4882a593Smuzhiyun 		new_buf[string_length] = 0;
437*4882a593Smuzhiyun 		break;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	case ACPI_TYPE_BUFFER:
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 		/* Setup string length, base, and separator */
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 		switch (type) {
444*4882a593Smuzhiyun 		case ACPI_EXPLICIT_CONVERT_DECIMAL:	/* Used by to_decimal_string */
445*4882a593Smuzhiyun 			/*
446*4882a593Smuzhiyun 			 * Explicit conversion from the to_decimal_string ASL operator.
447*4882a593Smuzhiyun 			 *
448*4882a593Smuzhiyun 			 * From ACPI: "If the input is a buffer, it is converted to a
449*4882a593Smuzhiyun 			 * a string of decimal values separated by commas."
450*4882a593Smuzhiyun 			 */
451*4882a593Smuzhiyun 			base = 10;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 			/*
454*4882a593Smuzhiyun 			 * Calculate the final string length. Individual string values
455*4882a593Smuzhiyun 			 * are variable length (include separator for each)
456*4882a593Smuzhiyun 			 */
457*4882a593Smuzhiyun 			for (i = 0; i < obj_desc->buffer.length; i++) {
458*4882a593Smuzhiyun 				if (obj_desc->buffer.pointer[i] >= 100) {
459*4882a593Smuzhiyun 					string_length += 4;
460*4882a593Smuzhiyun 				} else if (obj_desc->buffer.pointer[i] >= 10) {
461*4882a593Smuzhiyun 					string_length += 3;
462*4882a593Smuzhiyun 				} else {
463*4882a593Smuzhiyun 					string_length += 2;
464*4882a593Smuzhiyun 				}
465*4882a593Smuzhiyun 			}
466*4882a593Smuzhiyun 			break;
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 		case ACPI_IMPLICIT_CONVERT_HEX:
469*4882a593Smuzhiyun 			/*
470*4882a593Smuzhiyun 			 * Implicit buffer-to-string conversion
471*4882a593Smuzhiyun 			 *
472*4882a593Smuzhiyun 			 * From the ACPI spec:
473*4882a593Smuzhiyun 			 * "The entire contents of the buffer are converted to a string of
474*4882a593Smuzhiyun 			 * two-character hexadecimal numbers, each separated by a space."
475*4882a593Smuzhiyun 			 *
476*4882a593Smuzhiyun 			 * Each hex number is prefixed with 0x (11/2018)
477*4882a593Smuzhiyun 			 */
478*4882a593Smuzhiyun 			separator = ' ';
479*4882a593Smuzhiyun 			string_length = (obj_desc->buffer.length * 5);
480*4882a593Smuzhiyun 			break;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 		case ACPI_EXPLICIT_CONVERT_HEX:
483*4882a593Smuzhiyun 			/*
484*4882a593Smuzhiyun 			 * Explicit conversion from the to_hex_string ASL operator.
485*4882a593Smuzhiyun 			 *
486*4882a593Smuzhiyun 			 * From ACPI: "If Data is a buffer, it is converted to a string of
487*4882a593Smuzhiyun 			 * hexadecimal values separated by commas."
488*4882a593Smuzhiyun 			 *
489*4882a593Smuzhiyun 			 * Each hex number is prefixed with 0x (11/2018)
490*4882a593Smuzhiyun 			 */
491*4882a593Smuzhiyun 			separator = ',';
492*4882a593Smuzhiyun 			string_length = (obj_desc->buffer.length * 5);
493*4882a593Smuzhiyun 			break;
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 		default:
496*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_BAD_PARAMETER);
497*4882a593Smuzhiyun 		}
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 		/*
500*4882a593Smuzhiyun 		 * Create a new string object and string buffer
501*4882a593Smuzhiyun 		 * (-1 because of extra separator included in string_length from above)
502*4882a593Smuzhiyun 		 * Allow creation of zero-length strings from zero-length buffers.
503*4882a593Smuzhiyun 		 */
504*4882a593Smuzhiyun 		if (string_length) {
505*4882a593Smuzhiyun 			string_length--;
506*4882a593Smuzhiyun 		}
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 		return_desc =
509*4882a593Smuzhiyun 		    acpi_ut_create_string_object((acpi_size)string_length);
510*4882a593Smuzhiyun 		if (!return_desc) {
511*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_NO_MEMORY);
512*4882a593Smuzhiyun 		}
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 		new_buf = return_desc->buffer.pointer;
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 		/*
517*4882a593Smuzhiyun 		 * Convert buffer bytes to hex or decimal values
518*4882a593Smuzhiyun 		 * (separated by commas or spaces)
519*4882a593Smuzhiyun 		 */
520*4882a593Smuzhiyun 		for (i = 0; i < obj_desc->buffer.length; i++) {
521*4882a593Smuzhiyun 			if (base == 16) {
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 				/* Emit 0x prefix for explicit/implicit hex conversion */
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 				*new_buf++ = '0';
526*4882a593Smuzhiyun 				*new_buf++ = 'x';
527*4882a593Smuzhiyun 			}
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 			new_buf += acpi_ex_convert_to_ascii((u64) obj_desc->
530*4882a593Smuzhiyun 							    buffer.pointer[i],
531*4882a593Smuzhiyun 							    base, new_buf, 1);
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun 			/* Each digit is separated by either a comma or space */
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 			*new_buf++ = separator;
536*4882a593Smuzhiyun 		}
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 		/*
539*4882a593Smuzhiyun 		 * Null terminate the string
540*4882a593Smuzhiyun 		 * (overwrites final comma/space from above)
541*4882a593Smuzhiyun 		 */
542*4882a593Smuzhiyun 		if (obj_desc->buffer.length) {
543*4882a593Smuzhiyun 			new_buf--;
544*4882a593Smuzhiyun 		}
545*4882a593Smuzhiyun 		*new_buf = 0;
546*4882a593Smuzhiyun 		break;
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	default:
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_TYPE);
551*4882a593Smuzhiyun 	}
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	*result_desc = return_desc;
554*4882a593Smuzhiyun 	return_ACPI_STATUS(AE_OK);
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun /*******************************************************************************
558*4882a593Smuzhiyun  *
559*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_convert_to_target_type
560*4882a593Smuzhiyun  *
561*4882a593Smuzhiyun  * PARAMETERS:  destination_type    - Current type of the destination
562*4882a593Smuzhiyun  *              source_desc         - Source object to be converted.
563*4882a593Smuzhiyun  *              result_desc         - Where the converted object is returned
564*4882a593Smuzhiyun  *              walk_state          - Current method state
565*4882a593Smuzhiyun  *
566*4882a593Smuzhiyun  * RETURN:      Status
567*4882a593Smuzhiyun  *
568*4882a593Smuzhiyun  * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
569*4882a593Smuzhiyun  *
570*4882a593Smuzhiyun  ******************************************************************************/
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 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)573*4882a593Smuzhiyun acpi_ex_convert_to_target_type(acpi_object_type destination_type,
574*4882a593Smuzhiyun 			       union acpi_operand_object *source_desc,
575*4882a593Smuzhiyun 			       union acpi_operand_object **result_desc,
576*4882a593Smuzhiyun 			       struct acpi_walk_state *walk_state)
577*4882a593Smuzhiyun {
578*4882a593Smuzhiyun 	acpi_status status = AE_OK;
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ex_convert_to_target_type);
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 	/* Default behavior */
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	*result_desc = source_desc;
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	/*
587*4882a593Smuzhiyun 	 * If required by the target,
588*4882a593Smuzhiyun 	 * perform implicit conversion on the source before we store it.
589*4882a593Smuzhiyun 	 */
590*4882a593Smuzhiyun 	switch (GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args)) {
591*4882a593Smuzhiyun 	case ARGI_SIMPLE_TARGET:
592*4882a593Smuzhiyun 	case ARGI_FIXED_TARGET:
593*4882a593Smuzhiyun 	case ARGI_INTEGER_REF:	/* Handles Increment, Decrement cases */
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 		switch (destination_type) {
596*4882a593Smuzhiyun 		case ACPI_TYPE_LOCAL_REGION_FIELD:
597*4882a593Smuzhiyun 			/*
598*4882a593Smuzhiyun 			 * Named field can always handle conversions
599*4882a593Smuzhiyun 			 */
600*4882a593Smuzhiyun 			break;
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 		default:
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 			/* No conversion allowed for these types */
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 			if (destination_type != source_desc->common.type) {
607*4882a593Smuzhiyun 				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
608*4882a593Smuzhiyun 						  "Explicit operator, will store (%s) over existing type (%s)\n",
609*4882a593Smuzhiyun 						  acpi_ut_get_object_type_name
610*4882a593Smuzhiyun 						  (source_desc),
611*4882a593Smuzhiyun 						  acpi_ut_get_type_name
612*4882a593Smuzhiyun 						  (destination_type)));
613*4882a593Smuzhiyun 				status = AE_TYPE;
614*4882a593Smuzhiyun 			}
615*4882a593Smuzhiyun 		}
616*4882a593Smuzhiyun 		break;
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	case ARGI_TARGETREF:
619*4882a593Smuzhiyun 	case ARGI_STORE_TARGET:
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 		switch (destination_type) {
622*4882a593Smuzhiyun 		case ACPI_TYPE_INTEGER:
623*4882a593Smuzhiyun 		case ACPI_TYPE_BUFFER_FIELD:
624*4882a593Smuzhiyun 		case ACPI_TYPE_LOCAL_BANK_FIELD:
625*4882a593Smuzhiyun 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
626*4882a593Smuzhiyun 			/*
627*4882a593Smuzhiyun 			 * These types require an Integer operand. We can convert
628*4882a593Smuzhiyun 			 * a Buffer or a String to an Integer if necessary.
629*4882a593Smuzhiyun 			 */
630*4882a593Smuzhiyun 			status =
631*4882a593Smuzhiyun 			    acpi_ex_convert_to_integer(source_desc, result_desc,
632*4882a593Smuzhiyun 						       ACPI_IMPLICIT_CONVERSION);
633*4882a593Smuzhiyun 			break;
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun 		case ACPI_TYPE_STRING:
636*4882a593Smuzhiyun 			/*
637*4882a593Smuzhiyun 			 * The operand must be a String. We can convert an
638*4882a593Smuzhiyun 			 * Integer or Buffer if necessary
639*4882a593Smuzhiyun 			 */
640*4882a593Smuzhiyun 			status =
641*4882a593Smuzhiyun 			    acpi_ex_convert_to_string(source_desc, result_desc,
642*4882a593Smuzhiyun 						      ACPI_IMPLICIT_CONVERT_HEX);
643*4882a593Smuzhiyun 			break;
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 		case ACPI_TYPE_BUFFER:
646*4882a593Smuzhiyun 			/*
647*4882a593Smuzhiyun 			 * The operand must be a Buffer. We can convert an
648*4882a593Smuzhiyun 			 * Integer or String if necessary
649*4882a593Smuzhiyun 			 */
650*4882a593Smuzhiyun 			status =
651*4882a593Smuzhiyun 			    acpi_ex_convert_to_buffer(source_desc, result_desc);
652*4882a593Smuzhiyun 			break;
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun 		default:
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun 			ACPI_ERROR((AE_INFO,
657*4882a593Smuzhiyun 				    "Bad destination type during conversion: 0x%X",
658*4882a593Smuzhiyun 				    destination_type));
659*4882a593Smuzhiyun 			status = AE_AML_INTERNAL;
660*4882a593Smuzhiyun 			break;
661*4882a593Smuzhiyun 		}
662*4882a593Smuzhiyun 		break;
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun 	case ARGI_REFERENCE:
665*4882a593Smuzhiyun 		/*
666*4882a593Smuzhiyun 		 * create_xxxx_field cases - we are storing the field object into the name
667*4882a593Smuzhiyun 		 */
668*4882a593Smuzhiyun 		break;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	default:
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO,
673*4882a593Smuzhiyun 			    "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
674*4882a593Smuzhiyun 			    GET_CURRENT_ARG_TYPE(walk_state->op_info->
675*4882a593Smuzhiyun 						 runtime_args),
676*4882a593Smuzhiyun 			    walk_state->opcode,
677*4882a593Smuzhiyun 			    acpi_ut_get_type_name(destination_type)));
678*4882a593Smuzhiyun 		status = AE_AML_INTERNAL;
679*4882a593Smuzhiyun 	}
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun 	/*
682*4882a593Smuzhiyun 	 * Source-to-Target conversion semantics:
683*4882a593Smuzhiyun 	 *
684*4882a593Smuzhiyun 	 * If conversion to the target type cannot be performed, then simply
685*4882a593Smuzhiyun 	 * overwrite the target with the new object and type.
686*4882a593Smuzhiyun 	 */
687*4882a593Smuzhiyun 	if (status == AE_TYPE) {
688*4882a593Smuzhiyun 		status = AE_OK;
689*4882a593Smuzhiyun 	}
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
692*4882a593Smuzhiyun }
693