1 /****************************************************************************** 2 * 3 * Module Name: dsopcode - Dispatcher support for regions and fields 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acparser.h" 47 #include "amlcode.h" 48 #include "acdispat.h" 49 #include "acinterp.h" 50 #include "acnamesp.h" 51 #include "acevents.h" 52 #include "actables.h" 53 54 #define _COMPONENT ACPI_DISPATCHER 55 ACPI_MODULE_NAME("dsopcode") 56 57 /* Local prototypes */ 58 static acpi_status 59 acpi_ds_init_buffer_field(u16 aml_opcode, 60 union acpi_operand_object *obj_desc, 61 union acpi_operand_object *buffer_desc, 62 union acpi_operand_object *offset_desc, 63 union acpi_operand_object *length_desc, 64 union acpi_operand_object *result_desc); 65 66 /******************************************************************************* 67 * 68 * FUNCTION: acpi_ds_initialize_region 69 * 70 * PARAMETERS: obj_handle - Region namespace node 71 * 72 * RETURN: Status 73 * 74 * DESCRIPTION: Front end to ev_initialize_region 75 * 76 ******************************************************************************/ 77 78 acpi_status acpi_ds_initialize_region(acpi_handle obj_handle) 79 { 80 union acpi_operand_object *obj_desc; 81 acpi_status status; 82 83 obj_desc = acpi_ns_get_attached_object(obj_handle); 84 85 /* Namespace is NOT locked */ 86 87 status = acpi_ev_initialize_region(obj_desc); 88 return (status); 89 } 90 91 /******************************************************************************* 92 * 93 * FUNCTION: acpi_ds_init_buffer_field 94 * 95 * PARAMETERS: aml_opcode - create_xxx_field 96 * obj_desc - buffer_field object 97 * buffer_desc - Host Buffer 98 * offset_desc - Offset into buffer 99 * length_desc - Length of field (CREATE_FIELD_OP only) 100 * result_desc - Where to store the result 101 * 102 * RETURN: Status 103 * 104 * DESCRIPTION: Perform actual initialization of a buffer field 105 * 106 ******************************************************************************/ 107 108 static acpi_status 109 acpi_ds_init_buffer_field(u16 aml_opcode, 110 union acpi_operand_object *obj_desc, 111 union acpi_operand_object *buffer_desc, 112 union acpi_operand_object *offset_desc, 113 union acpi_operand_object *length_desc, 114 union acpi_operand_object *result_desc) 115 { 116 u32 offset; 117 u32 bit_offset; 118 u32 bit_count; 119 u8 field_flags; 120 acpi_status status; 121 122 ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc); 123 124 /* Host object must be a Buffer */ 125 126 if (buffer_desc->common.type != ACPI_TYPE_BUFFER) { 127 ACPI_ERROR((AE_INFO, 128 "Target of Create Field is not a Buffer object - %s", 129 acpi_ut_get_object_type_name(buffer_desc))); 130 131 status = AE_AML_OPERAND_TYPE; 132 goto cleanup; 133 } 134 135 /* 136 * The last parameter to all of these opcodes (result_desc) started 137 * out as a name_string, and should therefore now be a NS node 138 * after resolution in acpi_ex_resolve_operands(). 139 */ 140 if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) { 141 ACPI_ERROR((AE_INFO, 142 "(%s) destination not a NS Node [%s]", 143 acpi_ps_get_opcode_name(aml_opcode), 144 acpi_ut_get_descriptor_name(result_desc))); 145 146 status = AE_AML_OPERAND_TYPE; 147 goto cleanup; 148 } 149 150 offset = (u32) offset_desc->integer.value; 151 152 /* 153 * Setup the Bit offsets and counts, according to the opcode 154 */ 155 switch (aml_opcode) { 156 case AML_CREATE_FIELD_OP: 157 158 /* Offset is in bits, count is in bits */ 159 160 field_flags = AML_FIELD_ACCESS_BYTE; 161 bit_offset = offset; 162 bit_count = (u32) length_desc->integer.value; 163 164 /* Must have a valid (>0) bit count */ 165 166 if (bit_count == 0) { 167 ACPI_ERROR((AE_INFO, 168 "Attempt to CreateField of length zero")); 169 status = AE_AML_OPERAND_VALUE; 170 goto cleanup; 171 } 172 break; 173 174 case AML_CREATE_BIT_FIELD_OP: 175 176 /* Offset is in bits, Field is one bit */ 177 178 bit_offset = offset; 179 bit_count = 1; 180 field_flags = AML_FIELD_ACCESS_BYTE; 181 break; 182 183 case AML_CREATE_BYTE_FIELD_OP: 184 185 /* Offset is in bytes, field is one byte */ 186 187 bit_offset = 8 * offset; 188 bit_count = 8; 189 field_flags = AML_FIELD_ACCESS_BYTE; 190 break; 191 192 case AML_CREATE_WORD_FIELD_OP: 193 194 /* Offset is in bytes, field is one word */ 195 196 bit_offset = 8 * offset; 197 bit_count = 16; 198 field_flags = AML_FIELD_ACCESS_WORD; 199 break; 200 201 case AML_CREATE_DWORD_FIELD_OP: 202 203 /* Offset is in bytes, field is one dword */ 204 205 bit_offset = 8 * offset; 206 bit_count = 32; 207 field_flags = AML_FIELD_ACCESS_DWORD; 208 break; 209 210 case AML_CREATE_QWORD_FIELD_OP: 211 212 /* Offset is in bytes, field is one qword */ 213 214 bit_offset = 8 * offset; 215 bit_count = 64; 216 field_flags = AML_FIELD_ACCESS_QWORD; 217 break; 218 219 default: 220 221 ACPI_ERROR((AE_INFO, 222 "Unknown field creation opcode 0x%02X", 223 aml_opcode)); 224 status = AE_AML_BAD_OPCODE; 225 goto cleanup; 226 } 227 228 /* Entire field must fit within the current length of the buffer */ 229 230 if ((bit_offset + bit_count) > (8 * (u32)buffer_desc->buffer.length)) { 231 ACPI_ERROR((AE_INFO, 232 "Field [%4.4s] at bit offset/length %u/%u " 233 "exceeds size of target Buffer (%u bits)", 234 acpi_ut_get_node_name(result_desc), bit_offset, 235 bit_count, 8 * (u32)buffer_desc->buffer.length)); 236 status = AE_AML_BUFFER_LIMIT; 237 goto cleanup; 238 } 239 240 /* 241 * Initialize areas of the field object that are common to all fields 242 * For field_flags, use LOCK_RULE = 0 (NO_LOCK), 243 * UPDATE_RULE = 0 (UPDATE_PRESERVE) 244 */ 245 status = 246 acpi_ex_prep_common_field_object(obj_desc, field_flags, 0, 247 bit_offset, bit_count); 248 if (ACPI_FAILURE(status)) { 249 goto cleanup; 250 } 251 252 obj_desc->buffer_field.buffer_obj = buffer_desc; 253 254 /* Reference count for buffer_desc inherits obj_desc count */ 255 256 buffer_desc->common.reference_count = (u16) 257 (buffer_desc->common.reference_count + 258 obj_desc->common.reference_count); 259 260 cleanup: 261 262 /* Always delete the operands */ 263 264 acpi_ut_remove_reference(offset_desc); 265 acpi_ut_remove_reference(buffer_desc); 266 267 if (aml_opcode == AML_CREATE_FIELD_OP) { 268 acpi_ut_remove_reference(length_desc); 269 } 270 271 /* On failure, delete the result descriptor */ 272 273 if (ACPI_FAILURE(status)) { 274 acpi_ut_remove_reference(result_desc); /* Result descriptor */ 275 } else { 276 /* Now the address and length are valid for this buffer_field */ 277 278 obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID; 279 } 280 281 return_ACPI_STATUS(status); 282 } 283 284 /******************************************************************************* 285 * 286 * FUNCTION: acpi_ds_eval_buffer_field_operands 287 * 288 * PARAMETERS: walk_state - Current walk 289 * op - A valid buffer_field Op object 290 * 291 * RETURN: Status 292 * 293 * DESCRIPTION: Get buffer_field Buffer and Index 294 * Called from acpi_ds_exec_end_op during buffer_field parse tree walk 295 * 296 ******************************************************************************/ 297 298 acpi_status 299 acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, 300 union acpi_parse_object *op) 301 { 302 acpi_status status; 303 union acpi_operand_object *obj_desc; 304 struct acpi_namespace_node *node; 305 union acpi_parse_object *next_op; 306 307 ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op); 308 309 /* 310 * This is where we evaluate the address and length fields of the 311 * create_xxx_field declaration 312 */ 313 node = op->common.node; 314 315 /* next_op points to the op that holds the Buffer */ 316 317 next_op = op->common.value.arg; 318 319 /* Evaluate/create the address and length operands */ 320 321 status = acpi_ds_create_operands(walk_state, next_op); 322 if (ACPI_FAILURE(status)) { 323 return_ACPI_STATUS(status); 324 } 325 326 obj_desc = acpi_ns_get_attached_object(node); 327 if (!obj_desc) { 328 return_ACPI_STATUS(AE_NOT_EXIST); 329 } 330 331 /* Resolve the operands */ 332 333 status = 334 acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS, 335 walk_state); 336 if (ACPI_FAILURE(status)) { 337 ACPI_ERROR((AE_INFO, "(%s) bad operand(s), status 0x%X", 338 acpi_ps_get_opcode_name(op->common.aml_opcode), 339 status)); 340 341 return_ACPI_STATUS(status); 342 } 343 344 /* Initialize the Buffer Field */ 345 346 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { 347 348 /* NOTE: Slightly different operands for this opcode */ 349 350 status = 351 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, 352 walk_state->operands[0], 353 walk_state->operands[1], 354 walk_state->operands[2], 355 walk_state->operands[3]); 356 } else { 357 /* All other, create_xxx_field opcodes */ 358 359 status = 360 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, 361 walk_state->operands[0], 362 walk_state->operands[1], NULL, 363 walk_state->operands[2]); 364 } 365 366 return_ACPI_STATUS(status); 367 } 368 369 /******************************************************************************* 370 * 371 * FUNCTION: acpi_ds_eval_region_operands 372 * 373 * PARAMETERS: walk_state - Current walk 374 * op - A valid region Op object 375 * 376 * RETURN: Status 377 * 378 * DESCRIPTION: Get region address and length 379 * Called from acpi_ds_exec_end_op during op_region parse tree walk 380 * 381 ******************************************************************************/ 382 383 acpi_status 384 acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, 385 union acpi_parse_object *op) 386 { 387 acpi_status status; 388 union acpi_operand_object *obj_desc; 389 union acpi_operand_object *operand_desc; 390 struct acpi_namespace_node *node; 391 union acpi_parse_object *next_op; 392 393 ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op); 394 395 /* 396 * This is where we evaluate the address and length fields of the 397 * op_region declaration 398 */ 399 node = op->common.node; 400 401 /* next_op points to the op that holds the space_ID */ 402 403 next_op = op->common.value.arg; 404 405 /* next_op points to address op */ 406 407 next_op = next_op->common.next; 408 409 /* Evaluate/create the address and length operands */ 410 411 status = acpi_ds_create_operands(walk_state, next_op); 412 if (ACPI_FAILURE(status)) { 413 return_ACPI_STATUS(status); 414 } 415 416 /* Resolve the length and address operands to numbers */ 417 418 status = 419 acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS, 420 walk_state); 421 if (ACPI_FAILURE(status)) { 422 return_ACPI_STATUS(status); 423 } 424 425 obj_desc = acpi_ns_get_attached_object(node); 426 if (!obj_desc) { 427 return_ACPI_STATUS(AE_NOT_EXIST); 428 } 429 430 /* 431 * Get the length operand and save it 432 * (at Top of stack) 433 */ 434 operand_desc = walk_state->operands[walk_state->num_operands - 1]; 435 436 obj_desc->region.length = (u32) operand_desc->integer.value; 437 acpi_ut_remove_reference(operand_desc); 438 439 /* 440 * Get the address and save it 441 * (at top of stack - 1) 442 */ 443 operand_desc = walk_state->operands[walk_state->num_operands - 2]; 444 445 obj_desc->region.address = (acpi_physical_address) 446 operand_desc->integer.value; 447 acpi_ut_remove_reference(operand_desc); 448 449 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 450 obj_desc, 451 ACPI_FORMAT_UINT64(obj_desc->region.address), 452 obj_desc->region.length)); 453 454 /* Now the address and length are valid for this opregion */ 455 456 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 457 return_ACPI_STATUS(status); 458 } 459 460 /******************************************************************************* 461 * 462 * FUNCTION: acpi_ds_eval_table_region_operands 463 * 464 * PARAMETERS: walk_state - Current walk 465 * op - A valid region Op object 466 * 467 * RETURN: Status 468 * 469 * DESCRIPTION: Get region address and length. 470 * Called from acpi_ds_exec_end_op during data_table_region parse 471 * tree walk. 472 * 473 ******************************************************************************/ 474 475 acpi_status 476 acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, 477 union acpi_parse_object *op) 478 { 479 acpi_status status; 480 union acpi_operand_object *obj_desc; 481 union acpi_operand_object **operand; 482 struct acpi_namespace_node *node; 483 union acpi_parse_object *next_op; 484 struct acpi_table_header *table; 485 u32 table_index; 486 487 ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); 488 489 /* 490 * This is where we evaluate the Signature string, oem_id string, 491 * and oem_table_id string of the Data Table Region declaration 492 */ 493 node = op->common.node; 494 495 /* next_op points to Signature string op */ 496 497 next_op = op->common.value.arg; 498 499 /* 500 * Evaluate/create the Signature string, oem_id string, 501 * and oem_table_id string operands 502 */ 503 status = acpi_ds_create_operands(walk_state, next_op); 504 if (ACPI_FAILURE(status)) { 505 return_ACPI_STATUS(status); 506 } 507 508 operand = &walk_state->operands[0]; 509 510 /* 511 * Resolve the Signature string, oem_id string, 512 * and oem_table_id string operands 513 */ 514 status = 515 acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS, 516 walk_state); 517 if (ACPI_FAILURE(status)) { 518 goto cleanup; 519 } 520 521 /* Find the ACPI table */ 522 523 status = acpi_tb_find_table(operand[0]->string.pointer, 524 operand[1]->string.pointer, 525 operand[2]->string.pointer, &table_index); 526 if (ACPI_FAILURE(status)) { 527 if (status == AE_NOT_FOUND) { 528 ACPI_ERROR((AE_INFO, 529 "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT", 530 operand[0]->string.pointer, 531 operand[1]->string.pointer, 532 operand[2]->string.pointer)); 533 } 534 goto cleanup; 535 } 536 537 status = acpi_get_table_by_index(table_index, &table); 538 if (ACPI_FAILURE(status)) { 539 goto cleanup; 540 } 541 542 obj_desc = acpi_ns_get_attached_object(node); 543 if (!obj_desc) { 544 status = AE_NOT_EXIST; 545 goto cleanup; 546 } 547 548 obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table); 549 obj_desc->region.length = table->length; 550 551 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 552 obj_desc, 553 ACPI_FORMAT_UINT64(obj_desc->region.address), 554 obj_desc->region.length)); 555 556 /* Now the address and length are valid for this opregion */ 557 558 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 559 560 cleanup: 561 acpi_ut_remove_reference(operand[0]); 562 acpi_ut_remove_reference(operand[1]); 563 acpi_ut_remove_reference(operand[2]); 564 565 return_ACPI_STATUS(status); 566 } 567 568 /******************************************************************************* 569 * 570 * FUNCTION: acpi_ds_eval_data_object_operands 571 * 572 * PARAMETERS: walk_state - Current walk 573 * op - A valid data_object Op object 574 * obj_desc - data_object 575 * 576 * RETURN: Status 577 * 578 * DESCRIPTION: Get the operands and complete the following data object types: 579 * Buffer, Package. 580 * 581 ******************************************************************************/ 582 583 acpi_status 584 acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, 585 union acpi_parse_object *op, 586 union acpi_operand_object *obj_desc) 587 { 588 acpi_status status; 589 union acpi_operand_object *arg_desc; 590 u32 length; 591 592 ACPI_FUNCTION_TRACE(ds_eval_data_object_operands); 593 594 /* The first operand (for all of these data objects) is the length */ 595 596 /* 597 * Set proper index into operand stack for acpi_ds_obj_stack_push 598 * invoked inside acpi_ds_create_operand. 599 */ 600 walk_state->operand_index = walk_state->num_operands; 601 602 /* Ignore if child is not valid */ 603 604 if (!op->common.value.arg) { 605 ACPI_ERROR((AE_INFO, 606 "Dispatch: Missing child while executing TermArg for %X", 607 op->common.aml_opcode)); 608 return_ACPI_STATUS(AE_OK); 609 } 610 611 status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); 612 if (ACPI_FAILURE(status)) { 613 return_ACPI_STATUS(status); 614 } 615 616 status = acpi_ex_resolve_operands(walk_state->opcode, 617 &(walk_state-> 618 operands[walk_state->num_operands - 619 1]), walk_state); 620 if (ACPI_FAILURE(status)) { 621 return_ACPI_STATUS(status); 622 } 623 624 /* Extract length operand */ 625 626 arg_desc = walk_state->operands[walk_state->num_operands - 1]; 627 length = (u32) arg_desc->integer.value; 628 629 /* Cleanup for length operand */ 630 631 status = acpi_ds_obj_stack_pop(1, walk_state); 632 if (ACPI_FAILURE(status)) { 633 return_ACPI_STATUS(status); 634 } 635 636 acpi_ut_remove_reference(arg_desc); 637 638 /* 639 * Create the actual data object 640 */ 641 switch (op->common.aml_opcode) { 642 case AML_BUFFER_OP: 643 644 status = 645 acpi_ds_build_internal_buffer_obj(walk_state, op, length, 646 &obj_desc); 647 break; 648 649 case AML_PACKAGE_OP: 650 case AML_VARIABLE_PACKAGE_OP: 651 652 status = 653 acpi_ds_build_internal_package_obj(walk_state, op, length, 654 &obj_desc); 655 break; 656 657 default: 658 659 return_ACPI_STATUS(AE_AML_BAD_OPCODE); 660 } 661 662 if (ACPI_SUCCESS(status)) { 663 /* 664 * Return the object in the walk_state, unless the parent is a package - 665 * in this case, the return object will be stored in the parse tree 666 * for the package. 667 */ 668 if ((!op->common.parent) || 669 ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && 670 (op->common.parent->common.aml_opcode != 671 AML_VARIABLE_PACKAGE_OP) 672 && (op->common.parent->common.aml_opcode != 673 AML_NAME_OP))) { 674 walk_state->result_obj = obj_desc; 675 } 676 } 677 678 return_ACPI_STATUS(status); 679 } 680 681 /******************************************************************************* 682 * 683 * FUNCTION: acpi_ds_eval_bank_field_operands 684 * 685 * PARAMETERS: walk_state - Current walk 686 * op - A valid bank_field Op object 687 * 688 * RETURN: Status 689 * 690 * DESCRIPTION: Get bank_field bank_value 691 * Called from acpi_ds_exec_end_op during bank_field parse tree walk 692 * 693 ******************************************************************************/ 694 695 acpi_status 696 acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, 697 union acpi_parse_object *op) 698 { 699 acpi_status status; 700 union acpi_operand_object *obj_desc; 701 union acpi_operand_object *operand_desc; 702 struct acpi_namespace_node *node; 703 union acpi_parse_object *next_op; 704 union acpi_parse_object *arg; 705 706 ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op); 707 708 /* 709 * This is where we evaluate the bank_value field of the 710 * bank_field declaration 711 */ 712 713 /* next_op points to the op that holds the Region */ 714 715 next_op = op->common.value.arg; 716 717 /* next_op points to the op that holds the Bank Register */ 718 719 next_op = next_op->common.next; 720 721 /* next_op points to the op that holds the Bank Value */ 722 723 next_op = next_op->common.next; 724 725 /* 726 * Set proper index into operand stack for acpi_ds_obj_stack_push 727 * invoked inside acpi_ds_create_operand. 728 * 729 * We use walk_state->Operands[0] to store the evaluated bank_value 730 */ 731 walk_state->operand_index = 0; 732 733 status = acpi_ds_create_operand(walk_state, next_op, 0); 734 if (ACPI_FAILURE(status)) { 735 return_ACPI_STATUS(status); 736 } 737 738 status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state); 739 if (ACPI_FAILURE(status)) { 740 return_ACPI_STATUS(status); 741 } 742 743 ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, 744 acpi_ps_get_opcode_name(op->common.aml_opcode), 1); 745 /* 746 * Get the bank_value operand and save it 747 * (at Top of stack) 748 */ 749 operand_desc = walk_state->operands[0]; 750 751 /* Arg points to the start Bank Field */ 752 753 arg = acpi_ps_get_arg(op, 4); 754 while (arg) { 755 756 /* Ignore OFFSET and ACCESSAS terms here */ 757 758 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 759 node = arg->common.node; 760 761 obj_desc = acpi_ns_get_attached_object(node); 762 if (!obj_desc) { 763 return_ACPI_STATUS(AE_NOT_EXIST); 764 } 765 766 obj_desc->bank_field.value = 767 (u32) operand_desc->integer.value; 768 } 769 770 /* Move to next field in the list */ 771 772 arg = arg->common.next; 773 } 774 775 acpi_ut_remove_reference(operand_desc); 776 return_ACPI_STATUS(status); 777 } 778