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