Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: dsopcode - Dispatcher support for regions and fields
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acparser.h"
0013 #include "amlcode.h"
0014 #include "acdispat.h"
0015 #include "acinterp.h"
0016 #include "acnamesp.h"
0017 #include "acevents.h"
0018 #include "actables.h"
0019 
0020 #define _COMPONENT          ACPI_DISPATCHER
0021 ACPI_MODULE_NAME("dsopcode")
0022 
0023 /* Local prototypes */
0024 static acpi_status
0025 acpi_ds_init_buffer_field(u16 aml_opcode,
0026               union acpi_operand_object *obj_desc,
0027               union acpi_operand_object *buffer_desc,
0028               union acpi_operand_object *offset_desc,
0029               union acpi_operand_object *length_desc,
0030               union acpi_operand_object *result_desc);
0031 
0032 /*******************************************************************************
0033  *
0034  * FUNCTION:    acpi_ds_initialize_region
0035  *
0036  * PARAMETERS:  obj_handle      - Region namespace node
0037  *
0038  * RETURN:      Status
0039  *
0040  * DESCRIPTION: Front end to ev_initialize_region
0041  *
0042  ******************************************************************************/
0043 
0044 acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
0045 {
0046     union acpi_operand_object *obj_desc;
0047     acpi_status status;
0048 
0049     obj_desc = acpi_ns_get_attached_object(obj_handle);
0050 
0051     /* Namespace is NOT locked */
0052 
0053     status = acpi_ev_initialize_region(obj_desc);
0054     return (status);
0055 }
0056 
0057 /*******************************************************************************
0058  *
0059  * FUNCTION:    acpi_ds_init_buffer_field
0060  *
0061  * PARAMETERS:  aml_opcode      - create_xxx_field
0062  *              obj_desc        - buffer_field object
0063  *              buffer_desc     - Host Buffer
0064  *              offset_desc     - Offset into buffer
0065  *              length_desc     - Length of field (CREATE_FIELD_OP only)
0066  *              result_desc     - Where to store the result
0067  *
0068  * RETURN:      Status
0069  *
0070  * DESCRIPTION: Perform actual initialization of a buffer field
0071  *
0072  ******************************************************************************/
0073 
0074 static acpi_status
0075 acpi_ds_init_buffer_field(u16 aml_opcode,
0076               union acpi_operand_object *obj_desc,
0077               union acpi_operand_object *buffer_desc,
0078               union acpi_operand_object *offset_desc,
0079               union acpi_operand_object *length_desc,
0080               union acpi_operand_object *result_desc)
0081 {
0082     u32 offset;
0083     u32 bit_offset;
0084     u32 bit_count;
0085     u8 field_flags;
0086     acpi_status status;
0087 
0088     ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc);
0089 
0090     /* Host object must be a Buffer */
0091 
0092     if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
0093         ACPI_ERROR((AE_INFO,
0094                 "Target of Create Field is not a Buffer object - %s",
0095                 acpi_ut_get_object_type_name(buffer_desc)));
0096 
0097         status = AE_AML_OPERAND_TYPE;
0098         goto cleanup;
0099     }
0100 
0101     /*
0102      * The last parameter to all of these opcodes (result_desc) started
0103      * out as a name_string, and should therefore now be a NS node
0104      * after resolution in acpi_ex_resolve_operands().
0105      */
0106     if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) {
0107         ACPI_ERROR((AE_INFO,
0108                 "(%s) destination not a NS Node [%s]",
0109                 acpi_ps_get_opcode_name(aml_opcode),
0110                 acpi_ut_get_descriptor_name(result_desc)));
0111 
0112         status = AE_AML_OPERAND_TYPE;
0113         goto cleanup;
0114     }
0115 
0116     offset = (u32) offset_desc->integer.value;
0117 
0118     /*
0119      * Setup the Bit offsets and counts, according to the opcode
0120      */
0121     switch (aml_opcode) {
0122     case AML_CREATE_FIELD_OP:
0123 
0124         /* Offset is in bits, count is in bits */
0125 
0126         field_flags = AML_FIELD_ACCESS_BYTE;
0127         bit_offset = offset;
0128         bit_count = (u32) length_desc->integer.value;
0129 
0130         /* Must have a valid (>0) bit count */
0131 
0132         if (bit_count == 0) {
0133             ACPI_BIOS_ERROR((AE_INFO,
0134                      "Attempt to CreateField of length zero"));
0135             status = AE_AML_OPERAND_VALUE;
0136             goto cleanup;
0137         }
0138         break;
0139 
0140     case AML_CREATE_BIT_FIELD_OP:
0141 
0142         /* Offset is in bits, Field is one bit */
0143 
0144         bit_offset = offset;
0145         bit_count = 1;
0146         field_flags = AML_FIELD_ACCESS_BYTE;
0147         break;
0148 
0149     case AML_CREATE_BYTE_FIELD_OP:
0150 
0151         /* Offset is in bytes, field is one byte */
0152 
0153         bit_offset = 8 * offset;
0154         bit_count = 8;
0155         field_flags = AML_FIELD_ACCESS_BYTE;
0156         break;
0157 
0158     case AML_CREATE_WORD_FIELD_OP:
0159 
0160         /* Offset is in bytes, field is one word */
0161 
0162         bit_offset = 8 * offset;
0163         bit_count = 16;
0164         field_flags = AML_FIELD_ACCESS_WORD;
0165         break;
0166 
0167     case AML_CREATE_DWORD_FIELD_OP:
0168 
0169         /* Offset is in bytes, field is one dword */
0170 
0171         bit_offset = 8 * offset;
0172         bit_count = 32;
0173         field_flags = AML_FIELD_ACCESS_DWORD;
0174         break;
0175 
0176     case AML_CREATE_QWORD_FIELD_OP:
0177 
0178         /* Offset is in bytes, field is one qword */
0179 
0180         bit_offset = 8 * offset;
0181         bit_count = 64;
0182         field_flags = AML_FIELD_ACCESS_QWORD;
0183         break;
0184 
0185     default:
0186 
0187         ACPI_ERROR((AE_INFO,
0188                 "Unknown field creation opcode 0x%02X",
0189                 aml_opcode));
0190         status = AE_AML_BAD_OPCODE;
0191         goto cleanup;
0192     }
0193 
0194     /* Entire field must fit within the current length of the buffer */
0195 
0196     if ((bit_offset + bit_count) > (8 * (u32)buffer_desc->buffer.length)) {
0197         status = AE_AML_BUFFER_LIMIT;
0198         ACPI_BIOS_EXCEPTION((AE_INFO, status,
0199                      "Field [%4.4s] at bit offset/length %u/%u "
0200                      "exceeds size of target Buffer (%u bits)",
0201                      acpi_ut_get_node_name(result_desc),
0202                      bit_offset, bit_count,
0203                      8 * (u32)buffer_desc->buffer.length));
0204         goto cleanup;
0205     }
0206 
0207     /*
0208      * Initialize areas of the field object that are common to all fields
0209      * For field_flags, use LOCK_RULE = 0 (NO_LOCK),
0210      * UPDATE_RULE = 0 (UPDATE_PRESERVE)
0211      */
0212     status =
0213         acpi_ex_prep_common_field_object(obj_desc, field_flags, 0,
0214                          bit_offset, bit_count);
0215     if (ACPI_FAILURE(status)) {
0216         goto cleanup;
0217     }
0218 
0219     obj_desc->buffer_field.buffer_obj = buffer_desc;
0220     obj_desc->buffer_field.is_create_field =
0221         aml_opcode == AML_CREATE_FIELD_OP;
0222 
0223     /* Reference count for buffer_desc inherits obj_desc count */
0224 
0225     buffer_desc->common.reference_count = (u16)
0226         (buffer_desc->common.reference_count +
0227          obj_desc->common.reference_count);
0228 
0229 cleanup:
0230 
0231     /* Always delete the operands */
0232 
0233     acpi_ut_remove_reference(offset_desc);
0234     acpi_ut_remove_reference(buffer_desc);
0235 
0236     if (aml_opcode == AML_CREATE_FIELD_OP) {
0237         acpi_ut_remove_reference(length_desc);
0238     }
0239 
0240     /* On failure, delete the result descriptor */
0241 
0242     if (ACPI_FAILURE(status)) {
0243         acpi_ut_remove_reference(result_desc);  /* Result descriptor */
0244     } else {
0245         /* Now the address and length are valid for this buffer_field */
0246 
0247         obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
0248     }
0249 
0250     return_ACPI_STATUS(status);
0251 }
0252 
0253 /*******************************************************************************
0254  *
0255  * FUNCTION:    acpi_ds_eval_buffer_field_operands
0256  *
0257  * PARAMETERS:  walk_state      - Current walk
0258  *              op              - A valid buffer_field Op object
0259  *
0260  * RETURN:      Status
0261  *
0262  * DESCRIPTION: Get buffer_field Buffer and Index
0263  *              Called from acpi_ds_exec_end_op during buffer_field parse tree walk
0264  *
0265  ******************************************************************************/
0266 
0267 acpi_status
0268 acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
0269                    union acpi_parse_object *op)
0270 {
0271     acpi_status status;
0272     union acpi_operand_object *obj_desc;
0273     struct acpi_namespace_node *node;
0274     union acpi_parse_object *next_op;
0275 
0276     ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op);
0277 
0278     /*
0279      * This is where we evaluate the address and length fields of the
0280      * create_xxx_field declaration
0281      */
0282     node = op->common.node;
0283 
0284     /* next_op points to the op that holds the Buffer */
0285 
0286     next_op = op->common.value.arg;
0287 
0288     /* Evaluate/create the address and length operands */
0289 
0290     status = acpi_ds_create_operands(walk_state, next_op);
0291     if (ACPI_FAILURE(status)) {
0292         return_ACPI_STATUS(status);
0293     }
0294 
0295     obj_desc = acpi_ns_get_attached_object(node);
0296     if (!obj_desc) {
0297         return_ACPI_STATUS(AE_NOT_EXIST);
0298     }
0299 
0300     /* Resolve the operands */
0301 
0302     status =
0303         acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS,
0304                      walk_state);
0305     if (ACPI_FAILURE(status)) {
0306         ACPI_ERROR((AE_INFO, "(%s) bad operand(s), status 0x%X",
0307                 acpi_ps_get_opcode_name(op->common.aml_opcode),
0308                 status));
0309 
0310         return_ACPI_STATUS(status);
0311     }
0312 
0313     /* Initialize the Buffer Field */
0314 
0315     if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
0316 
0317         /* NOTE: Slightly different operands for this opcode */
0318 
0319         status =
0320             acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
0321                           walk_state->operands[0],
0322                           walk_state->operands[1],
0323                           walk_state->operands[2],
0324                           walk_state->operands[3]);
0325     } else {
0326         /* All other, create_xxx_field opcodes */
0327 
0328         status =
0329             acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
0330                           walk_state->operands[0],
0331                           walk_state->operands[1], NULL,
0332                           walk_state->operands[2]);
0333     }
0334 
0335     return_ACPI_STATUS(status);
0336 }
0337 
0338 /*******************************************************************************
0339  *
0340  * FUNCTION:    acpi_ds_eval_region_operands
0341  *
0342  * PARAMETERS:  walk_state      - Current walk
0343  *              op              - A valid region Op object
0344  *
0345  * RETURN:      Status
0346  *
0347  * DESCRIPTION: Get region address and length
0348  *              Called from acpi_ds_exec_end_op during op_region parse tree walk
0349  *
0350  ******************************************************************************/
0351 
0352 acpi_status
0353 acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
0354                  union acpi_parse_object *op)
0355 {
0356     acpi_status status;
0357     union acpi_operand_object *obj_desc;
0358     union acpi_operand_object *operand_desc;
0359     struct acpi_namespace_node *node;
0360     union acpi_parse_object *next_op;
0361     acpi_adr_space_type space_id;
0362 
0363     ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op);
0364 
0365     /*
0366      * This is where we evaluate the address and length fields of the
0367      * op_region declaration
0368      */
0369     node = op->common.node;
0370 
0371     /* next_op points to the op that holds the space_ID */
0372 
0373     next_op = op->common.value.arg;
0374     space_id = (acpi_adr_space_type)next_op->common.value.integer;
0375 
0376     /* next_op points to address op */
0377 
0378     next_op = next_op->common.next;
0379 
0380     /* Evaluate/create the address and length operands */
0381 
0382     status = acpi_ds_create_operands(walk_state, next_op);
0383     if (ACPI_FAILURE(status)) {
0384         return_ACPI_STATUS(status);
0385     }
0386 
0387     /* Resolve the length and address operands to numbers */
0388 
0389     status =
0390         acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS,
0391                      walk_state);
0392     if (ACPI_FAILURE(status)) {
0393         return_ACPI_STATUS(status);
0394     }
0395 
0396     obj_desc = acpi_ns_get_attached_object(node);
0397     if (!obj_desc) {
0398         return_ACPI_STATUS(AE_NOT_EXIST);
0399     }
0400 
0401     /*
0402      * Get the length operand and save it
0403      * (at Top of stack)
0404      */
0405     operand_desc = walk_state->operands[walk_state->num_operands - 1];
0406 
0407     obj_desc->region.length = (u32) operand_desc->integer.value;
0408     acpi_ut_remove_reference(operand_desc);
0409 
0410     /* A zero-length operation region is unusable. Just warn */
0411 
0412     if (!obj_desc->region.length
0413         && (space_id < ACPI_NUM_PREDEFINED_REGIONS)) {
0414         ACPI_WARNING((AE_INFO,
0415                   "Operation Region [%4.4s] has zero length (SpaceId %X)",
0416                   node->name.ascii, space_id));
0417     }
0418 
0419     /*
0420      * Get the address and save it
0421      * (at top of stack - 1)
0422      */
0423     operand_desc = walk_state->operands[walk_state->num_operands - 2];
0424 
0425     obj_desc->region.address = (acpi_physical_address)
0426         operand_desc->integer.value;
0427     acpi_ut_remove_reference(operand_desc);
0428 
0429     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
0430               obj_desc,
0431               ACPI_FORMAT_UINT64(obj_desc->region.address),
0432               obj_desc->region.length));
0433 
0434     status = acpi_ut_add_address_range(obj_desc->region.space_id,
0435                        obj_desc->region.address,
0436                        obj_desc->region.length, node);
0437 
0438     /* Now the address and length are valid for this opregion */
0439 
0440     obj_desc->region.flags |= AOPOBJ_DATA_VALID;
0441     return_ACPI_STATUS(status);
0442 }
0443 
0444 /*******************************************************************************
0445  *
0446  * FUNCTION:    acpi_ds_eval_table_region_operands
0447  *
0448  * PARAMETERS:  walk_state      - Current walk
0449  *              op              - A valid region Op object
0450  *
0451  * RETURN:      Status
0452  *
0453  * DESCRIPTION: Get region address and length.
0454  *              Called from acpi_ds_exec_end_op during data_table_region parse
0455  *              tree walk.
0456  *
0457  ******************************************************************************/
0458 
0459 acpi_status
0460 acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
0461                    union acpi_parse_object *op)
0462 {
0463     acpi_status status;
0464     union acpi_operand_object *obj_desc;
0465     union acpi_operand_object **operand;
0466     struct acpi_namespace_node *node;
0467     union acpi_parse_object *next_op;
0468     struct acpi_table_header *table;
0469     u32 table_index;
0470 
0471     ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
0472 
0473     /*
0474      * This is where we evaluate the Signature string, oem_id string,
0475      * and oem_table_id string of the Data Table Region declaration
0476      */
0477     node = op->common.node;
0478 
0479     /* next_op points to Signature string op */
0480 
0481     next_op = op->common.value.arg;
0482 
0483     /*
0484      * Evaluate/create the Signature string, oem_id string,
0485      * and oem_table_id string operands
0486      */
0487     status = acpi_ds_create_operands(walk_state, next_op);
0488     if (ACPI_FAILURE(status)) {
0489         return_ACPI_STATUS(status);
0490     }
0491 
0492     operand = &walk_state->operands[0];
0493 
0494     /*
0495      * Resolve the Signature string, oem_id string,
0496      * and oem_table_id string operands
0497      */
0498     status =
0499         acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS,
0500                      walk_state);
0501     if (ACPI_FAILURE(status)) {
0502         goto cleanup;
0503     }
0504 
0505     /* Find the ACPI table */
0506 
0507     status = acpi_tb_find_table(operand[0]->string.pointer,
0508                     operand[1]->string.pointer,
0509                     operand[2]->string.pointer, &table_index);
0510     if (ACPI_FAILURE(status)) {
0511         if (status == AE_NOT_FOUND) {
0512             ACPI_ERROR((AE_INFO,
0513                     "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
0514                     operand[0]->string.pointer,
0515                     operand[1]->string.pointer,
0516                     operand[2]->string.pointer));
0517         }
0518         goto cleanup;
0519     }
0520 
0521     status = acpi_get_table_by_index(table_index, &table);
0522     if (ACPI_FAILURE(status)) {
0523         goto cleanup;
0524     }
0525 
0526     obj_desc = acpi_ns_get_attached_object(node);
0527     if (!obj_desc) {
0528         status = AE_NOT_EXIST;
0529         goto cleanup;
0530     }
0531 
0532     obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table);
0533     obj_desc->region.length = table->length;
0534     obj_desc->region.pointer = table;
0535 
0536     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
0537               obj_desc,
0538               ACPI_FORMAT_UINT64(obj_desc->region.address),
0539               obj_desc->region.length));
0540 
0541     /* Now the address and length are valid for this opregion */
0542 
0543     obj_desc->region.flags |= AOPOBJ_DATA_VALID;
0544 
0545 cleanup:
0546     acpi_ut_remove_reference(operand[0]);
0547     acpi_ut_remove_reference(operand[1]);
0548     acpi_ut_remove_reference(operand[2]);
0549 
0550     return_ACPI_STATUS(status);
0551 }
0552 
0553 /*******************************************************************************
0554  *
0555  * FUNCTION:    acpi_ds_eval_data_object_operands
0556  *
0557  * PARAMETERS:  walk_state      - Current walk
0558  *              op              - A valid data_object Op object
0559  *              obj_desc        - data_object
0560  *
0561  * RETURN:      Status
0562  *
0563  * DESCRIPTION: Get the operands and complete the following data object types:
0564  *              Buffer, Package.
0565  *
0566  ******************************************************************************/
0567 
0568 acpi_status
0569 acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
0570                   union acpi_parse_object *op,
0571                   union acpi_operand_object *obj_desc)
0572 {
0573     acpi_status status;
0574     union acpi_operand_object *arg_desc;
0575     u32 length;
0576 
0577     ACPI_FUNCTION_TRACE(ds_eval_data_object_operands);
0578 
0579     /* The first operand (for all of these data objects) is the length */
0580 
0581     /*
0582      * Set proper index into operand stack for acpi_ds_obj_stack_push
0583      * invoked inside acpi_ds_create_operand.
0584      */
0585     walk_state->operand_index = walk_state->num_operands;
0586 
0587     /* Ignore if child is not valid */
0588 
0589     if (!op->common.value.arg) {
0590         ACPI_ERROR((AE_INFO,
0591                 "Missing child while evaluating opcode %4.4X, Op %p",
0592                 op->common.aml_opcode, op));
0593         return_ACPI_STATUS(AE_OK);
0594     }
0595 
0596     status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
0597     if (ACPI_FAILURE(status)) {
0598         return_ACPI_STATUS(status);
0599     }
0600 
0601     status = acpi_ex_resolve_operands(walk_state->opcode,
0602                       &(walk_state->
0603                         operands[walk_state->num_operands -
0604                              1]), walk_state);
0605     if (ACPI_FAILURE(status)) {
0606         return_ACPI_STATUS(status);
0607     }
0608 
0609     /* Extract length operand */
0610 
0611     arg_desc = walk_state->operands[walk_state->num_operands - 1];
0612     length = (u32) arg_desc->integer.value;
0613 
0614     /* Cleanup for length operand */
0615 
0616     status = acpi_ds_obj_stack_pop(1, walk_state);
0617     if (ACPI_FAILURE(status)) {
0618         return_ACPI_STATUS(status);
0619     }
0620 
0621     acpi_ut_remove_reference(arg_desc);
0622 
0623     /*
0624      * Create the actual data object
0625      */
0626     switch (op->common.aml_opcode) {
0627     case AML_BUFFER_OP:
0628 
0629         status =
0630             acpi_ds_build_internal_buffer_obj(walk_state, op, length,
0631                               &obj_desc);
0632         break;
0633 
0634     case AML_PACKAGE_OP:
0635     case AML_VARIABLE_PACKAGE_OP:
0636 
0637         status =
0638             acpi_ds_build_internal_package_obj(walk_state, op, length,
0639                                &obj_desc);
0640         break;
0641 
0642     default:
0643 
0644         return_ACPI_STATUS(AE_AML_BAD_OPCODE);
0645     }
0646 
0647     if (ACPI_SUCCESS(status)) {
0648         /*
0649          * Return the object in the walk_state, unless the parent is a package -
0650          * in this case, the return object will be stored in the parse tree
0651          * for the package.
0652          */
0653         if ((!op->common.parent) ||
0654             ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
0655              (op->common.parent->common.aml_opcode !=
0656               AML_VARIABLE_PACKAGE_OP)
0657              && (op->common.parent->common.aml_opcode !=
0658              AML_NAME_OP))) {
0659             walk_state->result_obj = obj_desc;
0660         }
0661     }
0662 
0663     return_ACPI_STATUS(status);
0664 }
0665 
0666 /*******************************************************************************
0667  *
0668  * FUNCTION:    acpi_ds_eval_bank_field_operands
0669  *
0670  * PARAMETERS:  walk_state      - Current walk
0671  *              op              - A valid bank_field Op object
0672  *
0673  * RETURN:      Status
0674  *
0675  * DESCRIPTION: Get bank_field bank_value
0676  *              Called from acpi_ds_exec_end_op during bank_field parse tree walk
0677  *
0678  ******************************************************************************/
0679 
0680 acpi_status
0681 acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
0682                  union acpi_parse_object *op)
0683 {
0684     acpi_status status;
0685     union acpi_operand_object *obj_desc;
0686     union acpi_operand_object *operand_desc;
0687     struct acpi_namespace_node *node;
0688     union acpi_parse_object *next_op;
0689     union acpi_parse_object *arg;
0690 
0691     ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op);
0692 
0693     /*
0694      * This is where we evaluate the bank_value field of the
0695      * bank_field declaration
0696      */
0697 
0698     /* next_op points to the op that holds the Region */
0699 
0700     next_op = op->common.value.arg;
0701 
0702     /* next_op points to the op that holds the Bank Register */
0703 
0704     next_op = next_op->common.next;
0705 
0706     /* next_op points to the op that holds the Bank Value */
0707 
0708     next_op = next_op->common.next;
0709 
0710     /*
0711      * Set proper index into operand stack for acpi_ds_obj_stack_push
0712      * invoked inside acpi_ds_create_operand.
0713      *
0714      * We use walk_state->Operands[0] to store the evaluated bank_value
0715      */
0716     walk_state->operand_index = 0;
0717 
0718     status = acpi_ds_create_operand(walk_state, next_op, 0);
0719     if (ACPI_FAILURE(status)) {
0720         return_ACPI_STATUS(status);
0721     }
0722 
0723     status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state);
0724     if (ACPI_FAILURE(status)) {
0725         return_ACPI_STATUS(status);
0726     }
0727 
0728     ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
0729                acpi_ps_get_opcode_name(op->common.aml_opcode), 1);
0730     /*
0731      * Get the bank_value operand and save it
0732      * (at Top of stack)
0733      */
0734     operand_desc = walk_state->operands[0];
0735 
0736     /* Arg points to the start Bank Field */
0737 
0738     arg = acpi_ps_get_arg(op, 4);
0739     while (arg) {
0740 
0741         /* Ignore OFFSET and ACCESSAS terms here */
0742 
0743         if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
0744             node = arg->common.node;
0745 
0746             obj_desc = acpi_ns_get_attached_object(node);
0747             if (!obj_desc) {
0748                 return_ACPI_STATUS(AE_NOT_EXIST);
0749             }
0750 
0751             obj_desc->bank_field.value =
0752                 (u32) operand_desc->integer.value;
0753         }
0754 
0755         /* Move to next field in the list */
0756 
0757         arg = arg->common.next;
0758     }
0759 
0760     acpi_ut_remove_reference(operand_desc);
0761     return_ACPI_STATUS(status);
0762 }