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