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 - 2021, 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 return_ACPI_STATUS 1011 (status); 1012 } 1013 1014 return_desc = temp_desc; 1015 break; 1016 1017 default: 1018 1019 /* Add another reference to the object */ 1020 1021 acpi_ut_add_reference 1022 (return_desc); 1023 break; 1024 } 1025 } 1026 break; 1027 1028 default: 1029 1030 ACPI_ERROR((AE_INFO, 1031 "Unknown class in reference(%p) - 0x%2.2X", 1032 operand[0], 1033 operand[0]->reference.class)); 1034 1035 status = AE_TYPE; 1036 goto cleanup; 1037 } 1038 } 1039 break; 1040 1041 default: 1042 1043 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X", 1044 walk_state->opcode)); 1045 1046 status = AE_AML_BAD_OPCODE; 1047 goto cleanup; 1048 } 1049 1050 cleanup: 1051 1052 /* Delete return object on error */ 1053 1054 if (ACPI_FAILURE(status)) { 1055 acpi_ut_remove_reference(return_desc); 1056 } 1057 1058 /* Save return object on success */ 1059 1060 else { 1061 walk_state->result_obj = return_desc; 1062 } 1063 1064 return_ACPI_STATUS(status); 1065 } 1066