blob: 66437f5cc904b6289975b2b500343576c1fe65c3 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/******************************************************************************
2 *
3 * Module Name: exconvrt - Object conversion routines
4 *
5 *****************************************************************************/
6
7/*
Bob Mooreda6f8322018-01-04 10:06:38 -08008 * Copyright (C) 2000 - 2018, Intel Corp.
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <acpi/acpi.h>
Len Browne2f7a772009-01-09 00:30:03 -050045#include "accommon.h"
46#include "acinterp.h"
47#include "amlcode.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#define _COMPONENT ACPI_EXECUTER
Len Brown4be44fc2005-08-05 00:44:28 -040050ACPI_MODULE_NAME("exconvrt")
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Robert Moore44f6c012005-04-18 22:49:35 -040052/* Local prototypes */
Robert Moore44f6c012005-04-18 22:49:35 -040053static u32
Bob Moore5df7e6c2010-01-21 10:06:32 +080054acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ex_convert_to_integer
59 *
Bob Moorefe97d282017-09-20 10:00:36 +080060 * PARAMETERS: obj_desc - Object to be converted. Must be an
61 * Integer, Buffer, or String
62 * result_desc - Where the new Integer object is returned
63 * implicit_conversion - Used for string conversion
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 *
65 * RETURN: Status
66 *
67 * DESCRIPTION: Convert an ACPI Object to an integer.
68 *
69 ******************************************************************************/
70
71acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -040072acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
Bob Moorefe97d282017-09-20 10:00:36 +080073 union acpi_operand_object **result_desc,
74 u32 implicit_conversion)
Linus Torvalds1da177e2005-04-16 15:20:36 -070075{
Len Brown4be44fc2005-08-05 00:44:28 -040076 union acpi_operand_object *return_desc;
77 u8 *pointer;
Bob Moore5df7e6c2010-01-21 10:06:32 +080078 u64 result;
Len Brown4be44fc2005-08-05 00:44:28 -040079 u32 i;
80 u32 count;
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
Bob Mooreb229cf92006-04-21 17:15:00 -040082 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
Bob Moore3371c192009-02-18 14:44:03 +080084 switch (obj_desc->common.type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 case ACPI_TYPE_INTEGER:
86
87 /* No conversion necessary */
88
89 *result_desc = obj_desc;
Len Brown4be44fc2005-08-05 00:44:28 -040090 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
92 case ACPI_TYPE_BUFFER:
93 case ACPI_TYPE_STRING:
94
95 /* Note: Takes advantage of common buffer/string fields */
96
97 pointer = obj_desc->buffer.pointer;
Len Brown4be44fc2005-08-05 00:44:28 -040098 count = obj_desc->buffer.length;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 break;
100
101 default:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000102
Len Brown4be44fc2005-08-05 00:44:28 -0400103 return_ACPI_STATUS(AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 }
105
106 /*
Bob Moore2425a092008-09-27 10:42:02 +0800107 * Convert the buffer/string to an integer. Note that both buffers and
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 * strings are treated as raw data - we don't convert ascii to hex for
109 * strings.
110 *
111 * There are two terminating conditions for the loop:
112 * 1) The size of an integer has been reached, or
113 * 2) The end of the buffer or string has been reached
114 */
115 result = 0;
116
Robert Moore44f6c012005-04-18 22:49:35 -0400117 /* String conversion is different than Buffer conversion */
118
Bob Moore3371c192009-02-18 14:44:03 +0800119 switch (obj_desc->common.type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 case ACPI_TYPE_STRING:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 /*
122 * Convert string to an integer - for most cases, the string must be
Bob Moore2425a092008-09-27 10:42:02 +0800123 * hexadecimal as per the ACPI specification. The only exception (as
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 * of ACPI 3.0) is that the to_integer() operator allows both decimal
125 * and hexadecimal strings (hex prefixed with "0x").
Bob Moorefe97d282017-09-20 10:00:36 +0800126 *
127 * Explicit conversion is used only by to_integer.
128 * All other string-to-integer conversions are implicit conversions.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 */
Bob Moorefe97d282017-09-20 10:00:36 +0800130 if (implicit_conversion) {
131 result =
132 acpi_ut_implicit_strtoul64(ACPI_CAST_PTR
133 (char, pointer));
134 } else {
135 result =
136 acpi_ut_explicit_strtoul64(ACPI_CAST_PTR
137 (char, pointer));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 }
139 break;
140
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141 case ACPI_TYPE_BUFFER:
142
143 /* Check for zero-length buffer */
144
145 if (!count) {
Len Brown4be44fc2005-08-05 00:44:28 -0400146 return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 }
148
149 /* Transfer no more than an integer's worth of data */
150
151 if (count > acpi_gbl_integer_byte_width) {
152 count = acpi_gbl_integer_byte_width;
153 }
154
155 /*
156 * Convert buffer to an integer - we simply grab enough raw data
157 * from the buffer to fill an integer
158 */
159 for (i = 0; i < count; i++) {
160 /*
161 * Get next byte and shift it into the Result.
162 * Little endian is used, meaning that the first byte of the buffer
163 * is the LSB of the integer
164 */
Bob Moore5df7e6c2010-01-21 10:06:32 +0800165 result |= (((u64) pointer[i]) << (i * 8));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 }
167 break;
168
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 default:
Bob Moore2425a092008-09-27 10:42:02 +0800170
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 /* No other types can get here */
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000172
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 break;
174 }
175
Robert Moore44f6c012005-04-18 22:49:35 -0400176 /* Create a new integer */
177
Bob Mooredc95a272009-11-12 09:52:45 +0800178 return_desc = acpi_ut_create_integer_object(result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 if (!return_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -0400180 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 }
182
Bob Mooref6dd9222006-07-07 20:44:38 -0400183 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
184 ACPI_FORMAT_UINT64(result)));
185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 /* Save the Result */
187
Bob Mooreef42e532012-12-31 00:07:18 +0000188 (void)acpi_ex_truncate_for32bit_table(return_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 *result_desc = return_desc;
Len Brown4be44fc2005-08-05 00:44:28 -0400190 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191}
192
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193/*******************************************************************************
194 *
195 * FUNCTION: acpi_ex_convert_to_buffer
196 *
Bob Moore2425a092008-09-27 10:42:02 +0800197 * PARAMETERS: obj_desc - Object to be converted. Must be an
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 * Integer, Buffer, or String
199 * result_desc - Where the new buffer object is returned
200 *
201 * RETURN: Status
202 *
203 * DESCRIPTION: Convert an ACPI Object to a Buffer
204 *
205 ******************************************************************************/
206
207acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400208acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
209 union acpi_operand_object **result_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210{
Len Brown4be44fc2005-08-05 00:44:28 -0400211 union acpi_operand_object *return_desc;
212 u8 *new_buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213
Bob Mooreb229cf92006-04-21 17:15:00 -0400214 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
Bob Moore3371c192009-02-18 14:44:03 +0800216 switch (obj_desc->common.type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217 case ACPI_TYPE_BUFFER:
218
219 /* No conversion necessary */
220
221 *result_desc = obj_desc;
Len Brown4be44fc2005-08-05 00:44:28 -0400222 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223
224 case ACPI_TYPE_INTEGER:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 /*
226 * Create a new Buffer object.
227 * Need enough space for one integer
228 */
Len Brown4be44fc2005-08-05 00:44:28 -0400229 return_desc =
230 acpi_ut_create_buffer_object(acpi_gbl_integer_byte_width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 if (!return_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -0400232 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 }
234
235 /* Copy the integer to the buffer, LSB first */
236
237 new_buf = return_desc->buffer.pointer;
Bob Moore1fad8732015-12-29 13:54:36 +0800238 memcpy(new_buf, &obj_desc->integer.value,
239 acpi_gbl_integer_byte_width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 break;
241
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242 case ACPI_TYPE_STRING:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 /*
244 * Create a new Buffer object
245 * Size will be the string length
246 *
247 * NOTE: Add one to the string length to include the null terminator.
248 * The ACPI spec is unclear on this subject, but there is existing
249 * ASL/AML code that depends on the null being transferred to the new
250 * buffer.
251 */
Len Brown4be44fc2005-08-05 00:44:28 -0400252 return_desc = acpi_ut_create_buffer_object((acpi_size)
253 obj_desc->string.
254 length + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 if (!return_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -0400256 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 }
258
259 /* Copy the string to the buffer */
260
261 new_buf = return_desc->buffer.pointer;
Bob Moore4fa46162015-07-01 14:45:11 +0800262 strncpy((char *)new_buf, (char *)obj_desc->string.pointer,
263 obj_desc->string.length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 break;
265
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 default:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000267
Len Brown4be44fc2005-08-05 00:44:28 -0400268 return_ACPI_STATUS(AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 }
270
271 /* Mark buffer initialized */
272
273 return_desc->common.flags |= AOPOBJ_DATA_VALID;
274 *result_desc = return_desc;
Len Brown4be44fc2005-08-05 00:44:28 -0400275 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276}
277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278/*******************************************************************************
279 *
280 * FUNCTION: acpi_ex_convert_to_ascii
281 *
Bob Mooreba494be2012-07-12 09:40:10 +0800282 * PARAMETERS: integer - Value to be converted
283 * base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
284 * string - Where the string is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 * data_width - Size of data item to be converted, in bytes
286 *
287 * RETURN: Actual string length
288 *
289 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
290 *
291 ******************************************************************************/
292
Robert Moore44f6c012005-04-18 22:49:35 -0400293static u32
Bob Moore5df7e6c2010-01-21 10:06:32 +0800294acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295{
Bob Moore5df7e6c2010-01-21 10:06:32 +0800296 u64 digit;
Bob Moore67a119f2008-06-10 13:42:13 +0800297 u32 i;
298 u32 j;
299 u32 k = 0;
300 u32 hex_length;
301 u32 decimal_length;
Len Brown4be44fc2005-08-05 00:44:28 -0400302 u32 remainder;
303 u8 supress_zeros;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304
Len Brown4be44fc2005-08-05 00:44:28 -0400305 ACPI_FUNCTION_ENTRY();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306
307 switch (base) {
308 case 10:
309
310 /* Setup max length for the decimal number */
311
312 switch (data_width) {
313 case 1:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000314
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
316 break;
317
318 case 4:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000319
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
321 break;
322
323 case 8:
324 default:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
327 break;
328 }
329
Len Brown4be44fc2005-08-05 00:44:28 -0400330 supress_zeros = TRUE; /* No leading zeros */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 remainder = 0;
332
333 for (i = decimal_length; i > 0; i--) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400334
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 /* Divide by nth factor of 10 */
336
337 digit = integer;
338 for (j = 0; j < i; j++) {
Len Brown4be44fc2005-08-05 00:44:28 -0400339 (void)acpi_ut_short_divide(digit, 10, &digit,
340 &remainder);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 }
342
343 /* Handle leading zeros */
344
345 if (remainder != 0) {
346 supress_zeros = FALSE;
347 }
348
349 if (!supress_zeros) {
350 string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
351 k++;
352 }
353 }
354 break;
355
356 case 16:
357
Robert Moore44f6c012005-04-18 22:49:35 -0400358 /* hex_length: 2 ascii hex chars per data byte */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
Bob Moore67a119f2008-06-10 13:42:13 +0800360 hex_length = ACPI_MUL_2(data_width);
Len Brown4be44fc2005-08-05 00:44:28 -0400361 for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400362
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 /* Get one hex digit, most significant digits first */
364
Bob Moore1fad8732015-12-29 13:54:36 +0800365 string[k] = (u8)
366 acpi_ut_hex_to_ascii_char(integer, ACPI_MUL_4(j));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 k++;
368 }
369 break;
370
371 default:
372 return (0);
373 }
374
375 /*
Bob Moore2425a092008-09-27 10:42:02 +0800376 * Since leading zeros are suppressed, we must check for the case where
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 * the integer equals 0
378 *
379 * Finally, null terminate the string and return the length
380 */
381 if (!k) {
Len Brown4be44fc2005-08-05 00:44:28 -0400382 string[0] = ACPI_ASCII_ZERO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 k = 1;
384 }
385
Len Brown4be44fc2005-08-05 00:44:28 -0400386 string[k] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 return ((u32) k);
388}
389
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390/*******************************************************************************
391 *
392 * FUNCTION: acpi_ex_convert_to_string
393 *
Bob Moore2425a092008-09-27 10:42:02 +0800394 * PARAMETERS: obj_desc - Object to be converted. Must be an
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 * Integer, Buffer, or String
396 * result_desc - Where the string object is returned
Bob Mooreba494be2012-07-12 09:40:10 +0800397 * type - String flags (base and conversion type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 *
399 * RETURN: Status
400 *
401 * DESCRIPTION: Convert an ACPI Object to a string
402 *
403 ******************************************************************************/
404
405acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400406acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
407 union acpi_operand_object ** result_desc, u32 type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408{
Len Brown4be44fc2005-08-05 00:44:28 -0400409 union acpi_operand_object *return_desc;
410 u8 *new_buf;
411 u32 i;
412 u32 string_length = 0;
413 u16 base = 16;
414 u8 separator = ',';
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415
Bob Mooreb229cf92006-04-21 17:15:00 -0400416 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
Bob Moore3371c192009-02-18 14:44:03 +0800418 switch (obj_desc->common.type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 case ACPI_TYPE_STRING:
420
421 /* No conversion necessary */
422
423 *result_desc = obj_desc;
Len Brown4be44fc2005-08-05 00:44:28 -0400424 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
426 case ACPI_TYPE_INTEGER:
427
428 switch (type) {
429 case ACPI_EXPLICIT_CONVERT_DECIMAL:
430
431 /* Make room for maximum decimal number */
432
433 string_length = ACPI_MAX_DECIMAL_DIGITS;
434 base = 10;
435 break;
436
437 default:
438
439 /* Two hex string characters for each integer byte */
440
Len Brown4be44fc2005-08-05 00:44:28 -0400441 string_length = ACPI_MUL_2(acpi_gbl_integer_byte_width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 break;
443 }
444
445 /*
446 * Create a new String
447 * Need enough space for one ASCII integer (plus null terminator)
448 */
Len Brown4be44fc2005-08-05 00:44:28 -0400449 return_desc =
Lv Zhengf5c1e1c2016-05-05 12:57:53 +0800450 acpi_ut_create_string_object((acpi_size)string_length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 if (!return_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -0400452 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 }
454
455 new_buf = return_desc->buffer.pointer;
456
457 /* Convert integer to string */
458
Len Brown4be44fc2005-08-05 00:44:28 -0400459 string_length =
460 acpi_ex_convert_to_ascii(obj_desc->integer.value, base,
461 new_buf,
462 acpi_gbl_integer_byte_width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
464 /* Null terminate at the correct place */
465
466 return_desc->string.length = string_length;
Len Brown4be44fc2005-08-05 00:44:28 -0400467 new_buf[string_length] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 break;
469
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 case ACPI_TYPE_BUFFER:
471
472 /* Setup string length, base, and separator */
473
474 switch (type) {
Len Brown4be44fc2005-08-05 00:44:28 -0400475 case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 /*
477 * From ACPI: "If Data is a buffer, it is converted to a string of
478 * decimal values separated by commas."
479 */
480 base = 10;
481
482 /*
Bob Moore2425a092008-09-27 10:42:02 +0800483 * Calculate the final string length. Individual string values
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 * are variable length (include separator for each)
485 */
486 for (i = 0; i < obj_desc->buffer.length; i++) {
487 if (obj_desc->buffer.pointer[i] >= 100) {
488 string_length += 4;
Len Brown4be44fc2005-08-05 00:44:28 -0400489 } else if (obj_desc->buffer.pointer[i] >= 10) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 string_length += 3;
Len Brown4be44fc2005-08-05 00:44:28 -0400491 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 string_length += 2;
493 }
494 }
495 break;
496
497 case ACPI_IMPLICIT_CONVERT_HEX:
498 /*
499 * From the ACPI spec:
500 *"The entire contents of the buffer are converted to a string of
501 * two-character hexadecimal numbers, each separated by a space."
502 */
503 separator = ' ';
504 string_length = (obj_desc->buffer.length * 3);
505 break;
506
Len Brown4be44fc2005-08-05 00:44:28 -0400507 case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 /*
509 * From ACPI: "If Data is a buffer, it is converted to a string of
510 * hexadecimal values separated by commas."
511 */
512 string_length = (obj_desc->buffer.length * 3);
513 break;
514
515 default:
Len Brown4be44fc2005-08-05 00:44:28 -0400516 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 }
518
519 /*
Bob Moorec51a4de2005-11-17 13:07:00 -0500520 * Create a new string object and string buffer
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 * (-1 because of extra separator included in string_length from above)
Bob Moore4ca846e2008-09-27 13:27:51 +0800522 * Allow creation of zero-length strings from zero-length buffers.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 */
Bob Moore4ca846e2008-09-27 13:27:51 +0800524 if (string_length) {
525 string_length--;
526 }
527
Lv Zheng1f86e8c2012-10-31 02:25:45 +0000528 return_desc =
Lv Zhengf5c1e1c2016-05-05 12:57:53 +0800529 acpi_ut_create_string_object((acpi_size)string_length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 if (!return_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -0400531 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 }
533
534 new_buf = return_desc->buffer.pointer;
535
536 /*
537 * Convert buffer bytes to hex or decimal values
538 * (separated by commas or spaces)
539 */
540 for (i = 0; i < obj_desc->buffer.length; i++) {
Bob Moore5df7e6c2010-01-21 10:06:32 +0800541 new_buf += acpi_ex_convert_to_ascii((u64) obj_desc->
542 buffer.pointer[i],
543 base, new_buf, 1);
Len Brown4be44fc2005-08-05 00:44:28 -0400544 *new_buf++ = separator; /* each separated by a comma or space */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 }
546
Robert Moore44f6c012005-04-18 22:49:35 -0400547 /*
548 * Null terminate the string
549 * (overwrites final comma/space from above)
550 */
Bob Moore4ca846e2008-09-27 13:27:51 +0800551 if (obj_desc->buffer.length) {
552 new_buf--;
553 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 *new_buf = 0;
555 break;
556
557 default:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000558
Len Brown4be44fc2005-08-05 00:44:28 -0400559 return_ACPI_STATUS(AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 }
561
562 *result_desc = return_desc;
Len Brown4be44fc2005-08-05 00:44:28 -0400563 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564}
565
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566/*******************************************************************************
567 *
568 * FUNCTION: acpi_ex_convert_to_target_type
569 *
570 * PARAMETERS: destination_type - Current type of the destination
571 * source_desc - Source object to be converted.
572 * result_desc - Where the converted object is returned
573 * walk_state - Current method state
574 *
575 * RETURN: Status
576 *
577 * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
578 *
579 ******************************************************************************/
580
581acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400582acpi_ex_convert_to_target_type(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)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586{
Len Brown4be44fc2005-08-05 00:44:28 -0400587 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
Bob Mooreb229cf92006-04-21 17:15:00 -0400589 ACPI_FUNCTION_TRACE(ex_convert_to_target_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590
591 /* Default behavior */
592
593 *result_desc = source_desc;
594
595 /*
596 * If required by the target,
597 * perform implicit conversion on the source before we store it.
598 */
Len Brown4be44fc2005-08-05 00:44:28 -0400599 switch (GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 case ARGI_SIMPLE_TARGET:
Bob Moore7decc662018-02-15 13:17:04 -0800601 case ARGI_FIXED_TARGET:
Len Brown4be44fc2005-08-05 00:44:28 -0400602 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
604 switch (destination_type) {
605 case ACPI_TYPE_LOCAL_REGION_FIELD:
606 /*
607 * Named field can always handle conversions
608 */
609 break;
610
611 default:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000612
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 /* No conversion allowed for these types */
614
Bob Moore3371c192009-02-18 14:44:03 +0800615 if (destination_type != source_desc->common.type) {
Len Brown4be44fc2005-08-05 00:44:28 -0400616 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
617 "Explicit operator, will store (%s) over existing type (%s)\n",
618 acpi_ut_get_object_type_name
619 (source_desc),
620 acpi_ut_get_type_name
621 (destination_type)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 status = AE_TYPE;
623 }
624 }
625 break;
626
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 case ARGI_TARGETREF:
Bob Moorea5922a12015-10-19 10:24:58 +0800628 case ARGI_STORE_TARGET:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629
630 switch (destination_type) {
631 case ACPI_TYPE_INTEGER:
632 case ACPI_TYPE_BUFFER_FIELD:
633 case ACPI_TYPE_LOCAL_BANK_FIELD:
634 case ACPI_TYPE_LOCAL_INDEX_FIELD:
635 /*
Bob Moore2425a092008-09-27 10:42:02 +0800636 * These types require an Integer operand. We can convert
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 * a Buffer or a String to an Integer if necessary.
638 */
Len Brown4be44fc2005-08-05 00:44:28 -0400639 status =
640 acpi_ex_convert_to_integer(source_desc, result_desc,
Bob Moorefe97d282017-09-20 10:00:36 +0800641 ACPI_IMPLICIT_CONVERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 break;
643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 case ACPI_TYPE_STRING:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 /*
Bob Moore2425a092008-09-27 10:42:02 +0800646 * The operand must be a String. We can convert an
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647 * Integer or Buffer if necessary
648 */
Len Brown4be44fc2005-08-05 00:44:28 -0400649 status =
650 acpi_ex_convert_to_string(source_desc, result_desc,
651 ACPI_IMPLICIT_CONVERT_HEX);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 break;
653
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 case ACPI_TYPE_BUFFER:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 /*
Bob Moore2425a092008-09-27 10:42:02 +0800656 * The operand must be a Buffer. We can convert an
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 * Integer or String if necessary
658 */
Len Brown4be44fc2005-08-05 00:44:28 -0400659 status =
660 acpi_ex_convert_to_buffer(source_desc, result_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 break;
662
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663 default:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000664
Bob Mooreb8e4d892006-01-27 16:43:00 -0500665 ACPI_ERROR((AE_INFO,
Bob Mooref6a22b02010-03-05 17:56:40 +0800666 "Bad destination type during conversion: 0x%X",
Bob Mooreb8e4d892006-01-27 16:43:00 -0500667 destination_type));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 status = AE_AML_INTERNAL;
669 break;
670 }
671 break;
672
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 case ARGI_REFERENCE:
674 /*
675 * create_xxxx_field cases - we are storing the field object into the name
676 */
677 break;
678
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 default:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000680
Bob Mooreb8e4d892006-01-27 16:43:00 -0500681 ACPI_ERROR((AE_INFO,
Bob Mooref6a22b02010-03-05 17:56:40 +0800682 "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
Bob Mooreb8e4d892006-01-27 16:43:00 -0500683 GET_CURRENT_ARG_TYPE(walk_state->op_info->
684 runtime_args),
685 walk_state->opcode,
686 acpi_ut_get_type_name(destination_type)));
Bob Moore4a90c7e2006-01-13 16:22:00 -0500687 status = AE_AML_INTERNAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 }
689
690 /*
691 * Source-to-Target conversion semantics:
692 *
693 * If conversion to the target type cannot be performed, then simply
694 * overwrite the target with the new object and type.
695 */
696 if (status == AE_TYPE) {
697 status = AE_OK;
698 }
699
Len Brown4be44fc2005-08-05 00:44:28 -0400700 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701}