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