root/drivers/acpi/acpica/exoparg1.c

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

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ex_opcode_1A_0T_0R
  3. acpi_ex_opcode_1A_1T_0R
  4. acpi_ex_opcode_1A_1T_1R
  5. acpi_ex_opcode_1A_0T_1R

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: exoparg1 - AML execution - opcodes with 1 argument
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acparser.h"
  13 #include "acdispat.h"
  14 #include "acinterp.h"
  15 #include "amlcode.h"
  16 #include "acnamesp.h"
  17 
  18 #define _COMPONENT          ACPI_EXECUTER
  19 ACPI_MODULE_NAME("exoparg1")
  20 
  21 /*!
  22  * Naming convention for AML interpreter execution routines.
  23  *
  24  * The routines that begin execution of AML opcodes are named with a common
  25  * convention based upon the number of arguments, the number of target operands,
  26  * and whether or not a value is returned:
  27  *
  28  *      AcpiExOpcode_xA_yT_zR
  29  *
  30  * Where:
  31  *
  32  * xA - ARGUMENTS:    The number of arguments (input operands) that are
  33  *                    required for this opcode type (0 through 6 args).
  34  * yT - TARGETS:      The number of targets (output operands) that are required
  35  *                    for this opcode type (0, 1, or 2 targets).
  36  * zR - RETURN VALUE: Indicates whether this opcode type returns a value
  37  *                    as the function return (0 or 1).
  38  *
  39  * The AcpiExOpcode* functions are called via the Dispatcher component with
  40  * fully resolved operands.
  41 !*/
  42 /*******************************************************************************
  43  *
  44  * FUNCTION:    acpi_ex_opcode_0A_0T_1R
  45  *
  46  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
  47  *
  48  * RETURN:      Status
  49  *
  50  * DESCRIPTION: Execute operator with no operands, one return value
  51  *
  52  ******************************************************************************/
  53 acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
  54 {
  55         acpi_status status = AE_OK;
  56         union acpi_operand_object *return_desc = NULL;
  57 
  58         ACPI_FUNCTION_TRACE_STR(ex_opcode_0A_0T_1R,
  59                                 acpi_ps_get_opcode_name(walk_state->opcode));
  60 
  61         /* Examine the AML opcode */
  62 
  63         switch (walk_state->opcode) {
  64         case AML_TIMER_OP:      /*  Timer () */
  65 
  66                 /* Create a return object of type Integer */
  67 
  68                 return_desc =
  69                     acpi_ut_create_integer_object(acpi_os_get_timer());
  70                 if (!return_desc) {
  71                         status = AE_NO_MEMORY;
  72                         goto cleanup;
  73                 }
  74                 break;
  75 
  76         default:                /*  Unknown opcode  */
  77 
  78                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
  79                             walk_state->opcode));
  80                 status = AE_AML_BAD_OPCODE;
  81                 break;
  82         }
  83 
  84 cleanup:
  85 
  86         /* Delete return object on error */
  87 
  88         if ((ACPI_FAILURE(status)) || walk_state->result_obj) {
  89                 acpi_ut_remove_reference(return_desc);
  90                 walk_state->result_obj = NULL;
  91         } else {
  92                 /* Save the return value */
  93 
  94                 walk_state->result_obj = return_desc;
  95         }
  96 
  97         return_ACPI_STATUS(status);
  98 }
  99 
 100 /*******************************************************************************
 101  *
 102  * FUNCTION:    acpi_ex_opcode_1A_0T_0R
 103  *
 104  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
 105  *
 106  * RETURN:      Status
 107  *
 108  * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
 109  *              object stack
 110  *
 111  ******************************************************************************/
 112 
 113 acpi_status acpi_ex_opcode_1A_0T_0R(struct acpi_walk_state *walk_state)
 114 {
 115         union acpi_operand_object **operand = &walk_state->operands[0];
 116         acpi_status status = AE_OK;
 117 
 118         ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_0R,
 119                                 acpi_ps_get_opcode_name(walk_state->opcode));
 120 
 121         /* Examine the AML opcode */
 122 
 123         switch (walk_state->opcode) {
 124         case AML_RELEASE_OP:    /*  Release (mutex_object) */
 125 
 126                 status = acpi_ex_release_mutex(operand[0], walk_state);
 127                 break;
 128 
 129         case AML_RESET_OP:      /*  Reset (event_object) */
 130 
 131                 status = acpi_ex_system_reset_event(operand[0]);
 132                 break;
 133 
 134         case AML_SIGNAL_OP:     /*  Signal (event_object) */
 135 
 136                 status = acpi_ex_system_signal_event(operand[0]);
 137                 break;
 138 
 139         case AML_SLEEP_OP:      /*  Sleep (msec_time) */
 140 
 141                 status = acpi_ex_system_do_sleep(operand[0]->integer.value);
 142                 break;
 143 
 144         case AML_STALL_OP:      /*  Stall (usec_time) */
 145 
 146                 status =
 147                     acpi_ex_system_do_stall((u32) operand[0]->integer.value);
 148                 break;
 149 
 150         case AML_UNLOAD_OP:     /*  Unload (Handle) */
 151 
 152                 status = acpi_ex_unload_table(operand[0]);
 153                 break;
 154 
 155         default:                /*  Unknown opcode  */
 156 
 157                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
 158                             walk_state->opcode));
 159                 status = AE_AML_BAD_OPCODE;
 160                 break;
 161         }
 162 
 163         return_ACPI_STATUS(status);
 164 }
 165 
 166 /*******************************************************************************
 167  *
 168  * FUNCTION:    acpi_ex_opcode_1A_1T_0R
 169  *
 170  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
 171  *
 172  * RETURN:      Status
 173  *
 174  * DESCRIPTION: Execute opcode with one argument, one target, and no
 175  *              return value.
 176  *
 177  ******************************************************************************/
 178 
 179 acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state)
 180 {
 181         acpi_status status = AE_OK;
 182         union acpi_operand_object **operand = &walk_state->operands[0];
 183 
 184         ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_0R,
 185                                 acpi_ps_get_opcode_name(walk_state->opcode));
 186 
 187         /* Examine the AML opcode */
 188 
 189         switch (walk_state->opcode) {
 190         case AML_LOAD_OP:
 191 
 192                 status = acpi_ex_load_op(operand[0], operand[1], walk_state);
 193                 break;
 194 
 195         default:                /* Unknown opcode */
 196 
 197                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
 198                             walk_state->opcode));
 199                 status = AE_AML_BAD_OPCODE;
 200                 goto cleanup;
 201         }
 202 
 203 cleanup:
 204 
 205         return_ACPI_STATUS(status);
 206 }
 207 
 208 /*******************************************************************************
 209  *
 210  * FUNCTION:    acpi_ex_opcode_1A_1T_1R
 211  *
 212  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
 213  *
 214  * RETURN:      Status
 215  *
 216  * DESCRIPTION: Execute opcode with one argument, one target, and a
 217  *              return value.
 218  *
 219  ******************************************************************************/
 220 
 221 acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state)
 222 {
 223         acpi_status status = AE_OK;
 224         union acpi_operand_object **operand = &walk_state->operands[0];
 225         union acpi_operand_object *return_desc = NULL;
 226         union acpi_operand_object *return_desc2 = NULL;
 227         u32 temp32;
 228         u32 i;
 229         u64 power_of_ten;
 230         u64 digit;
 231 
 232         ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_1R,
 233                                 acpi_ps_get_opcode_name(walk_state->opcode));
 234 
 235         /* Examine the AML opcode */
 236 
 237         switch (walk_state->opcode) {
 238         case AML_BIT_NOT_OP:
 239         case AML_FIND_SET_LEFT_BIT_OP:
 240         case AML_FIND_SET_RIGHT_BIT_OP:
 241         case AML_FROM_BCD_OP:
 242         case AML_TO_BCD_OP:
 243         case AML_CONDITIONAL_REF_OF_OP:
 244 
 245                 /* Create a return object of type Integer for these opcodes */
 246 
 247                 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
 248                 if (!return_desc) {
 249                         status = AE_NO_MEMORY;
 250                         goto cleanup;
 251                 }
 252 
 253                 switch (walk_state->opcode) {
 254                 case AML_BIT_NOT_OP:    /* Not (Operand, Result)  */
 255 
 256                         return_desc->integer.value = ~operand[0]->integer.value;
 257                         break;
 258 
 259                 case AML_FIND_SET_LEFT_BIT_OP:  /* find_set_left_bit (Operand, Result) */
 260 
 261                         return_desc->integer.value = operand[0]->integer.value;
 262 
 263                         /*
 264                          * Acpi specification describes Integer type as a little
 265                          * endian unsigned value, so this boundary condition is valid.
 266                          */
 267                         for (temp32 = 0; return_desc->integer.value &&
 268                              temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
 269                                 return_desc->integer.value >>= 1;
 270                         }
 271 
 272                         return_desc->integer.value = temp32;
 273                         break;
 274 
 275                 case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */
 276 
 277                         return_desc->integer.value = operand[0]->integer.value;
 278 
 279                         /*
 280                          * The Acpi specification describes Integer type as a little
 281                          * endian unsigned value, so this boundary condition is valid.
 282                          */
 283                         for (temp32 = 0; return_desc->integer.value &&
 284                              temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
 285                                 return_desc->integer.value <<= 1;
 286                         }
 287 
 288                         /* Since the bit position is one-based, subtract from 33 (65) */
 289 
 290                         return_desc->integer.value =
 291                             temp32 ==
 292                             0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
 293                         break;
 294 
 295                 case AML_FROM_BCD_OP:   /* from_bcd (BCDValue, Result) */
 296                         /*
 297                          * The 64-bit ACPI integer can hold 16 4-bit BCD characters
 298                          * (if table is 32-bit, integer can hold 8 BCD characters)
 299                          * Convert each 4-bit BCD value
 300                          */
 301                         power_of_ten = 1;
 302                         return_desc->integer.value = 0;
 303                         digit = operand[0]->integer.value;
 304 
 305                         /* Convert each BCD digit (each is one nybble wide) */
 306 
 307                         for (i = 0;
 308                              (i < acpi_gbl_integer_nybble_width) && (digit > 0);
 309                              i++) {
 310 
 311                                 /* Get the least significant 4-bit BCD digit */
 312 
 313                                 temp32 = ((u32) digit) & 0xF;
 314 
 315                                 /* Check the range of the digit */
 316 
 317                                 if (temp32 > 9) {
 318                                         ACPI_ERROR((AE_INFO,
 319                                                     "BCD digit too large (not decimal): 0x%X",
 320                                                     temp32));
 321 
 322                                         status = AE_AML_NUMERIC_OVERFLOW;
 323                                         goto cleanup;
 324                                 }
 325 
 326                                 /* Sum the digit into the result with the current power of 10 */
 327 
 328                                 return_desc->integer.value +=
 329                                     (((u64) temp32) * power_of_ten);
 330 
 331                                 /* Shift to next BCD digit */
 332 
 333                                 digit >>= 4;
 334 
 335                                 /* Next power of 10 */
 336 
 337                                 power_of_ten *= 10;
 338                         }
 339                         break;
 340 
 341                 case AML_TO_BCD_OP:     /* to_bcd (Operand, Result) */
 342 
 343                         return_desc->integer.value = 0;
 344                         digit = operand[0]->integer.value;
 345 
 346                         /* Each BCD digit is one nybble wide */
 347 
 348                         for (i = 0;
 349                              (i < acpi_gbl_integer_nybble_width) && (digit > 0);
 350                              i++) {
 351                                 (void)acpi_ut_short_divide(digit, 10, &digit,
 352                                                            &temp32);
 353 
 354                                 /*
 355                                  * Insert the BCD digit that resides in the
 356                                  * remainder from above
 357                                  */
 358                                 return_desc->integer.value |=
 359                                     (((u64) temp32) << ACPI_MUL_4(i));
 360                         }
 361 
 362                         /* Overflow if there is any data left in Digit */
 363 
 364                         if (digit > 0) {
 365                                 ACPI_ERROR((AE_INFO,
 366                                             "Integer too large to convert to BCD: 0x%8.8X%8.8X",
 367                                             ACPI_FORMAT_UINT64(operand[0]->
 368                                                                integer.value)));
 369                                 status = AE_AML_NUMERIC_OVERFLOW;
 370                                 goto cleanup;
 371                         }
 372                         break;
 373 
 374                 case AML_CONDITIONAL_REF_OF_OP: /* cond_ref_of (source_object, Result) */
 375                         /*
 376                          * This op is a little strange because the internal return value is
 377                          * different than the return value stored in the result descriptor
 378                          * (There are really two return values)
 379                          */
 380                         if ((struct acpi_namespace_node *)operand[0] ==
 381                             acpi_gbl_root_node) {
 382                                 /*
 383                                  * This means that the object does not exist in the namespace,
 384                                  * return FALSE
 385                                  */
 386                                 return_desc->integer.value = 0;
 387                                 goto cleanup;
 388                         }
 389 
 390                         /* Get the object reference, store it, and remove our reference */
 391 
 392                         status = acpi_ex_get_object_reference(operand[0],
 393                                                               &return_desc2,
 394                                                               walk_state);
 395                         if (ACPI_FAILURE(status)) {
 396                                 goto cleanup;
 397                         }
 398 
 399                         status =
 400                             acpi_ex_store(return_desc2, operand[1], walk_state);
 401                         acpi_ut_remove_reference(return_desc2);
 402 
 403                         /* The object exists in the namespace, return TRUE */
 404 
 405                         return_desc->integer.value = ACPI_UINT64_MAX;
 406                         goto cleanup;
 407 
 408                 default:
 409 
 410                         /* No other opcodes get here */
 411 
 412                         break;
 413                 }
 414                 break;
 415 
 416         case AML_STORE_OP:      /* Store (Source, Target) */
 417                 /*
 418                  * A store operand is typically a number, string, buffer or lvalue
 419                  * Be careful about deleting the source object,
 420                  * since the object itself may have been stored.
 421                  */
 422                 status = acpi_ex_store(operand[0], operand[1], walk_state);
 423                 if (ACPI_FAILURE(status)) {
 424                         return_ACPI_STATUS(status);
 425                 }
 426 
 427                 /* It is possible that the Store already produced a return object */
 428 
 429                 if (!walk_state->result_obj) {
 430                         /*
 431                          * Normally, we would remove a reference on the Operand[0]
 432                          * parameter; But since it is being used as the internal return
 433                          * object (meaning we would normally increment it), the two
 434                          * cancel out, and we simply don't do anything.
 435                          */
 436                         walk_state->result_obj = operand[0];
 437                         walk_state->operands[0] = NULL; /* Prevent deletion */
 438                 }
 439                 return_ACPI_STATUS(status);
 440 
 441                 /*
 442                  * ACPI 2.0 Opcodes
 443                  */
 444         case AML_COPY_OBJECT_OP:        /* copy_object (Source, Target) */
 445 
 446                 status =
 447                     acpi_ut_copy_iobject_to_iobject(operand[0], &return_desc,
 448                                                     walk_state);
 449                 break;
 450 
 451         case AML_TO_DECIMAL_STRING_OP:  /* to_decimal_string (Data, Result) */
 452 
 453                 status =
 454                     acpi_ex_convert_to_string(operand[0], &return_desc,
 455                                               ACPI_EXPLICIT_CONVERT_DECIMAL);
 456                 if (return_desc == operand[0]) {
 457 
 458                         /* No conversion performed, add ref to handle return value */
 459 
 460                         acpi_ut_add_reference(return_desc);
 461                 }
 462                 break;
 463 
 464         case AML_TO_HEX_STRING_OP:      /* to_hex_string (Data, Result) */
 465 
 466                 status =
 467                     acpi_ex_convert_to_string(operand[0], &return_desc,
 468                                               ACPI_EXPLICIT_CONVERT_HEX);
 469                 if (return_desc == operand[0]) {
 470 
 471                         /* No conversion performed, add ref to handle return value */
 472 
 473                         acpi_ut_add_reference(return_desc);
 474                 }
 475                 break;
 476 
 477         case AML_TO_BUFFER_OP:  /* to_buffer (Data, Result) */
 478 
 479                 status = acpi_ex_convert_to_buffer(operand[0], &return_desc);
 480                 if (return_desc == operand[0]) {
 481 
 482                         /* No conversion performed, add ref to handle return value */
 483 
 484                         acpi_ut_add_reference(return_desc);
 485                 }
 486                 break;
 487 
 488         case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */
 489 
 490                 /* Perform "explicit" conversion */
 491 
 492                 status =
 493                     acpi_ex_convert_to_integer(operand[0], &return_desc, 0);
 494                 if (return_desc == operand[0]) {
 495 
 496                         /* No conversion performed, add ref to handle return value */
 497 
 498                         acpi_ut_add_reference(return_desc);
 499                 }
 500                 break;
 501 
 502         case AML_SHIFT_LEFT_BIT_OP:     /* shift_left_bit (Source, bit_num) */
 503         case AML_SHIFT_RIGHT_BIT_OP:    /* shift_right_bit (Source, bit_num) */
 504 
 505                 /* These are two obsolete opcodes */
 506 
 507                 ACPI_ERROR((AE_INFO,
 508                             "%s is obsolete and not implemented",
 509                             acpi_ps_get_opcode_name(walk_state->opcode)));
 510                 status = AE_SUPPORT;
 511                 goto cleanup;
 512 
 513         default:                /* Unknown opcode */
 514 
 515                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
 516                             walk_state->opcode));
 517                 status = AE_AML_BAD_OPCODE;
 518                 goto cleanup;
 519         }
 520 
 521         if (ACPI_SUCCESS(status)) {
 522 
 523                 /* Store the return value computed above into the target object */
 524 
 525                 status = acpi_ex_store(return_desc, operand[1], walk_state);
 526         }
 527 
 528 cleanup:
 529 
 530         /* Delete return object on error */
 531 
 532         if (ACPI_FAILURE(status)) {
 533                 acpi_ut_remove_reference(return_desc);
 534         }
 535 
 536         /* Save return object on success */
 537 
 538         else if (!walk_state->result_obj) {
 539                 walk_state->result_obj = return_desc;
 540         }
 541 
 542         return_ACPI_STATUS(status);
 543 }
 544 
 545 /*******************************************************************************
 546  *
 547  * FUNCTION:    acpi_ex_opcode_1A_0T_1R
 548  *
 549  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
 550  *
 551  * RETURN:      Status
 552  *
 553  * DESCRIPTION: Execute opcode with one argument, no target, and a return value
 554  *
 555  ******************************************************************************/
 556 
 557 acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
 558 {
 559         union acpi_operand_object **operand = &walk_state->operands[0];
 560         union acpi_operand_object *temp_desc;
 561         union acpi_operand_object *return_desc = NULL;
 562         acpi_status status = AE_OK;
 563         u32 type;
 564         u64 value;
 565 
 566         ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_1R,
 567                                 acpi_ps_get_opcode_name(walk_state->opcode));
 568 
 569         /* Examine the AML opcode */
 570 
 571         switch (walk_state->opcode) {
 572         case AML_LOGICAL_NOT_OP:        /* LNot (Operand) */
 573 
 574                 return_desc = acpi_ut_create_integer_object((u64) 0);
 575                 if (!return_desc) {
 576                         status = AE_NO_MEMORY;
 577                         goto cleanup;
 578                 }
 579 
 580                 /*
 581                  * Set result to ONES (TRUE) if Value == 0. Note:
 582                  * return_desc->Integer.Value is initially == 0 (FALSE) from above.
 583                  */
 584                 if (!operand[0]->integer.value) {
 585                         return_desc->integer.value = ACPI_UINT64_MAX;
 586                 }
 587                 break;
 588 
 589         case AML_DECREMENT_OP:  /* Decrement (Operand)  */
 590         case AML_INCREMENT_OP:  /* Increment (Operand)  */
 591                 /*
 592                  * Create a new integer. Can't just get the base integer and
 593                  * increment it because it may be an Arg or Field.
 594                  */
 595                 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
 596                 if (!return_desc) {
 597                         status = AE_NO_MEMORY;
 598                         goto cleanup;
 599                 }
 600 
 601                 /*
 602                  * Since we are expecting a Reference operand, it can be either a
 603                  * NS Node or an internal object.
 604                  */
 605                 temp_desc = operand[0];
 606                 if (ACPI_GET_DESCRIPTOR_TYPE(temp_desc) ==
 607                     ACPI_DESC_TYPE_OPERAND) {
 608 
 609                         /* Internal reference object - prevent deletion */
 610 
 611                         acpi_ut_add_reference(temp_desc);
 612                 }
 613 
 614                 /*
 615                  * Convert the Reference operand to an Integer (This removes a
 616                  * reference on the Operand[0] object)
 617                  *
 618                  * NOTE:  We use LNOT_OP here in order to force resolution of the
 619                  * reference operand to an actual integer.
 620                  */
 621                 status = acpi_ex_resolve_operands(AML_LOGICAL_NOT_OP,
 622                                                   &temp_desc, walk_state);
 623                 if (ACPI_FAILURE(status)) {
 624                         ACPI_EXCEPTION((AE_INFO, status,
 625                                         "While resolving operands for [%s]",
 626                                         acpi_ps_get_opcode_name(walk_state->
 627                                                                 opcode)));
 628 
 629                         goto cleanup;
 630                 }
 631 
 632                 /*
 633                  * temp_desc is now guaranteed to be an Integer object --
 634                  * Perform the actual increment or decrement
 635                  */
 636                 if (walk_state->opcode == AML_INCREMENT_OP) {
 637                         return_desc->integer.value =
 638                             temp_desc->integer.value + 1;
 639                 } else {
 640                         return_desc->integer.value =
 641                             temp_desc->integer.value - 1;
 642                 }
 643 
 644                 /* Finished with this Integer object */
 645 
 646                 acpi_ut_remove_reference(temp_desc);
 647 
 648                 /*
 649                  * Store the result back (indirectly) through the original
 650                  * Reference object
 651                  */
 652                 status = acpi_ex_store(return_desc, operand[0], walk_state);
 653                 break;
 654 
 655         case AML_OBJECT_TYPE_OP:        /* object_type (source_object) */
 656                 /*
 657                  * Note: The operand is not resolved at this point because we want to
 658                  * get the associated object, not its value. For example, we don't
 659                  * want to resolve a field_unit to its value, we want the actual
 660                  * field_unit object.
 661                  */
 662 
 663                 /* Get the type of the base object */
 664 
 665                 status =
 666                     acpi_ex_resolve_multiple(walk_state, operand[0], &type,
 667                                              NULL);
 668                 if (ACPI_FAILURE(status)) {
 669                         goto cleanup;
 670                 }
 671 
 672                 /* Allocate a descriptor to hold the type. */
 673 
 674                 return_desc = acpi_ut_create_integer_object((u64) type);
 675                 if (!return_desc) {
 676                         status = AE_NO_MEMORY;
 677                         goto cleanup;
 678                 }
 679                 break;
 680 
 681         case AML_SIZE_OF_OP:    /* size_of (source_object) */
 682                 /*
 683                  * Note: The operand is not resolved at this point because we want to
 684                  * get the associated object, not its value.
 685                  */
 686 
 687                 /* Get the base object */
 688 
 689                 status =
 690                     acpi_ex_resolve_multiple(walk_state, operand[0], &type,
 691                                              &temp_desc);
 692                 if (ACPI_FAILURE(status)) {
 693                         goto cleanup;
 694                 }
 695 
 696                 /*
 697                  * The type of the base object must be integer, buffer, string, or
 698                  * package. All others are not supported.
 699                  *
 700                  * NOTE: Integer is not specifically supported by the ACPI spec,
 701                  * but is supported implicitly via implicit operand conversion.
 702                  * rather than bother with conversion, we just use the byte width
 703                  * global (4 or 8 bytes).
 704                  */
 705                 switch (type) {
 706                 case ACPI_TYPE_INTEGER:
 707 
 708                         value = acpi_gbl_integer_byte_width;
 709                         break;
 710 
 711                 case ACPI_TYPE_STRING:
 712 
 713                         value = temp_desc->string.length;
 714                         break;
 715 
 716                 case ACPI_TYPE_BUFFER:
 717 
 718                         /* Buffer arguments may not be evaluated at this point */
 719 
 720                         status = acpi_ds_get_buffer_arguments(temp_desc);
 721                         value = temp_desc->buffer.length;
 722                         break;
 723 
 724                 case ACPI_TYPE_PACKAGE:
 725 
 726                         /* Package arguments may not be evaluated at this point */
 727 
 728                         status = acpi_ds_get_package_arguments(temp_desc);
 729                         value = temp_desc->package.count;
 730                         break;
 731 
 732                 default:
 733 
 734                         ACPI_ERROR((AE_INFO,
 735                                     "Operand must be Buffer/Integer/String/Package"
 736                                     " - found type %s",
 737                                     acpi_ut_get_type_name(type)));
 738 
 739                         status = AE_AML_OPERAND_TYPE;
 740                         goto cleanup;
 741                 }
 742 
 743                 if (ACPI_FAILURE(status)) {
 744                         goto cleanup;
 745                 }
 746 
 747                 /*
 748                  * Now that we have the size of the object, create a result
 749                  * object to hold the value
 750                  */
 751                 return_desc = acpi_ut_create_integer_object(value);
 752                 if (!return_desc) {
 753                         status = AE_NO_MEMORY;
 754                         goto cleanup;
 755                 }
 756                 break;
 757 
 758         case AML_REF_OF_OP:     /* ref_of (source_object) */
 759 
 760                 status =
 761                     acpi_ex_get_object_reference(operand[0], &return_desc,
 762                                                  walk_state);
 763                 if (ACPI_FAILURE(status)) {
 764                         goto cleanup;
 765                 }
 766                 break;
 767 
 768         case AML_DEREF_OF_OP:   /* deref_of (obj_reference | String) */
 769 
 770                 /* Check for a method local or argument, or standalone String */
 771 
 772                 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) ==
 773                     ACPI_DESC_TYPE_NAMED) {
 774                         temp_desc =
 775                             acpi_ns_get_attached_object((struct
 776                                                          acpi_namespace_node *)
 777                                                         operand[0]);
 778                         if (temp_desc
 779                             && ((temp_desc->common.type == ACPI_TYPE_STRING)
 780                                 || (temp_desc->common.type ==
 781                                     ACPI_TYPE_LOCAL_REFERENCE))) {
 782                                 operand[0] = temp_desc;
 783                                 acpi_ut_add_reference(temp_desc);
 784                         } else {
 785                                 status = AE_AML_OPERAND_TYPE;
 786                                 goto cleanup;
 787                         }
 788                 } else {
 789                         switch ((operand[0])->common.type) {
 790                         case ACPI_TYPE_LOCAL_REFERENCE:
 791                                 /*
 792                                  * This is a deref_of (local_x | arg_x)
 793                                  *
 794                                  * Must resolve/dereference the local/arg reference first
 795                                  */
 796                                 switch (operand[0]->reference.class) {
 797                                 case ACPI_REFCLASS_LOCAL:
 798                                 case ACPI_REFCLASS_ARG:
 799 
 800                                         /* Set Operand[0] to the value of the local/arg */
 801 
 802                                         status =
 803                                             acpi_ds_method_data_get_value
 804                                             (operand[0]->reference.class,
 805                                              operand[0]->reference.value,
 806                                              walk_state, &temp_desc);
 807                                         if (ACPI_FAILURE(status)) {
 808                                                 goto cleanup;
 809                                         }
 810 
 811                                         /*
 812                                          * Delete our reference to the input object and
 813                                          * point to the object just retrieved
 814                                          */
 815                                         acpi_ut_remove_reference(operand[0]);
 816                                         operand[0] = temp_desc;
 817                                         break;
 818 
 819                                 case ACPI_REFCLASS_REFOF:
 820 
 821                                         /* Get the object to which the reference refers */
 822 
 823                                         temp_desc =
 824                                             operand[0]->reference.object;
 825                                         acpi_ut_remove_reference(operand[0]);
 826                                         operand[0] = temp_desc;
 827                                         break;
 828 
 829                                 default:
 830 
 831                                         /* Must be an Index op - handled below */
 832                                         break;
 833                                 }
 834                                 break;
 835 
 836                         case ACPI_TYPE_STRING:
 837 
 838                                 break;
 839 
 840                         default:
 841 
 842                                 status = AE_AML_OPERAND_TYPE;
 843                                 goto cleanup;
 844                         }
 845                 }
 846 
 847                 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
 848                     ACPI_DESC_TYPE_NAMED) {
 849                         if ((operand[0])->common.type == ACPI_TYPE_STRING) {
 850                                 /*
 851                                  * This is a deref_of (String). The string is a reference
 852                                  * to a named ACPI object.
 853                                  *
 854                                  * 1) Find the owning Node
 855                                  * 2) Dereference the node to an actual object. Could be a
 856                                  *    Field, so we need to resolve the node to a value.
 857                                  */
 858                                 status =
 859                                     acpi_ns_get_node_unlocked(walk_state->
 860                                                               scope_info->scope.
 861                                                               node,
 862                                                               operand[0]->
 863                                                               string.pointer,
 864                                                               ACPI_NS_SEARCH_PARENT,
 865                                                               ACPI_CAST_INDIRECT_PTR
 866                                                               (struct
 867                                                                acpi_namespace_node,
 868                                                                &return_desc));
 869                                 if (ACPI_FAILURE(status)) {
 870                                         goto cleanup;
 871                                 }
 872 
 873                                 status =
 874                                     acpi_ex_resolve_node_to_value
 875                                     (ACPI_CAST_INDIRECT_PTR
 876                                      (struct acpi_namespace_node, &return_desc),
 877                                      walk_state);
 878                                 goto cleanup;
 879                         }
 880                 }
 881 
 882                 /* Operand[0] may have changed from the code above */
 883 
 884                 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) ==
 885                     ACPI_DESC_TYPE_NAMED) {
 886                         /*
 887                          * This is a deref_of (object_reference)
 888                          * Get the actual object from the Node (This is the dereference).
 889                          * This case may only happen when a local_x or arg_x is
 890                          * dereferenced above, or for references to device and
 891                          * thermal objects.
 892                          */
 893                         switch (((struct acpi_namespace_node *)operand[0])->
 894                                 type) {
 895                         case ACPI_TYPE_DEVICE:
 896                         case ACPI_TYPE_THERMAL:
 897 
 898                                 /* These types have no node subobject, return the NS node */
 899 
 900                                 return_desc = operand[0];
 901                                 break;
 902 
 903                         default:
 904                                 /* For most types, get the object attached to the node */
 905 
 906                                 return_desc = acpi_ns_get_attached_object((struct acpi_namespace_node *)operand[0]);
 907                                 acpi_ut_add_reference(return_desc);
 908                                 break;
 909                         }
 910                 } else {
 911                         /*
 912                          * This must be a reference object produced by either the
 913                          * Index() or ref_of() operator
 914                          */
 915                         switch (operand[0]->reference.class) {
 916                         case ACPI_REFCLASS_INDEX:
 917                                 /*
 918                                  * The target type for the Index operator must be
 919                                  * either a Buffer or a Package
 920                                  */
 921                                 switch (operand[0]->reference.target_type) {
 922                                 case ACPI_TYPE_BUFFER_FIELD:
 923 
 924                                         temp_desc =
 925                                             operand[0]->reference.object;
 926 
 927                                         /*
 928                                          * Create a new object that contains one element of the
 929                                          * buffer -- the element pointed to by the index.
 930                                          *
 931                                          * NOTE: index into a buffer is NOT a pointer to a
 932                                          * sub-buffer of the main buffer, it is only a pointer to a
 933                                          * single element (byte) of the buffer!
 934                                          *
 935                                          * Since we are returning the value of the buffer at the
 936                                          * indexed location, we don't need to add an additional
 937                                          * reference to the buffer itself.
 938                                          */
 939                                         return_desc =
 940                                             acpi_ut_create_integer_object((u64)
 941                                                                           temp_desc->buffer.pointer[operand[0]->reference.value]);
 942                                         if (!return_desc) {
 943                                                 status = AE_NO_MEMORY;
 944                                                 goto cleanup;
 945                                         }
 946                                         break;
 947 
 948                                 case ACPI_TYPE_PACKAGE:
 949                                         /*
 950                                          * Return the referenced element of the package. We must
 951                                          * add another reference to the referenced object, however.
 952                                          */
 953                                         return_desc =
 954                                             *(operand[0]->reference.where);
 955                                         if (!return_desc) {
 956                                                 /*
 957                                                  * Element is NULL, do not allow the dereference.
 958                                                  * This provides compatibility with other ACPI
 959                                                  * implementations.
 960                                                  */
 961                                                 return_ACPI_STATUS
 962                                                     (AE_AML_UNINITIALIZED_ELEMENT);
 963                                         }
 964 
 965                                         acpi_ut_add_reference(return_desc);
 966                                         break;
 967 
 968                                 default:
 969 
 970                                         ACPI_ERROR((AE_INFO,
 971                                                     "Unknown Index TargetType 0x%X in reference object %p",
 972                                                     operand[0]->reference.
 973                                                     target_type, operand[0]));
 974 
 975                                         status = AE_AML_OPERAND_TYPE;
 976                                         goto cleanup;
 977                                 }
 978                                 break;
 979 
 980                         case ACPI_REFCLASS_REFOF:
 981 
 982                                 return_desc = operand[0]->reference.object;
 983 
 984                                 if (ACPI_GET_DESCRIPTOR_TYPE(return_desc) ==
 985                                     ACPI_DESC_TYPE_NAMED) {
 986                                         return_desc =
 987                                             acpi_ns_get_attached_object((struct
 988                                                                          acpi_namespace_node
 989                                                                          *)
 990                                                                         return_desc);
 991                                         if (!return_desc) {
 992                                                 break;
 993                                         }
 994 
 995                                         /*
 996                                          * June 2013:
 997                                          * buffer_fields/field_units require additional resolution
 998                                          */
 999                                         switch (return_desc->common.type) {
1000                                         case ACPI_TYPE_BUFFER_FIELD:
1001                                         case ACPI_TYPE_LOCAL_REGION_FIELD:
1002                                         case ACPI_TYPE_LOCAL_BANK_FIELD:
1003                                         case ACPI_TYPE_LOCAL_INDEX_FIELD:
1004 
1005                                                 status =
1006                                                     acpi_ex_read_data_from_field
1007                                                     (walk_state, return_desc,
1008                                                      &temp_desc);
1009                                                 if (ACPI_FAILURE(status)) {
1010                                                         goto cleanup;
1011                                                 }
1012 
1013                                                 return_desc = temp_desc;
1014                                                 break;
1015 
1016                                         default:
1017 
1018                                                 /* Add another reference to the object */
1019 
1020                                                 acpi_ut_add_reference
1021                                                     (return_desc);
1022                                                 break;
1023                                         }
1024                                 }
1025                                 break;
1026 
1027                         default:
1028 
1029                                 ACPI_ERROR((AE_INFO,
1030                                             "Unknown class in reference(%p) - 0x%2.2X",
1031                                             operand[0],
1032                                             operand[0]->reference.class));
1033 
1034                                 status = AE_TYPE;
1035                                 goto cleanup;
1036                         }
1037                 }
1038                 break;
1039 
1040         default:
1041 
1042                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
1043                             walk_state->opcode));
1044 
1045                 status = AE_AML_BAD_OPCODE;
1046                 goto cleanup;
1047         }
1048 
1049 cleanup:
1050 
1051         /* Delete return object on error */
1052 
1053         if (ACPI_FAILURE(status)) {
1054                 acpi_ut_remove_reference(return_desc);
1055         }
1056 
1057         /* Save return object on success */
1058 
1059         else {
1060                 walk_state->result_obj = return_desc;
1061         }
1062 
1063         return_ACPI_STATUS(status);
1064 }

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