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