1 /****************************************************************************** 2 * 3 * Module Name: dsopcode - Dispatcher support for regions and fields 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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, FALSE); 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 %u exceeds Buffer [%4.4s] size %u (bits)", 233 acpi_ut_get_node_name(result_desc), 234 bit_offset + bit_count, 235 acpi_ut_get_node_name(buffer_desc->buffer.node), 236 8 * (u32) buffer_desc->buffer.length)); 237 status = AE_AML_BUFFER_LIMIT; 238 goto cleanup; 239 } 240 241 /* 242 * Initialize areas of the field object that are common to all fields 243 * For field_flags, use LOCK_RULE = 0 (NO_LOCK), 244 * UPDATE_RULE = 0 (UPDATE_PRESERVE) 245 */ 246 status = 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 = acpi_ex_resolve_operands(op->common.aml_opcode, 334 ACPI_WALK_OPERANDS, walk_state); 335 if (ACPI_FAILURE(status)) { 336 ACPI_ERROR((AE_INFO, "(%s) bad operand(s), status 0x%X", 337 acpi_ps_get_opcode_name(op->common.aml_opcode), 338 status)); 339 340 return_ACPI_STATUS(status); 341 } 342 343 /* Initialize the Buffer Field */ 344 345 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { 346 347 /* NOTE: Slightly different operands for this opcode */ 348 349 status = 350 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, 351 walk_state->operands[0], 352 walk_state->operands[1], 353 walk_state->operands[2], 354 walk_state->operands[3]); 355 } else { 356 /* All other, create_xxx_field opcodes */ 357 358 status = 359 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, 360 walk_state->operands[0], 361 walk_state->operands[1], NULL, 362 walk_state->operands[2]); 363 } 364 365 return_ACPI_STATUS(status); 366 } 367 368 /******************************************************************************* 369 * 370 * FUNCTION: acpi_ds_eval_region_operands 371 * 372 * PARAMETERS: walk_state - Current walk 373 * op - A valid region Op object 374 * 375 * RETURN: Status 376 * 377 * DESCRIPTION: Get region address and length 378 * Called from acpi_ds_exec_end_op during op_region parse tree walk 379 * 380 ******************************************************************************/ 381 382 acpi_status 383 acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, 384 union acpi_parse_object *op) 385 { 386 acpi_status status; 387 union acpi_operand_object *obj_desc; 388 union acpi_operand_object *operand_desc; 389 struct acpi_namespace_node *node; 390 union acpi_parse_object *next_op; 391 392 ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op); 393 394 /* 395 * This is where we evaluate the address and length fields of the 396 * op_region declaration 397 */ 398 node = op->common.node; 399 400 /* next_op points to the op that holds the space_ID */ 401 402 next_op = op->common.value.arg; 403 404 /* next_op points to address op */ 405 406 next_op = next_op->common.next; 407 408 /* Evaluate/create the address and length operands */ 409 410 status = acpi_ds_create_operands(walk_state, next_op); 411 if (ACPI_FAILURE(status)) { 412 return_ACPI_STATUS(status); 413 } 414 415 /* Resolve the length and address operands to numbers */ 416 417 status = acpi_ex_resolve_operands(op->common.aml_opcode, 418 ACPI_WALK_OPERANDS, walk_state); 419 if (ACPI_FAILURE(status)) { 420 return_ACPI_STATUS(status); 421 } 422 423 obj_desc = acpi_ns_get_attached_object(node); 424 if (!obj_desc) { 425 return_ACPI_STATUS(AE_NOT_EXIST); 426 } 427 428 /* 429 * Get the length operand and save it 430 * (at Top of stack) 431 */ 432 operand_desc = walk_state->operands[walk_state->num_operands - 1]; 433 434 obj_desc->region.length = (u32) operand_desc->integer.value; 435 acpi_ut_remove_reference(operand_desc); 436 437 /* 438 * Get the address and save it 439 * (at top of stack - 1) 440 */ 441 operand_desc = walk_state->operands[walk_state->num_operands - 2]; 442 443 obj_desc->region.address = (acpi_physical_address) 444 operand_desc->integer.value; 445 acpi_ut_remove_reference(operand_desc); 446 447 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 448 obj_desc, 449 ACPI_FORMAT_UINT64(obj_desc->region.address), 450 obj_desc->region.length)); 451 452 /* Now the address and length are valid for this opregion */ 453 454 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 455 456 return_ACPI_STATUS(status); 457 } 458 459 /******************************************************************************* 460 * 461 * FUNCTION: acpi_ds_eval_table_region_operands 462 * 463 * PARAMETERS: walk_state - Current walk 464 * op - A valid region Op object 465 * 466 * RETURN: Status 467 * 468 * DESCRIPTION: Get region address and length. 469 * Called from acpi_ds_exec_end_op during data_table_region parse 470 * tree walk. 471 * 472 ******************************************************************************/ 473 474 acpi_status 475 acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, 476 union acpi_parse_object *op) 477 { 478 acpi_status status; 479 union acpi_operand_object *obj_desc; 480 union acpi_operand_object **operand; 481 struct acpi_namespace_node *node; 482 union acpi_parse_object *next_op; 483 struct acpi_table_header *table; 484 u32 table_index; 485 486 ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); 487 488 /* 489 * This is where we evaluate the Signature string, oem_id string, 490 * and oem_table_id string of the Data Table Region declaration 491 */ 492 node = op->common.node; 493 494 /* next_op points to Signature string op */ 495 496 next_op = op->common.value.arg; 497 498 /* 499 * Evaluate/create the Signature string, oem_id string, 500 * and oem_table_id string operands 501 */ 502 status = acpi_ds_create_operands(walk_state, next_op); 503 if (ACPI_FAILURE(status)) { 504 return_ACPI_STATUS(status); 505 } 506 507 operand = &walk_state->operands[0]; 508 509 /* 510 * Resolve the Signature string, oem_id string, 511 * and oem_table_id string operands 512 */ 513 status = acpi_ex_resolve_operands(op->common.aml_opcode, 514 ACPI_WALK_OPERANDS, walk_state); 515 if (ACPI_FAILURE(status)) { 516 goto cleanup; 517 } 518 519 /* Find the ACPI table */ 520 521 status = acpi_tb_find_table(operand[0]->string.pointer, 522 operand[1]->string.pointer, 523 operand[2]->string.pointer, &table_index); 524 if (ACPI_FAILURE(status)) { 525 if (status == AE_NOT_FOUND) { 526 ACPI_ERROR((AE_INFO, 527 "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT", 528 operand[0]->string.pointer, 529 operand[1]->string.pointer, 530 operand[2]->string.pointer)); 531 } 532 goto cleanup; 533 } 534 535 status = acpi_get_table_by_index(table_index, &table); 536 if (ACPI_FAILURE(status)) { 537 goto cleanup; 538 } 539 540 obj_desc = acpi_ns_get_attached_object(node); 541 if (!obj_desc) { 542 status = AE_NOT_EXIST; 543 goto cleanup; 544 } 545 546 obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table); 547 obj_desc->region.length = table->length; 548 549 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 550 obj_desc, 551 ACPI_FORMAT_UINT64(obj_desc->region.address), 552 obj_desc->region.length)); 553 554 /* Now the address and length are valid for this opregion */ 555 556 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 557 558 cleanup: 559 acpi_ut_remove_reference(operand[0]); 560 acpi_ut_remove_reference(operand[1]); 561 acpi_ut_remove_reference(operand[2]); 562 563 return_ACPI_STATUS(status); 564 } 565 566 /******************************************************************************* 567 * 568 * FUNCTION: acpi_ds_eval_data_object_operands 569 * 570 * PARAMETERS: walk_state - Current walk 571 * op - A valid data_object Op object 572 * obj_desc - data_object 573 * 574 * RETURN: Status 575 * 576 * DESCRIPTION: Get the operands and complete the following data object types: 577 * Buffer, Package. 578 * 579 ******************************************************************************/ 580 581 acpi_status 582 acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, 583 union acpi_parse_object *op, 584 union acpi_operand_object *obj_desc) 585 { 586 acpi_status status; 587 union acpi_operand_object *arg_desc; 588 u32 length; 589 590 ACPI_FUNCTION_TRACE(ds_eval_data_object_operands); 591 592 /* The first operand (for all of these data objects) is the length */ 593 594 /* 595 * Set proper index into operand stack for acpi_ds_obj_stack_push 596 * invoked inside acpi_ds_create_operand. 597 */ 598 walk_state->operand_index = walk_state->num_operands; 599 600 status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); 601 if (ACPI_FAILURE(status)) { 602 return_ACPI_STATUS(status); 603 } 604 605 status = acpi_ex_resolve_operands(walk_state->opcode, 606 &(walk_state-> 607 operands[walk_state->num_operands - 608 1]), walk_state); 609 if (ACPI_FAILURE(status)) { 610 return_ACPI_STATUS(status); 611 } 612 613 /* Extract length operand */ 614 615 arg_desc = walk_state->operands[walk_state->num_operands - 1]; 616 length = (u32) arg_desc->integer.value; 617 618 /* Cleanup for length operand */ 619 620 status = acpi_ds_obj_stack_pop(1, walk_state); 621 if (ACPI_FAILURE(status)) { 622 return_ACPI_STATUS(status); 623 } 624 625 acpi_ut_remove_reference(arg_desc); 626 627 /* 628 * Create the actual data object 629 */ 630 switch (op->common.aml_opcode) { 631 case AML_BUFFER_OP: 632 633 status = 634 acpi_ds_build_internal_buffer_obj(walk_state, op, length, 635 &obj_desc); 636 break; 637 638 case AML_PACKAGE_OP: 639 case AML_VAR_PACKAGE_OP: 640 641 status = 642 acpi_ds_build_internal_package_obj(walk_state, op, length, 643 &obj_desc); 644 break; 645 646 default: 647 648 return_ACPI_STATUS(AE_AML_BAD_OPCODE); 649 } 650 651 if (ACPI_SUCCESS(status)) { 652 /* 653 * Return the object in the walk_state, unless the parent is a package - 654 * in this case, the return object will be stored in the parse tree 655 * for the package. 656 */ 657 if ((!op->common.parent) || 658 ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && 659 (op->common.parent->common.aml_opcode != 660 AML_VAR_PACKAGE_OP) 661 && (op->common.parent->common.aml_opcode != 662 AML_NAME_OP))) { 663 walk_state->result_obj = obj_desc; 664 } 665 } 666 667 return_ACPI_STATUS(status); 668 } 669 670 /******************************************************************************* 671 * 672 * FUNCTION: acpi_ds_eval_bank_field_operands 673 * 674 * PARAMETERS: walk_state - Current walk 675 * op - A valid bank_field Op object 676 * 677 * RETURN: Status 678 * 679 * DESCRIPTION: Get bank_field bank_value 680 * Called from acpi_ds_exec_end_op during bank_field parse tree walk 681 * 682 ******************************************************************************/ 683 684 acpi_status 685 acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, 686 union acpi_parse_object *op) 687 { 688 acpi_status status; 689 union acpi_operand_object *obj_desc; 690 union acpi_operand_object *operand_desc; 691 struct acpi_namespace_node *node; 692 union acpi_parse_object *next_op; 693 union acpi_parse_object *arg; 694 695 ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op); 696 697 /* 698 * This is where we evaluate the bank_value field of the 699 * bank_field declaration 700 */ 701 702 /* next_op points to the op that holds the Region */ 703 704 next_op = op->common.value.arg; 705 706 /* next_op points to the op that holds the Bank Register */ 707 708 next_op = next_op->common.next; 709 710 /* next_op points to the op that holds the Bank Value */ 711 712 next_op = next_op->common.next; 713 714 /* 715 * Set proper index into operand stack for acpi_ds_obj_stack_push 716 * invoked inside acpi_ds_create_operand. 717 * 718 * We use walk_state->Operands[0] to store the evaluated bank_value 719 */ 720 walk_state->operand_index = 0; 721 722 status = acpi_ds_create_operand(walk_state, next_op, 0); 723 if (ACPI_FAILURE(status)) { 724 return_ACPI_STATUS(status); 725 } 726 727 status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state); 728 if (ACPI_FAILURE(status)) { 729 return_ACPI_STATUS(status); 730 } 731 732 ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, 733 acpi_ps_get_opcode_name(op->common.aml_opcode), 1); 734 /* 735 * Get the bank_value operand and save it 736 * (at Top of stack) 737 */ 738 operand_desc = walk_state->operands[0]; 739 740 /* Arg points to the start Bank Field */ 741 742 arg = acpi_ps_get_arg(op, 4); 743 while (arg) { 744 745 /* Ignore OFFSET and ACCESSAS terms here */ 746 747 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 748 node = arg->common.node; 749 750 obj_desc = acpi_ns_get_attached_object(node); 751 if (!obj_desc) { 752 return_ACPI_STATUS(AE_NOT_EXIST); 753 } 754 755 obj_desc->bank_field.value = 756 (u32) operand_desc->integer.value; 757 } 758 759 /* Move to next field in the list */ 760 761 arg = arg->common.next; 762 } 763 764 acpi_ut_remove_reference(operand_desc); 765 return_ACPI_STATUS(status); 766 } 767