Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: dsfield - Dispatcher field routines
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "amlcode.h"
0013 #include "acdispat.h"
0014 #include "acinterp.h"
0015 #include "acnamesp.h"
0016 #include "acparser.h"
0017 
0018 #ifdef ACPI_EXEC_APP
0019 #include "aecommon.h"
0020 #endif
0021 
0022 #define _COMPONENT          ACPI_DISPATCHER
0023 ACPI_MODULE_NAME("dsfield")
0024 
0025 /* Local prototypes */
0026 #ifdef ACPI_ASL_COMPILER
0027 #include "acdisasm.h"
0028 static acpi_status
0029 acpi_ds_create_external_region(acpi_status lookup_status,
0030                    union acpi_parse_object *op,
0031                    char *path,
0032                    struct acpi_walk_state *walk_state,
0033                    struct acpi_namespace_node **node);
0034 #endif
0035 
0036 static acpi_status
0037 acpi_ds_get_field_names(struct acpi_create_field_info *info,
0038             struct acpi_walk_state *walk_state,
0039             union acpi_parse_object *arg);
0040 
0041 #ifdef ACPI_ASL_COMPILER
0042 /*******************************************************************************
0043  *
0044  * FUNCTION:    acpi_ds_create_external_region (iASL Disassembler only)
0045  *
0046  * PARAMETERS:  lookup_status   - Status from ns_lookup operation
0047  *              op              - Op containing the Field definition and args
0048  *              path            - Pathname of the region
0049  *  `           walk_state      - Current method state
0050  *              node            - Where the new region node is returned
0051  *
0052  * RETURN:      Status
0053  *
0054  * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
0055  *              region node/object.
0056  *
0057  ******************************************************************************/
0058 
0059 static acpi_status
0060 acpi_ds_create_external_region(acpi_status lookup_status,
0061                    union acpi_parse_object *op,
0062                    char *path,
0063                    struct acpi_walk_state *walk_state,
0064                    struct acpi_namespace_node **node)
0065 {
0066     acpi_status status;
0067     union acpi_operand_object *obj_desc;
0068 
0069     if (lookup_status != AE_NOT_FOUND) {
0070         return (lookup_status);
0071     }
0072 
0073     /*
0074      * Table disassembly:
0075      * operation_region not found. Generate an External for it, and
0076      * insert the name into the namespace.
0077      */
0078     acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
0079 
0080     status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
0081                 ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
0082                 walk_state, node);
0083     if (ACPI_FAILURE(status)) {
0084         return (status);
0085     }
0086 
0087     /* Must create and install a region object for the new node */
0088 
0089     obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
0090     if (!obj_desc) {
0091         return (AE_NO_MEMORY);
0092     }
0093 
0094     obj_desc->region.node = *node;
0095     status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
0096     return (status);
0097 }
0098 #endif
0099 
0100 /*******************************************************************************
0101  *
0102  * FUNCTION:    acpi_ds_create_buffer_field
0103  *
0104  * PARAMETERS:  op                  - Current parse op (create_XXField)
0105  *              walk_state          - Current state
0106  *
0107  * RETURN:      Status
0108  *
0109  * DESCRIPTION: Execute the create_field operators:
0110  *              create_bit_field_op,
0111  *              create_byte_field_op,
0112  *              create_word_field_op,
0113  *              create_dword_field_op,
0114  *              create_qword_field_op,
0115  *              create_field_op     (all of which define a field in a buffer)
0116  *
0117  ******************************************************************************/
0118 
0119 acpi_status
0120 acpi_ds_create_buffer_field(union acpi_parse_object *op,
0121                 struct acpi_walk_state *walk_state)
0122 {
0123     union acpi_parse_object *arg;
0124     struct acpi_namespace_node *node;
0125     acpi_status status;
0126     union acpi_operand_object *obj_desc;
0127     union acpi_operand_object *second_desc = NULL;
0128     u32 flags;
0129 
0130     ACPI_FUNCTION_TRACE(ds_create_buffer_field);
0131 
0132     /*
0133      * Get the name_string argument (name of the new buffer_field)
0134      */
0135     if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
0136 
0137         /* For create_field, name is the 4th argument */
0138 
0139         arg = acpi_ps_get_arg(op, 3);
0140     } else {
0141         /* For all other create_XXXField operators, name is the 3rd argument */
0142 
0143         arg = acpi_ps_get_arg(op, 2);
0144     }
0145 
0146     if (!arg) {
0147         return_ACPI_STATUS(AE_AML_NO_OPERAND);
0148     }
0149 
0150     if (walk_state->deferred_node) {
0151         node = walk_state->deferred_node;
0152     } else {
0153         /* Execute flag should always be set when this function is entered */
0154 
0155         if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
0156             ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
0157             return_ACPI_STATUS(AE_AML_INTERNAL);
0158         }
0159 
0160         /* Creating new namespace node, should not already exist */
0161 
0162         flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
0163             ACPI_NS_ERROR_IF_FOUND;
0164 
0165         /*
0166          * Mark node temporary if we are executing a normal control
0167          * method. (Don't mark if this is a module-level code method)
0168          */
0169         if (walk_state->method_node &&
0170             !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
0171             flags |= ACPI_NS_TEMPORARY;
0172         }
0173 
0174         /* Enter the name_string into the namespace */
0175 
0176         status = acpi_ns_lookup(walk_state->scope_info,
0177                     arg->common.value.string, ACPI_TYPE_ANY,
0178                     ACPI_IMODE_LOAD_PASS1, flags,
0179                     walk_state, &node);
0180         if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE)
0181             && status == AE_ALREADY_EXISTS) {
0182             status = AE_OK;
0183         } else if (ACPI_FAILURE(status)) {
0184             ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0185                          arg->common.value.string, status);
0186             return_ACPI_STATUS(status);
0187         }
0188     }
0189 
0190     /*
0191      * We could put the returned object (Node) on the object stack for later,
0192      * but for now, we will put it in the "op" object that the parser uses,
0193      * so we can get it again at the end of this scope.
0194      */
0195     op->common.node = node;
0196 
0197     /*
0198      * If there is no object attached to the node, this node was just created
0199      * and we need to create the field object. Otherwise, this was a lookup
0200      * of an existing node and we don't want to create the field object again.
0201      */
0202     obj_desc = acpi_ns_get_attached_object(node);
0203     if (obj_desc) {
0204         return_ACPI_STATUS(AE_OK);
0205     }
0206 
0207     /*
0208      * The Field definition is not fully parsed at this time.
0209      * (We must save the address of the AML for the buffer and index operands)
0210      */
0211 
0212     /* Create the buffer field object */
0213 
0214     obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
0215     if (!obj_desc) {
0216         status = AE_NO_MEMORY;
0217         goto cleanup;
0218     }
0219 
0220     /*
0221      * Remember location in AML stream of the field unit opcode and operands
0222      * -- since the buffer and index operands must be evaluated.
0223      */
0224     second_desc = obj_desc->common.next_object;
0225     second_desc->extra.aml_start = op->named.data;
0226     second_desc->extra.aml_length = op->named.length;
0227     obj_desc->buffer_field.node = node;
0228 
0229     /* Attach constructed field descriptors to parent node */
0230 
0231     status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
0232     if (ACPI_FAILURE(status)) {
0233         goto cleanup;
0234     }
0235 
0236 cleanup:
0237 
0238     /* Remove local reference to the object */
0239 
0240     acpi_ut_remove_reference(obj_desc);
0241     return_ACPI_STATUS(status);
0242 }
0243 
0244 /*******************************************************************************
0245  *
0246  * FUNCTION:    acpi_ds_get_field_names
0247  *
0248  * PARAMETERS:  info            - create_field info structure
0249  *              walk_state      - Current method state
0250  *              arg             - First parser arg for the field name list
0251  *
0252  * RETURN:      Status
0253  *
0254  * DESCRIPTION: Process all named fields in a field declaration. Names are
0255  *              entered into the namespace.
0256  *
0257  ******************************************************************************/
0258 
0259 static acpi_status
0260 acpi_ds_get_field_names(struct acpi_create_field_info *info,
0261             struct acpi_walk_state *walk_state,
0262             union acpi_parse_object *arg)
0263 {
0264     acpi_status status;
0265     u64 position;
0266     union acpi_parse_object *child;
0267 
0268 #ifdef ACPI_EXEC_APP
0269     union acpi_operand_object *result_desc;
0270     union acpi_operand_object *obj_desc;
0271     char *name_path;
0272 #endif
0273 
0274     ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
0275 
0276     /* First field starts at bit zero */
0277 
0278     info->field_bit_position = 0;
0279 
0280     /* Process all elements in the field list (of parse nodes) */
0281 
0282     while (arg) {
0283         /*
0284          * Four types of field elements are handled:
0285          * 1) name - Enters a new named field into the namespace
0286          * 2) offset - specifies a bit offset
0287          * 3) access_as - changes the access mode/attributes
0288          * 4) connection - Associate a resource template with the field
0289          */
0290         switch (arg->common.aml_opcode) {
0291         case AML_INT_RESERVEDFIELD_OP:
0292 
0293             position = (u64)info->field_bit_position +
0294                 (u64)arg->common.value.size;
0295 
0296             if (position > ACPI_UINT32_MAX) {
0297                 ACPI_ERROR((AE_INFO,
0298                         "Bit offset within field too large (> 0xFFFFFFFF)"));
0299                 return_ACPI_STATUS(AE_SUPPORT);
0300             }
0301 
0302             info->field_bit_position = (u32) position;
0303             break;
0304 
0305         case AML_INT_ACCESSFIELD_OP:
0306         case AML_INT_EXTACCESSFIELD_OP:
0307             /*
0308              * Get new access_type, access_attribute, and access_length fields
0309              * -- to be used for all field units that follow, until the
0310              * end-of-field or another access_as keyword is encountered.
0311              * NOTE. These three bytes are encoded in the integer value
0312              * of the parseop for convenience.
0313              *
0314              * In field_flags, preserve the flag bits other than the
0315              * ACCESS_TYPE bits.
0316              */
0317 
0318             /* access_type (byte_acc, word_acc, etc.) */
0319 
0320             info->field_flags = (u8)
0321                 ((info->
0322                   field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
0323                  ((u8)((u32)(arg->common.value.integer & 0x07))));
0324 
0325             /* access_attribute (attrib_quick, attrib_byte, etc.) */
0326 
0327             info->attribute = (u8)
0328                 ((arg->common.value.integer >> 8) & 0xFF);
0329 
0330             /* access_length (for serial/buffer protocols) */
0331 
0332             info->access_length = (u8)
0333                 ((arg->common.value.integer >> 16) & 0xFF);
0334             break;
0335 
0336         case AML_INT_CONNECTION_OP:
0337             /*
0338              * Clear any previous connection. New connection is used for all
0339              * fields that follow, similar to access_as
0340              */
0341             info->resource_buffer = NULL;
0342             info->connection_node = NULL;
0343             info->pin_number_index = 0;
0344 
0345             /*
0346              * A Connection() is either an actual resource descriptor (buffer)
0347              * or a named reference to a resource template
0348              */
0349             child = arg->common.value.arg;
0350             if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
0351                 info->resource_buffer = child->named.data;
0352                 info->resource_length =
0353                     (u16)child->named.value.integer;
0354             } else {
0355                 /* Lookup the Connection() namepath, it should already exist */
0356 
0357                 status = acpi_ns_lookup(walk_state->scope_info,
0358                             child->common.value.
0359                             name, ACPI_TYPE_ANY,
0360                             ACPI_IMODE_EXECUTE,
0361                             ACPI_NS_DONT_OPEN_SCOPE,
0362                             walk_state,
0363                             &info->connection_node);
0364                 if (ACPI_FAILURE(status)) {
0365                     ACPI_ERROR_NAMESPACE(walk_state->
0366                                  scope_info,
0367                                  child->common.
0368                                  value.name,
0369                                  status);
0370                     return_ACPI_STATUS(status);
0371                 }
0372             }
0373             break;
0374 
0375         case AML_INT_NAMEDFIELD_OP:
0376 
0377             /* Lookup the name, it should already exist */
0378 
0379             status = acpi_ns_lookup(walk_state->scope_info,
0380                         (char *)&arg->named.name,
0381                         info->field_type,
0382                         ACPI_IMODE_EXECUTE,
0383                         ACPI_NS_DONT_OPEN_SCOPE,
0384                         walk_state, &info->field_node);
0385             if (ACPI_FAILURE(status)) {
0386                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0387                              (char *)&arg->named.name,
0388                              status);
0389                 return_ACPI_STATUS(status);
0390             } else {
0391                 arg->common.node = info->field_node;
0392                 info->field_bit_length = arg->common.value.size;
0393 
0394                 /*
0395                  * If there is no object attached to the node, this node was
0396                  * just created and we need to create the field object.
0397                  * Otherwise, this was a lookup of an existing node and we
0398                  * don't want to create the field object again.
0399                  */
0400                 if (!acpi_ns_get_attached_object
0401                     (info->field_node)) {
0402                     status = acpi_ex_prep_field_value(info);
0403                     if (ACPI_FAILURE(status)) {
0404                         return_ACPI_STATUS(status);
0405                     }
0406 #ifdef ACPI_EXEC_APP
0407                     name_path =
0408                         acpi_ns_get_external_pathname(info->
0409                                       field_node);
0410                     if (ACPI_SUCCESS
0411                         (ae_lookup_init_file_entry
0412                          (name_path, &obj_desc))) {
0413                         acpi_ex_write_data_to_field
0414                             (obj_desc,
0415                              acpi_ns_get_attached_object
0416                              (info->field_node),
0417                              &result_desc);
0418                         acpi_ut_remove_reference
0419                             (obj_desc);
0420                     }
0421                     ACPI_FREE(name_path);
0422 #endif
0423                 }
0424             }
0425 
0426             /* Keep track of bit position for the next field */
0427 
0428             position = (u64)info->field_bit_position +
0429                 (u64)arg->common.value.size;
0430 
0431             if (position > ACPI_UINT32_MAX) {
0432                 ACPI_ERROR((AE_INFO,
0433                         "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
0434                         ACPI_CAST_PTR(char,
0435                               &info->field_node->
0436                               name)));
0437                 return_ACPI_STATUS(AE_SUPPORT);
0438             }
0439 
0440             info->field_bit_position += info->field_bit_length;
0441             info->pin_number_index++;   /* Index relative to previous Connection() */
0442             break;
0443 
0444         default:
0445 
0446             ACPI_ERROR((AE_INFO,
0447                     "Invalid opcode in field list: 0x%X",
0448                     arg->common.aml_opcode));
0449             return_ACPI_STATUS(AE_AML_BAD_OPCODE);
0450         }
0451 
0452         arg = arg->common.next;
0453     }
0454 
0455     return_ACPI_STATUS(AE_OK);
0456 }
0457 
0458 /*******************************************************************************
0459  *
0460  * FUNCTION:    acpi_ds_create_field
0461  *
0462  * PARAMETERS:  op              - Op containing the Field definition and args
0463  *              region_node     - Object for the containing Operation Region
0464  *  `           walk_state      - Current method state
0465  *
0466  * RETURN:      Status
0467  *
0468  * DESCRIPTION: Create a new field in the specified operation region
0469  *
0470  ******************************************************************************/
0471 
0472 acpi_status
0473 acpi_ds_create_field(union acpi_parse_object *op,
0474              struct acpi_namespace_node *region_node,
0475              struct acpi_walk_state *walk_state)
0476 {
0477     acpi_status status;
0478     union acpi_parse_object *arg;
0479     struct acpi_create_field_info info;
0480 
0481     ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
0482 
0483     /* First arg is the name of the parent op_region (must already exist) */
0484 
0485     arg = op->common.value.arg;
0486 
0487     if (!region_node) {
0488         status =
0489             acpi_ns_lookup(walk_state->scope_info,
0490                    arg->common.value.name, ACPI_TYPE_REGION,
0491                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
0492                    walk_state, &region_node);
0493 #ifdef ACPI_ASL_COMPILER
0494         status = acpi_ds_create_external_region(status, arg,
0495                             arg->common.value.name,
0496                             walk_state,
0497                             &region_node);
0498 #endif
0499         if (ACPI_FAILURE(status)) {
0500             ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0501                          arg->common.value.name, status);
0502             return_ACPI_STATUS(status);
0503         }
0504     }
0505 
0506     memset(&info, 0, sizeof(struct acpi_create_field_info));
0507 
0508     /* Second arg is the field flags */
0509 
0510     arg = arg->common.next;
0511     info.field_flags = (u8) arg->common.value.integer;
0512     info.attribute = 0;
0513 
0514     /* Each remaining arg is a Named Field */
0515 
0516     info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
0517     info.region_node = region_node;
0518 
0519     status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
0520     if (ACPI_FAILURE(status)) {
0521         return_ACPI_STATUS(status);
0522     }
0523 
0524     if (info.region_node->object->region.space_id ==
0525         ACPI_ADR_SPACE_PLATFORM_COMM) {
0526         region_node->object->field.internal_pcc_buffer =
0527             ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
0528                      length);
0529         if (!region_node->object->field.internal_pcc_buffer) {
0530             return_ACPI_STATUS(AE_NO_MEMORY);
0531         }
0532     }
0533 
0534     return_ACPI_STATUS(status);
0535 }
0536 
0537 /*******************************************************************************
0538  *
0539  * FUNCTION:    acpi_ds_init_field_objects
0540  *
0541  * PARAMETERS:  op              - Op containing the Field definition and args
0542  *  `           walk_state      - Current method state
0543  *
0544  * RETURN:      Status
0545  *
0546  * DESCRIPTION: For each "Field Unit" name in the argument list that is
0547  *              part of the field declaration, enter the name into the
0548  *              namespace.
0549  *
0550  ******************************************************************************/
0551 
0552 acpi_status
0553 acpi_ds_init_field_objects(union acpi_parse_object *op,
0554                struct acpi_walk_state *walk_state)
0555 {
0556     acpi_status status;
0557     union acpi_parse_object *arg = NULL;
0558     struct acpi_namespace_node *node;
0559     u8 type = 0;
0560     u32 flags;
0561 
0562     ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
0563 
0564     /* Execute flag should always be set when this function is entered */
0565 
0566     if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
0567         if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
0568 
0569             /* bank_field Op is deferred, just return OK */
0570 
0571             return_ACPI_STATUS(AE_OK);
0572         }
0573 
0574         ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
0575         return_ACPI_STATUS(AE_AML_INTERNAL);
0576     }
0577 
0578     /*
0579      * Get the field_list argument for this opcode. This is the start of the
0580      * list of field elements.
0581      */
0582     switch (walk_state->opcode) {
0583     case AML_FIELD_OP:
0584 
0585         arg = acpi_ps_get_arg(op, 2);
0586         type = ACPI_TYPE_LOCAL_REGION_FIELD;
0587         break;
0588 
0589     case AML_BANK_FIELD_OP:
0590 
0591         arg = acpi_ps_get_arg(op, 4);
0592         type = ACPI_TYPE_LOCAL_BANK_FIELD;
0593         break;
0594 
0595     case AML_INDEX_FIELD_OP:
0596 
0597         arg = acpi_ps_get_arg(op, 3);
0598         type = ACPI_TYPE_LOCAL_INDEX_FIELD;
0599         break;
0600 
0601     default:
0602 
0603         return_ACPI_STATUS(AE_BAD_PARAMETER);
0604     }
0605 
0606     /* Creating new namespace node(s), should not already exist */
0607 
0608     flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
0609         ACPI_NS_ERROR_IF_FOUND;
0610 
0611     /*
0612      * Mark node(s) temporary if we are executing a normal control
0613      * method. (Don't mark if this is a module-level code method)
0614      */
0615     if (walk_state->method_node &&
0616         !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
0617         flags |= ACPI_NS_TEMPORARY;
0618     }
0619 #ifdef ACPI_EXEC_APP
0620     flags |= ACPI_NS_OVERRIDE_IF_FOUND;
0621 #endif
0622     /*
0623      * Walk the list of entries in the field_list
0624      * Note: field_list can be of zero length. In this case, Arg will be NULL.
0625      */
0626     while (arg) {
0627         /*
0628          * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
0629          * in the field names in order to enter them into the namespace.
0630          */
0631         if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
0632             status = acpi_ns_lookup(walk_state->scope_info,
0633                         (char *)&arg->named.name, type,
0634                         ACPI_IMODE_LOAD_PASS1, flags,
0635                         walk_state, &node);
0636             if (ACPI_FAILURE(status)) {
0637                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0638                              (char *)&arg->named.name,
0639                              status);
0640                 if (status != AE_ALREADY_EXISTS) {
0641                     return_ACPI_STATUS(status);
0642                 }
0643 
0644                 /* Name already exists, just ignore this error */
0645             }
0646 
0647             arg->common.node = node;
0648         }
0649 
0650         /* Get the next field element in the list */
0651 
0652         arg = arg->common.next;
0653     }
0654 
0655     return_ACPI_STATUS(AE_OK);
0656 }
0657 
0658 /*******************************************************************************
0659  *
0660  * FUNCTION:    acpi_ds_create_bank_field
0661  *
0662  * PARAMETERS:  op              - Op containing the Field definition and args
0663  *              region_node     - Object for the containing Operation Region
0664  *              walk_state      - Current method state
0665  *
0666  * RETURN:      Status
0667  *
0668  * DESCRIPTION: Create a new bank field in the specified operation region
0669  *
0670  ******************************************************************************/
0671 
0672 acpi_status
0673 acpi_ds_create_bank_field(union acpi_parse_object *op,
0674               struct acpi_namespace_node *region_node,
0675               struct acpi_walk_state *walk_state)
0676 {
0677     acpi_status status;
0678     union acpi_parse_object *arg;
0679     struct acpi_create_field_info info;
0680 
0681     ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
0682 
0683     /* First arg is the name of the parent op_region (must already exist) */
0684 
0685     arg = op->common.value.arg;
0686     if (!region_node) {
0687         status =
0688             acpi_ns_lookup(walk_state->scope_info,
0689                    arg->common.value.name, ACPI_TYPE_REGION,
0690                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
0691                    walk_state, &region_node);
0692 #ifdef ACPI_ASL_COMPILER
0693         status = acpi_ds_create_external_region(status, arg,
0694                             arg->common.value.name,
0695                             walk_state,
0696                             &region_node);
0697 #endif
0698         if (ACPI_FAILURE(status)) {
0699             ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0700                          arg->common.value.name, status);
0701             return_ACPI_STATUS(status);
0702         }
0703     }
0704 
0705     /* Second arg is the Bank Register (Field) (must already exist) */
0706 
0707     arg = arg->common.next;
0708     status =
0709         acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
0710                ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
0711                ACPI_NS_SEARCH_PARENT, walk_state,
0712                &info.register_node);
0713     if (ACPI_FAILURE(status)) {
0714         ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0715                      arg->common.value.string, status);
0716         return_ACPI_STATUS(status);
0717     }
0718 
0719     /*
0720      * Third arg is the bank_value
0721      * This arg is a term_arg, not a constant
0722      * It will be evaluated later, by acpi_ds_eval_bank_field_operands
0723      */
0724     arg = arg->common.next;
0725 
0726     /* Fourth arg is the field flags */
0727 
0728     arg = arg->common.next;
0729     info.field_flags = (u8) arg->common.value.integer;
0730 
0731     /* Each remaining arg is a Named Field */
0732 
0733     info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
0734     info.region_node = region_node;
0735 
0736     /*
0737      * Use Info.data_register_node to store bank_field Op
0738      * It's safe because data_register_node will never be used when create
0739      * bank field \we store aml_start and aml_length in the bank_field Op for
0740      * late evaluation. Used in acpi_ex_prep_field_value(Info)
0741      *
0742      * TBD: Or, should we add a field in struct acpi_create_field_info, like
0743      * "void *ParentOp"?
0744      */
0745     info.data_register_node = (struct acpi_namespace_node *)op;
0746 
0747     status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
0748     return_ACPI_STATUS(status);
0749 }
0750 
0751 /*******************************************************************************
0752  *
0753  * FUNCTION:    acpi_ds_create_index_field
0754  *
0755  * PARAMETERS:  op              - Op containing the Field definition and args
0756  *              region_node     - Object for the containing Operation Region
0757  *  `           walk_state      - Current method state
0758  *
0759  * RETURN:      Status
0760  *
0761  * DESCRIPTION: Create a new index field in the specified operation region
0762  *
0763  ******************************************************************************/
0764 
0765 acpi_status
0766 acpi_ds_create_index_field(union acpi_parse_object *op,
0767                struct acpi_namespace_node *region_node,
0768                struct acpi_walk_state *walk_state)
0769 {
0770     acpi_status status;
0771     union acpi_parse_object *arg;
0772     struct acpi_create_field_info info;
0773 
0774     ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
0775 
0776     /* First arg is the name of the Index register (must already exist) */
0777 
0778     arg = op->common.value.arg;
0779     status =
0780         acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
0781                ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
0782                ACPI_NS_SEARCH_PARENT, walk_state,
0783                &info.register_node);
0784     if (ACPI_FAILURE(status)) {
0785         ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0786                      arg->common.value.string, status);
0787         return_ACPI_STATUS(status);
0788     }
0789 
0790     /* Second arg is the data register (must already exist) */
0791 
0792     arg = arg->common.next;
0793     status =
0794         acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
0795                ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
0796                ACPI_NS_SEARCH_PARENT, walk_state,
0797                &info.data_register_node);
0798     if (ACPI_FAILURE(status)) {
0799         ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0800                      arg->common.value.string, status);
0801         return_ACPI_STATUS(status);
0802     }
0803 
0804     /* Next arg is the field flags */
0805 
0806     arg = arg->common.next;
0807     info.field_flags = (u8) arg->common.value.integer;
0808 
0809     /* Each remaining arg is a Named Field */
0810 
0811     info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
0812     info.region_node = region_node;
0813 
0814     status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
0815     return_ACPI_STATUS(status);
0816 }