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