root/drivers/acpi/acpica/exconvrt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ex_convert_to_buffer
  3. acpi_ex_convert_to_ascii
  4. acpi_ex_convert_to_string
  5. acpi_ex_convert_to_target_type

   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 - 2019, 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, 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 
  37 acpi_status
  38 acpi_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 
 173 acpi_status
 174 acpi_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 
 259 static u32
 260 acpi_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 
 372 acpi_status
 373 acpi_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 
 572 acpi_status
 573 acpi_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 }

/* [<][>][^][v][top][bottom][index][help] */