1 2/****************************************************************************** 3 * 4 * Module Name: exoparg1 - AML execution - opcodes with 1 argument 5 * $Revision: 1.1.1.1 $ 6 * 7 *****************************************************************************/ 8 9/* 10 * Copyright (C) 2000, 2001 R. Byron Moore 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 */ 26 27 28#include "acpi.h" 29#include "acparser.h" 30#include "acdispat.h" 31#include "acinterp.h" 32#include "amlcode.h" 33#include "acnamesp.h" 34 35 36#define _COMPONENT ACPI_EXECUTER 37 MODULE_NAME ("exoparg1") 38 39 40/*! 41 * Naming convention for AML interpreter execution routines. 42 * 43 * The routines that begin execution of AML opcodes are named with a common 44 * convention based upon the number of arguments, the number of target operands, 45 * and whether or not a value is returned: 46 * 47 * AcpiExOpcode_xA_yT_zR 48 * 49 * Where: 50 * 51 * xA - ARGUMENTS: The number of arguments (input operands) that are 52 * required for this opcode type (1 through 6 args). 53 * yT - TARGETS: The number of targets (output operands) that are required 54 * for this opcode type (0, 1, or 2 targets). 55 * zR - RETURN VALUE: Indicates whether this opcode type returns a value 56 * as the function return (0 or 1). 57 * 58 * The AcpiExOpcode* functions are called via the Dispatcher component with 59 * fully resolved operands. 60!*/ 61 62 63/******************************************************************************* 64 * 65 * FUNCTION: Acpi_ex_opcode_1A_0T_0R 66 * 67 * PARAMETERS: Walk_state - Current state (contains AML opcode) 68 * 69 * RETURN: Status 70 * 71 * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on 72 * object stack 73 * 74 ******************************************************************************/ 75 76acpi_status 77acpi_ex_opcode_1A_0T_0R ( 78 acpi_walk_state *walk_state) 79{ 80 acpi_operand_object **operand = &walk_state->operands[0]; 81 acpi_status status = AE_OK; 82 83 84 FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); 85 86 87 /* Examine the opcode */ 88 89 switch (walk_state->opcode) { 90 case AML_RELEASE_OP: /* Release (Mutex_object) */ 91 92 status = acpi_ex_release_mutex (operand[0], walk_state); 93 break; 94 95 96 case AML_RESET_OP: /* Reset (Event_object) */ 97 98 status = acpi_ex_system_reset_event (operand[0]); 99 break; 100 101 102 case AML_SIGNAL_OP: /* Signal (Event_object) */ 103 104 status = acpi_ex_system_signal_event (operand[0]); 105 break; 106 107 108 case AML_SLEEP_OP: /* Sleep (Msec_time) */ 109 110 acpi_ex_system_do_suspend ((u32) operand[0]->integer.value); 111 break; 112 113 114 case AML_STALL_OP: /* Stall (Usec_time) */ 115 116 acpi_ex_system_do_stall ((u32) operand[0]->integer.value); 117 break; 118 119 120 case AML_UNLOAD_OP: /* Unload (Handle) */ 121 122 status = acpi_ex_unload_table (operand[0]); 123 break; 124 125 126 default: /* Unknown opcode */ 127 128 REPORT_ERROR (("Acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n", 129 walk_state->opcode)); 130 status = AE_AML_BAD_OPCODE; 131 break; 132 } 133 134 return_ACPI_STATUS (status); 135} 136 137 138/******************************************************************************* 139 * 140 * FUNCTION: Acpi_ex_opcode_1A_1T_0R 141 * 142 * PARAMETERS: Walk_state - Current state (contains AML opcode) 143 * 144 * RETURN: Status 145 * 146 * DESCRIPTION: Execute opcode with one argument, one target, and no 147 * return value. 148 * 149 ******************************************************************************/ 150 151acpi_status 152acpi_ex_opcode_1A_1T_0R ( 153 acpi_walk_state *walk_state) 154{ 155 acpi_status status = AE_OK; 156 acpi_operand_object **operand = &walk_state->operands[0]; 157 158 159 FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); 160 161 162 switch (walk_state->opcode) { 163 164 case AML_LOAD_OP: 165 166 status = acpi_ex_load_op (operand[0], operand[1]); 167 break; 168 169 default: /* Unknown opcode */ 170 171 REPORT_ERROR (("Acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n", 172 walk_state->opcode)); 173 status = AE_AML_BAD_OPCODE; 174 goto cleanup; 175 } 176 177 178cleanup: 179 180 return_ACPI_STATUS (status); 181} 182 183 184/******************************************************************************* 185 * 186 * FUNCTION: Acpi_ex_opcode_1A_1T_1R 187 * 188 * PARAMETERS: Walk_state - Current state (contains AML opcode) 189 * 190 * RETURN: Status 191 * 192 * DESCRIPTION: Execute opcode with one argument, one target, and a 193 * return value. 194 * 195 ******************************************************************************/ 196 197acpi_status 198acpi_ex_opcode_1A_1T_1R ( 199 acpi_walk_state *walk_state) 200{ 201 acpi_status status = AE_OK; 202 acpi_operand_object **operand = &walk_state->operands[0]; 203 acpi_operand_object *return_desc = NULL; 204 acpi_operand_object *return_desc2 = NULL; 205 u32 temp32; 206 u32 i; 207 u32 j; 208 acpi_integer digit; 209 210 211 FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); 212 213 214 /* Create a return object of type Integer for most opcodes */ 215 216 switch (walk_state->opcode) { 217 case AML_BIT_NOT_OP: 218 case AML_FIND_SET_LEFT_BIT_OP: 219 case AML_FIND_SET_RIGHT_BIT_OP: 220 case AML_FROM_BCD_OP: 221 case AML_TO_BCD_OP: 222 case AML_COND_REF_OF_OP: 223 224 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); 225 if (!return_desc) { 226 status = AE_NO_MEMORY; 227 goto cleanup; 228 } 229 230 break; 231 } 232 233 234 switch (walk_state->opcode) { 235 236 case AML_BIT_NOT_OP: /* Not (Operand, Result) */ 237 238 return_desc->integer.value = ~operand[0]->integer.value; 239 break; 240 241 242 case AML_FIND_SET_LEFT_BIT_OP: /* Find_set_left_bit (Operand, Result) */ 243 244 245 return_desc->integer.value = operand[0]->integer.value; 246 247 /* 248 * Acpi specification describes Integer type as a little 249 * endian unsigned value, so this boundary condition is valid. 250 */ 251 for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { 252 return_desc->integer.value >>= 1; 253 } 254 255 return_desc->integer.value = temp32; 256 break; 257 258 259 case AML_FIND_SET_RIGHT_BIT_OP: /* Find_set_right_bit (Operand, Result) */ 260 261 262 return_desc->integer.value = operand[0]->integer.value; 263 264 /* 265 * The Acpi specification describes Integer type as a little 266 * endian unsigned value, so this boundary condition is valid. 267 */ 268 for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { 269 return_desc->integer.value <<= 1; 270 } 271 272 /* Since the bit position is one-based, subtract from 33 (65) */ 273 274 return_desc->integer.value = temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32; 275 break; 276 277 278 case AML_FROM_BCD_OP: /* From_bcd (BCDValue, Result) */ 279 280 /* 281 * The 64-bit ACPI integer can hold 16 4-bit BCD integers 282 */ 283 return_desc->integer.value = 0; 284 for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { 285 /* Get one BCD digit */ 286 287 digit = (acpi_integer) ((operand[0]->integer.value >> (i * 4)) & 0xF); 288 289 /* Check the range of the digit */ 290 291 if (digit > 9) { 292 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD digit too large: %d\n", 293 (u32) digit)); 294 status = AE_AML_NUMERIC_OVERFLOW; 295 goto cleanup; 296 } 297 298 if (digit > 0) { 299 /* Sum into the result with the appropriate power of 10 */ 300 301 for (j = 0; j < i; j++) { 302 digit *= 10; 303 } 304 305 return_desc->integer.value += digit; 306 } 307 } 308 break; 309 310 311 case AML_TO_BCD_OP: /* To_bcd (Operand, Result) */ 312 313 if (operand[0]->integer.value > ACPI_MAX_BCD_VALUE) { 314 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD overflow: %8.8X%8.8X\n", 315 HIDWORD(operand[0]->integer.value), LODWORD(operand[0]->integer.value))); 316 status = AE_AML_NUMERIC_OVERFLOW; 317 goto cleanup; 318 } 319 320 return_desc->integer.value = 0; 321 for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { 322 /* Divide by nth factor of 10 */ 323 324 temp32 = 0; 325 digit = operand[0]->integer.value; 326 for (j = 0; j < i; j++) { 327 acpi_ut_short_divide (&digit, 10, &digit, &temp32); 328 } 329 330 /* Create the BCD digit from the remainder above */ 331 332 if (digit > 0) { 333 return_desc->integer.value += (temp32 << (i * 4)); 334 } 335 } 336 break; 337 338 339 case AML_COND_REF_OF_OP: /* Cond_ref_of (Source_object, Result) */ 340 341 /* 342 * This op is a little strange because the internal return value is 343 * different than the return value stored in the result descriptor 344 * (There are really two return values) 345 */ 346 if ((acpi_namespace_node *) operand[0] == acpi_gbl_root_node) { 347 /* 348 * This means that the object does not exist in the namespace, 349 * return FALSE 350 */ 351 return_desc->integer.value = 0; 352 353 /* 354 * Must delete the result descriptor since there is no reference 355 * being returned 356 */ 357 acpi_ut_remove_reference (operand[1]); 358 goto cleanup; 359 } 360 361 /* Get the object reference and store it */ 362 363 status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state); 364 if (ACPI_FAILURE (status)) { 365 goto cleanup; 366 } 367 368 status = acpi_ex_store (return_desc2, operand[1], walk_state); 369 370 /* The object exists in the namespace, return TRUE */ 371 372 return_desc->integer.value = ACPI_INTEGER_MAX; 373 goto cleanup; 374 break; 375 376 377 case AML_STORE_OP: /* Store (Source, Target) */ 378 379 /* 380 * A store operand is typically a number, string, buffer or lvalue 381 * Be careful about deleting the source object, 382 * since the object itself may have been stored. 383 */ 384 status = acpi_ex_store (operand[0], operand[1], walk_state); 385 if (ACPI_FAILURE (status)) { 386 return_ACPI_STATUS (status); 387 } 388 389 /* 390 * Normally, we would remove a reference on the Operand[0] parameter; 391 * But since it is being used as the internal return object 392 * (meaning we would normally increment it), the two cancel out, 393 * and we simply don't do anything. 394 */ 395 walk_state->result_obj = operand[0]; 396 walk_state->operands[0] = NULL; /* Prevent deletion */ 397 return_ACPI_STATUS (status); 398 break; 399 400 401 /* 402 * ACPI 2.0 Opcodes 403 */ 404 case AML_COPY_OP: /* Copy (Source, Target) */ 405 406 status = AE_NOT_IMPLEMENTED; 407 goto cleanup; 408 break; 409 410 411 case AML_TO_DECSTRING_OP: /* To_decimal_string (Data, Result) */ 412 413 status = acpi_ex_convert_to_string (operand[0], &return_desc, 10, ACPI_UINT32_MAX, walk_state); 414 break; 415 416 417 case AML_TO_HEXSTRING_OP: /* To_hex_string (Data, Result) */ 418 419 status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, ACPI_UINT32_MAX, walk_state); 420 break; 421 422 423 case AML_TO_BUFFER_OP: /* To_buffer (Data, Result) */ 424 425 status = acpi_ex_convert_to_buffer (operand[0], &return_desc, walk_state); 426 break; 427 428 429 case AML_TO_INTEGER_OP: /* To_integer (Data, Result) */ 430 431 status = acpi_ex_convert_to_integer (operand[0], &return_desc, walk_state); 432 break; 433 434 435 /* 436 * These are two obsolete opcodes 437 */ 438 case AML_SHIFT_LEFT_BIT_OP: /* Shift_left_bit (Source, Bit_num) */ 439 case AML_SHIFT_RIGHT_BIT_OP: /* Shift_right_bit (Source, Bit_num) */ 440 441 442 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n", 443 acpi_ps_get_opcode_name (walk_state->opcode))); 444 status = AE_SUPPORT; 445 goto cleanup; 446 break; 447 448 449 default: /* Unknown opcode */ 450 451 REPORT_ERROR (("Acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n", 452 walk_state->opcode)); 453 status = AE_AML_BAD_OPCODE; 454 goto cleanup; 455 } 456 457 458 /* 459 * Store the return value computed above into the target object 460 */ 461 status = acpi_ex_store (return_desc, operand[1], walk_state); 462 463 464cleanup: 465 466 walk_state->result_obj = return_desc; 467 468 /* Delete return object on error */ 469 470 if (ACPI_FAILURE (status)) { 471 acpi_ut_remove_reference (return_desc); 472 } 473 474 return_ACPI_STATUS (status); 475} 476 477 478/******************************************************************************* 479 * 480 * FUNCTION: Acpi_ex_opcode_1A_0T_1R 481 * 482 * PARAMETERS: Walk_state - Current state (contains AML opcode) 483 * 484 * RETURN: Status 485 * 486 * DESCRIPTION: Execute opcode with one argument, no target, and a return value 487 * 488 ******************************************************************************/ 489 490acpi_status 491acpi_ex_opcode_1A_0T_1R ( 492 acpi_walk_state *walk_state) 493{ 494 acpi_operand_object **operand = &walk_state->operands[0]; 495 acpi_operand_object *temp_desc; 496 acpi_operand_object *return_desc = NULL; 497 acpi_status status = AE_OK; 498 u32 type; 499 acpi_integer value; 500 501 502 FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); 503 504 505 /* Get the operand and decode the opcode */ 506 507 switch (walk_state->opcode) { 508 509 case AML_LNOT_OP: /* LNot (Operand) */ 510 511 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); 512 if (!return_desc) { 513 status = AE_NO_MEMORY; 514 goto cleanup; 515 } 516 517 return_desc->integer.value = !operand[0]->integer.value; 518 break; 519 520 521 case AML_DECREMENT_OP: /* Decrement (Operand) */ 522 case AML_INCREMENT_OP: /* Increment (Operand) */ 523 524 /* 525 * Since we are expecting a Reference operand, it 526 * can be either a Node or an internal object. 527 */ 528 return_desc = operand[0]; 529 if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_INTERNAL)) { 530 /* Internal reference object - prevent deletion */ 531 532 acpi_ut_add_reference (return_desc); 533 } 534 535 /* 536 * Convert the Return_desc Reference to a Number 537 * (This removes a reference on the Return_desc object) 538 */ 539 status = acpi_ex_resolve_operands (AML_LNOT_OP, &return_desc, walk_state); 540 if (ACPI_FAILURE (status)) { 541 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n", 542 acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception(status))); 543 544 goto cleanup; 545 } 546 547 /* 548 * Return_desc is now guaranteed to be an Integer object 549 * Do the actual increment or decrement 550 */ 551 if (AML_INCREMENT_OP == walk_state->opcode) { 552 return_desc->integer.value++; 553 } 554 else { 555 return_desc->integer.value--; 556 } 557 558 /* Store the result back in the original descriptor */ 559 560 status = acpi_ex_store (return_desc, operand[0], walk_state); 561 break; 562 563 564 case AML_TYPE_OP: /* Object_type (Source_object) */ 565 566 if (INTERNAL_TYPE_REFERENCE == operand[0]->common.type) { 567 /* 568 * Not a Name -- an indirect name pointer would have 569 * been converted to a direct name pointer in Resolve_operands 570 */ 571 switch (operand[0]->reference.opcode) { 572 case AML_ZERO_OP: 573 case AML_ONE_OP: 574 case AML_ONES_OP: 575 case AML_REVISION_OP: 576 577 /* Constants are of type Integer */ 578 579 type = ACPI_TYPE_INTEGER; 580 break; 581 582 583 case AML_DEBUG_OP: 584 585 /* Per 1.0b spec, Debug object is of type "Debug_object" */ 586 587 type = ACPI_TYPE_DEBUG_OBJECT; 588 break; 589 590 591 case AML_INDEX_OP: 592 593 /* Get the type of this reference (index into another object) */ 594 595 type = operand[0]->reference.target_type; 596 if (type == ACPI_TYPE_PACKAGE) { 597 /* 598 * The main object is a package, we want to get the type 599 * of the individual package element that is referenced by 600 * the index. 601 */ 602 type = (*(operand[0]->reference.where))->common.type; 603 } 604 605 break; 606 607 608 case AML_LOCAL_OP: 609 case AML_ARG_OP: 610 611 type = acpi_ds_method_data_get_type (operand[0]->reference.opcode, 612 operand[0]->reference.offset, walk_state); 613 break; 614 615 616 default: 617 618 REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R/Type_op: Internal error - Unknown Reference subtype %X\n", 619 operand[0]->reference.opcode)); 620 status = AE_AML_INTERNAL; 621 goto cleanup; 622 } 623 } 624 625 else { 626 /* 627 * It's not a Reference, so it must be a direct name pointer. 628 */ 629 type = acpi_ns_get_type ((acpi_namespace_node *) operand[0]); 630 631 /* Convert internal types to external types */ 632 633 switch (type) { 634 case INTERNAL_TYPE_REGION_FIELD: 635 case INTERNAL_TYPE_BANK_FIELD: 636 case INTERNAL_TYPE_INDEX_FIELD: 637 638 type = ACPI_TYPE_FIELD_UNIT; 639 } 640 641 } 642 643 /* Allocate a descriptor to hold the type. */ 644 645 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); 646 if (!return_desc) { 647 status = AE_NO_MEMORY; 648 goto cleanup; 649 } 650 651 return_desc->integer.value = type; 652 break; 653 654 655 case AML_SIZE_OF_OP: /* Size_of (Source_object) */ 656 657 temp_desc = operand[0]; 658 if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) { 659 temp_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) operand[0]); 660 } 661 662 if (!temp_desc) { 663 value = 0; 664 } 665 666 else { 667 switch (temp_desc->common.type) { 668 case ACPI_TYPE_BUFFER: 669 value = temp_desc->buffer.length; 670 break; 671 672 case ACPI_TYPE_STRING: 673 value = temp_desc->string.length; 674 break; 675 676 case ACPI_TYPE_PACKAGE: 677 value = temp_desc->package.count; 678 break; 679 680 case INTERNAL_TYPE_REFERENCE: 681 682 /* TBD: this must be a reference to a buf/str/pkg?? */ 683 684 value = 4; 685 break; 686 687 default: 688 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Not Buf/Str/Pkg - found type %X\n", 689 temp_desc->common.type)); 690 status = AE_AML_OPERAND_TYPE; 691 goto cleanup; 692 } 693 } 694 695 /* 696 * Now that we have the size of the object, create a result 697 * object to hold the value 698 */ 699 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); 700 if (!return_desc) { 701 status = AE_NO_MEMORY; 702 goto cleanup; 703 } 704 705 return_desc->integer.value = value; 706 break; 707 708 709 case AML_REF_OF_OP: /* Ref_of (Source_object) */ 710 711 status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state); 712 if (ACPI_FAILURE (status)) { 713 goto cleanup; 714 } 715 break; 716 717 718 case AML_DEREF_OF_OP: /* Deref_of (Obj_reference) */ 719 720 /* Check for a method local or argument */ 721 722 if (!VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) { 723 /* 724 * Must resolve/dereference the local/arg reference first 725 */ 726 switch (operand[0]->reference.opcode) { 727 /* Set Operand[0] to the value of the local/arg */ 728 729 case AML_LOCAL_OP: 730 case AML_ARG_OP: 731 732 acpi_ds_method_data_get_value (operand[0]->reference.opcode, 733 operand[0]->reference.offset, walk_state, &temp_desc); 734 735 /* 736 * Delete our reference to the input object and 737 * point to the object just retrieved 738 */ 739 acpi_ut_remove_reference (operand[0]); 740 operand[0] = temp_desc; 741 break; 742 743 default: 744 745 /* Index op - handled below */ 746 break; 747 } 748 } 749 750 751 /* Operand[0] may have changed from the code above */ 752 753 if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) { 754 /* Get the actual object from the Node (This is the dereference) */ 755 756 return_desc = ((acpi_namespace_node *) operand[0])->object; 757 758 /* Returning a pointer to the object, add another reference! */ 759 760 acpi_ut_add_reference (return_desc); 761 } 762 763 else { 764 /* 765 * This must be a reference object produced by the Index 766 * ASL operation -- check internal opcode 767 */ 768 if ((operand[0]->reference.opcode != AML_INDEX_OP) && 769 (operand[0]->reference.opcode != AML_REF_OF_OP)) { 770 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n", 771 operand[0], operand[0]->reference.opcode)); 772 773 status = AE_TYPE; 774 goto cleanup; 775 } 776 777 778 switch (operand[0]->reference.opcode) { 779 case AML_INDEX_OP: 780 781 /* 782 * Supported target types for the Index operator are 783 * 1) A Buffer 784 * 2) A Package 785 */ 786 if (operand[0]->reference.target_type == ACPI_TYPE_BUFFER_FIELD) { 787 /* 788 * The target is a buffer, we must create a new object that 789 * contains one element of the buffer, the element pointed 790 * to by the index. 791 * 792 * NOTE: index into a buffer is NOT a pointer to a 793 * sub-buffer of the main buffer, it is only a pointer to a 794 * single element (byte) of the buffer! 795 */ 796 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); 797 if (!return_desc) { 798 status = AE_NO_MEMORY; 799 goto cleanup; 800 } 801 802 temp_desc = operand[0]->reference.object; 803 return_desc->integer.value = 804 temp_desc->buffer.pointer[operand[0]->reference.offset]; 805 806 /* TBD: [Investigate] (see below) Don't add an additional 807 * ref! 808 */ 809 } 810 811 else if (operand[0]->reference.target_type == ACPI_TYPE_PACKAGE) { 812 /* 813 * The target is a package, we want to return the referenced 814 * element of the package. We must add another reference to 815 * this object, however. 816 */ 817 return_desc = *(operand[0]->reference.where); 818 if (!return_desc) { 819 /* 820 * We can't return a NULL dereferenced value. This is 821 * an uninitialized package element and is thus a 822 * severe error. 823 */ 824 825 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n", 826 operand[0])); 827 status = AE_AML_UNINITIALIZED_ELEMENT; 828 goto cleanup; 829 } 830 831 acpi_ut_add_reference (return_desc); 832 } 833 834 else { 835 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Target_type %X in obj %p\n", 836 operand[0]->reference.target_type, operand[0])); 837 status = AE_AML_OPERAND_TYPE; 838 goto cleanup; 839 } 840 841 break; 842 843 844 case AML_REF_OF_OP: 845 846 return_desc = operand[0]->reference.object; 847 848 /* Add another reference to the object! */ 849 850 acpi_ut_add_reference (return_desc); 851 break; 852 } 853 } 854 855 break; 856 857 858 default: 859 860 REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n", 861 walk_state->opcode)); 862 status = AE_AML_BAD_OPCODE; 863 goto cleanup; 864 } 865 866 867cleanup: 868 869 /* Delete return object on error */ 870 871 if (ACPI_FAILURE (status)) { 872 acpi_ut_remove_reference (return_desc); 873 } 874 875 walk_state->result_obj = return_desc; 876 return_ACPI_STATUS (status); 877} 878 879