linux/drivers/acpi/acpica/exconvrt.c
<<
>>
Prefs
   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 - 2021, 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