1 /****************************************************************************** 2 * 3 * Module Name: dsopcode - Dispatcher support for regions and fields 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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_NATIVE_UINT(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 u32 table_index; 484 struct acpi_table_header *table; 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 /* 508 * Resolve the Signature string, oem_id string, 509 * and oem_table_id string operands 510 */ 511 status = acpi_ex_resolve_operands(op->common.aml_opcode, 512 ACPI_WALK_OPERANDS, walk_state); 513 if (ACPI_FAILURE(status)) { 514 return_ACPI_STATUS(status); 515 } 516 517 operand = &walk_state->operands[0]; 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 return_ACPI_STATUS(status); 526 } 527 528 acpi_ut_remove_reference(operand[0]); 529 acpi_ut_remove_reference(operand[1]); 530 acpi_ut_remove_reference(operand[2]); 531 532 status = acpi_get_table_by_index(table_index, &table); 533 if (ACPI_FAILURE(status)) { 534 return_ACPI_STATUS(status); 535 } 536 537 obj_desc = acpi_ns_get_attached_object(node); 538 if (!obj_desc) { 539 return_ACPI_STATUS(AE_NOT_EXIST); 540 } 541 542 obj_desc->region.address = 543 (acpi_physical_address) ACPI_TO_INTEGER(table); 544 obj_desc->region.length = table->length; 545 546 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 547 obj_desc, 548 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), 549 obj_desc->region.length)); 550 551 /* Now the address and length are valid for this opregion */ 552 553 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 554 555 return_ACPI_STATUS(status); 556 } 557 558 /******************************************************************************* 559 * 560 * FUNCTION: acpi_ds_eval_data_object_operands 561 * 562 * PARAMETERS: walk_state - Current walk 563 * op - A valid data_object Op object 564 * obj_desc - data_object 565 * 566 * RETURN: Status 567 * 568 * DESCRIPTION: Get the operands and complete the following data object types: 569 * Buffer, Package. 570 * 571 ******************************************************************************/ 572 573 acpi_status 574 acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, 575 union acpi_parse_object *op, 576 union acpi_operand_object *obj_desc) 577 { 578 acpi_status status; 579 union acpi_operand_object *arg_desc; 580 u32 length; 581 582 ACPI_FUNCTION_TRACE(ds_eval_data_object_operands); 583 584 /* The first operand (for all of these data objects) is the length */ 585 586 /* 587 * Set proper index into operand stack for acpi_ds_obj_stack_push 588 * invoked inside acpi_ds_create_operand. 589 */ 590 walk_state->operand_index = walk_state->num_operands; 591 592 status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); 593 if (ACPI_FAILURE(status)) { 594 return_ACPI_STATUS(status); 595 } 596 597 status = acpi_ex_resolve_operands(walk_state->opcode, 598 &(walk_state-> 599 operands[walk_state->num_operands - 600 1]), walk_state); 601 if (ACPI_FAILURE(status)) { 602 return_ACPI_STATUS(status); 603 } 604 605 /* Extract length operand */ 606 607 arg_desc = walk_state->operands[walk_state->num_operands - 1]; 608 length = (u32) arg_desc->integer.value; 609 610 /* Cleanup for length operand */ 611 612 status = acpi_ds_obj_stack_pop(1, walk_state); 613 if (ACPI_FAILURE(status)) { 614 return_ACPI_STATUS(status); 615 } 616 617 acpi_ut_remove_reference(arg_desc); 618 619 /* 620 * Create the actual data object 621 */ 622 switch (op->common.aml_opcode) { 623 case AML_BUFFER_OP: 624 625 status = 626 acpi_ds_build_internal_buffer_obj(walk_state, op, length, 627 &obj_desc); 628 break; 629 630 case AML_PACKAGE_OP: 631 case AML_VAR_PACKAGE_OP: 632 633 status = 634 acpi_ds_build_internal_package_obj(walk_state, op, length, 635 &obj_desc); 636 break; 637 638 default: 639 640 return_ACPI_STATUS(AE_AML_BAD_OPCODE); 641 } 642 643 if (ACPI_SUCCESS(status)) { 644 /* 645 * Return the object in the walk_state, unless the parent is a package - 646 * in this case, the return object will be stored in the parse tree 647 * for the package. 648 */ 649 if ((!op->common.parent) || 650 ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && 651 (op->common.parent->common.aml_opcode != 652 AML_VAR_PACKAGE_OP) 653 && (op->common.parent->common.aml_opcode != 654 AML_NAME_OP))) { 655 walk_state->result_obj = obj_desc; 656 } 657 } 658 659 return_ACPI_STATUS(status); 660 } 661 662 /******************************************************************************* 663 * 664 * FUNCTION: acpi_ds_eval_bank_field_operands 665 * 666 * PARAMETERS: walk_state - Current walk 667 * op - A valid bank_field Op object 668 * 669 * RETURN: Status 670 * 671 * DESCRIPTION: Get bank_field bank_value 672 * Called from acpi_ds_exec_end_op during bank_field parse tree walk 673 * 674 ******************************************************************************/ 675 676 acpi_status 677 acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, 678 union acpi_parse_object *op) 679 { 680 acpi_status status; 681 union acpi_operand_object *obj_desc; 682 union acpi_operand_object *operand_desc; 683 struct acpi_namespace_node *node; 684 union acpi_parse_object *next_op; 685 union acpi_parse_object *arg; 686 687 ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op); 688 689 /* 690 * This is where we evaluate the bank_value field of the 691 * bank_field declaration 692 */ 693 694 /* next_op points to the op that holds the Region */ 695 696 next_op = op->common.value.arg; 697 698 /* next_op points to the op that holds the Bank Register */ 699 700 next_op = next_op->common.next; 701 702 /* next_op points to the op that holds the Bank Value */ 703 704 next_op = next_op->common.next; 705 706 /* 707 * Set proper index into operand stack for acpi_ds_obj_stack_push 708 * invoked inside acpi_ds_create_operand. 709 * 710 * We use walk_state->Operands[0] to store the evaluated bank_value 711 */ 712 walk_state->operand_index = 0; 713 714 status = acpi_ds_create_operand(walk_state, next_op, 0); 715 if (ACPI_FAILURE(status)) { 716 return_ACPI_STATUS(status); 717 } 718 719 status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state); 720 if (ACPI_FAILURE(status)) { 721 return_ACPI_STATUS(status); 722 } 723 724 ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, 725 acpi_ps_get_opcode_name(op->common.aml_opcode), 1); 726 /* 727 * Get the bank_value operand and save it 728 * (at Top of stack) 729 */ 730 operand_desc = walk_state->operands[0]; 731 732 /* Arg points to the start Bank Field */ 733 734 arg = acpi_ps_get_arg(op, 4); 735 while (arg) { 736 737 /* Ignore OFFSET and ACCESSAS terms here */ 738 739 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 740 node = arg->common.node; 741 742 obj_desc = acpi_ns_get_attached_object(node); 743 if (!obj_desc) { 744 return_ACPI_STATUS(AE_NOT_EXIST); 745 } 746 747 obj_desc->bank_field.value = 748 (u32) operand_desc->integer.value; 749 } 750 751 /* Move to next field in the list */ 752 753 arg = arg->common.next; 754 } 755 756 acpi_ut_remove_reference(operand_desc); 757 return_ACPI_STATUS(status); 758 } 759