cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dsfield.c (23354B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: dsfield - Dispatcher field routines
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "amlcode.h"
     13#include "acdispat.h"
     14#include "acinterp.h"
     15#include "acnamesp.h"
     16#include "acparser.h"
     17
     18#ifdef ACPI_EXEC_APP
     19#include "aecommon.h"
     20#endif
     21
     22#define _COMPONENT          ACPI_DISPATCHER
     23ACPI_MODULE_NAME("dsfield")
     24
     25/* Local prototypes */
     26#ifdef ACPI_ASL_COMPILER
     27#include "acdisasm.h"
     28static acpi_status
     29acpi_ds_create_external_region(acpi_status lookup_status,
     30			       union acpi_parse_object *op,
     31			       char *path,
     32			       struct acpi_walk_state *walk_state,
     33			       struct acpi_namespace_node **node);
     34#endif
     35
     36static acpi_status
     37acpi_ds_get_field_names(struct acpi_create_field_info *info,
     38			struct acpi_walk_state *walk_state,
     39			union acpi_parse_object *arg);
     40
     41#ifdef ACPI_ASL_COMPILER
     42/*******************************************************************************
     43 *
     44 * FUNCTION:    acpi_ds_create_external_region (iASL Disassembler only)
     45 *
     46 * PARAMETERS:  lookup_status   - Status from ns_lookup operation
     47 *              op              - Op containing the Field definition and args
     48 *              path            - Pathname of the region
     49 *  `           walk_state      - Current method state
     50 *              node            - Where the new region node is returned
     51 *
     52 * RETURN:      Status
     53 *
     54 * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
     55 *              region node/object.
     56 *
     57 ******************************************************************************/
     58
     59static acpi_status
     60acpi_ds_create_external_region(acpi_status lookup_status,
     61			       union acpi_parse_object *op,
     62			       char *path,
     63			       struct acpi_walk_state *walk_state,
     64			       struct acpi_namespace_node **node)
     65{
     66	acpi_status status;
     67	union acpi_operand_object *obj_desc;
     68
     69	if (lookup_status != AE_NOT_FOUND) {
     70		return (lookup_status);
     71	}
     72
     73	/*
     74	 * Table disassembly:
     75	 * operation_region not found. Generate an External for it, and
     76	 * insert the name into the namespace.
     77	 */
     78	acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
     79
     80	status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
     81				ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
     82				walk_state, node);
     83	if (ACPI_FAILURE(status)) {
     84		return (status);
     85	}
     86
     87	/* Must create and install a region object for the new node */
     88
     89	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
     90	if (!obj_desc) {
     91		return (AE_NO_MEMORY);
     92	}
     93
     94	obj_desc->region.node = *node;
     95	status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
     96	return (status);
     97}
     98#endif
     99
    100/*******************************************************************************
    101 *
    102 * FUNCTION:    acpi_ds_create_buffer_field
    103 *
    104 * PARAMETERS:  op                  - Current parse op (create_XXField)
    105 *              walk_state          - Current state
    106 *
    107 * RETURN:      Status
    108 *
    109 * DESCRIPTION: Execute the create_field operators:
    110 *              create_bit_field_op,
    111 *              create_byte_field_op,
    112 *              create_word_field_op,
    113 *              create_dword_field_op,
    114 *              create_qword_field_op,
    115 *              create_field_op     (all of which define a field in a buffer)
    116 *
    117 ******************************************************************************/
    118
    119acpi_status
    120acpi_ds_create_buffer_field(union acpi_parse_object *op,
    121			    struct acpi_walk_state *walk_state)
    122{
    123	union acpi_parse_object *arg;
    124	struct acpi_namespace_node *node;
    125	acpi_status status;
    126	union acpi_operand_object *obj_desc;
    127	union acpi_operand_object *second_desc = NULL;
    128	u32 flags;
    129
    130	ACPI_FUNCTION_TRACE(ds_create_buffer_field);
    131
    132	/*
    133	 * Get the name_string argument (name of the new buffer_field)
    134	 */
    135	if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
    136
    137		/* For create_field, name is the 4th argument */
    138
    139		arg = acpi_ps_get_arg(op, 3);
    140	} else {
    141		/* For all other create_XXXField operators, name is the 3rd argument */
    142
    143		arg = acpi_ps_get_arg(op, 2);
    144	}
    145
    146	if (!arg) {
    147		return_ACPI_STATUS(AE_AML_NO_OPERAND);
    148	}
    149
    150	if (walk_state->deferred_node) {
    151		node = walk_state->deferred_node;
    152	} else {
    153		/* Execute flag should always be set when this function is entered */
    154
    155		if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
    156			ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
    157			return_ACPI_STATUS(AE_AML_INTERNAL);
    158		}
    159
    160		/* Creating new namespace node, should not already exist */
    161
    162		flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
    163		    ACPI_NS_ERROR_IF_FOUND;
    164
    165		/*
    166		 * Mark node temporary if we are executing a normal control
    167		 * method. (Don't mark if this is a module-level code method)
    168		 */
    169		if (walk_state->method_node &&
    170		    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
    171			flags |= ACPI_NS_TEMPORARY;
    172		}
    173
    174		/* Enter the name_string into the namespace */
    175
    176		status = acpi_ns_lookup(walk_state->scope_info,
    177					arg->common.value.string, ACPI_TYPE_ANY,
    178					ACPI_IMODE_LOAD_PASS1, flags,
    179					walk_state, &node);
    180		if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE)
    181		    && status == AE_ALREADY_EXISTS) {
    182			status = AE_OK;
    183		} else if (ACPI_FAILURE(status)) {
    184			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
    185					     arg->common.value.string, status);
    186			return_ACPI_STATUS(status);
    187		}
    188	}
    189
    190	/*
    191	 * We could put the returned object (Node) on the object stack for later,
    192	 * but for now, we will put it in the "op" object that the parser uses,
    193	 * so we can get it again at the end of this scope.
    194	 */
    195	op->common.node = node;
    196
    197	/*
    198	 * If there is no object attached to the node, this node was just created
    199	 * and we need to create the field object. Otherwise, this was a lookup
    200	 * of an existing node and we don't want to create the field object again.
    201	 */
    202	obj_desc = acpi_ns_get_attached_object(node);
    203	if (obj_desc) {
    204		return_ACPI_STATUS(AE_OK);
    205	}
    206
    207	/*
    208	 * The Field definition is not fully parsed at this time.
    209	 * (We must save the address of the AML for the buffer and index operands)
    210	 */
    211
    212	/* Create the buffer field object */
    213
    214	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
    215	if (!obj_desc) {
    216		status = AE_NO_MEMORY;
    217		goto cleanup;
    218	}
    219
    220	/*
    221	 * Remember location in AML stream of the field unit opcode and operands
    222	 * -- since the buffer and index operands must be evaluated.
    223	 */
    224	second_desc = obj_desc->common.next_object;
    225	second_desc->extra.aml_start = op->named.data;
    226	second_desc->extra.aml_length = op->named.length;
    227	obj_desc->buffer_field.node = node;
    228
    229	/* Attach constructed field descriptors to parent node */
    230
    231	status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
    232	if (ACPI_FAILURE(status)) {
    233		goto cleanup;
    234	}
    235
    236cleanup:
    237
    238	/* Remove local reference to the object */
    239
    240	acpi_ut_remove_reference(obj_desc);
    241	return_ACPI_STATUS(status);
    242}
    243
    244/*******************************************************************************
    245 *
    246 * FUNCTION:    acpi_ds_get_field_names
    247 *
    248 * PARAMETERS:  info            - create_field info structure
    249 *              walk_state      - Current method state
    250 *              arg             - First parser arg for the field name list
    251 *
    252 * RETURN:      Status
    253 *
    254 * DESCRIPTION: Process all named fields in a field declaration. Names are
    255 *              entered into the namespace.
    256 *
    257 ******************************************************************************/
    258
    259static acpi_status
    260acpi_ds_get_field_names(struct acpi_create_field_info *info,
    261			struct acpi_walk_state *walk_state,
    262			union acpi_parse_object *arg)
    263{
    264	acpi_status status;
    265	u64 position;
    266	union acpi_parse_object *child;
    267
    268#ifdef ACPI_EXEC_APP
    269	union acpi_operand_object *result_desc;
    270	union acpi_operand_object *obj_desc;
    271	char *name_path;
    272#endif
    273
    274	ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
    275
    276	/* First field starts at bit zero */
    277
    278	info->field_bit_position = 0;
    279
    280	/* Process all elements in the field list (of parse nodes) */
    281
    282	while (arg) {
    283		/*
    284		 * Four types of field elements are handled:
    285		 * 1) name - Enters a new named field into the namespace
    286		 * 2) offset - specifies a bit offset
    287		 * 3) access_as - changes the access mode/attributes
    288		 * 4) connection - Associate a resource template with the field
    289		 */
    290		switch (arg->common.aml_opcode) {
    291		case AML_INT_RESERVEDFIELD_OP:
    292
    293			position = (u64)info->field_bit_position +
    294			    (u64)arg->common.value.size;
    295
    296			if (position > ACPI_UINT32_MAX) {
    297				ACPI_ERROR((AE_INFO,
    298					    "Bit offset within field too large (> 0xFFFFFFFF)"));
    299				return_ACPI_STATUS(AE_SUPPORT);
    300			}
    301
    302			info->field_bit_position = (u32) position;
    303			break;
    304
    305		case AML_INT_ACCESSFIELD_OP:
    306		case AML_INT_EXTACCESSFIELD_OP:
    307			/*
    308			 * Get new access_type, access_attribute, and access_length fields
    309			 * -- to be used for all field units that follow, until the
    310			 * end-of-field or another access_as keyword is encountered.
    311			 * NOTE. These three bytes are encoded in the integer value
    312			 * of the parseop for convenience.
    313			 *
    314			 * In field_flags, preserve the flag bits other than the
    315			 * ACCESS_TYPE bits.
    316			 */
    317
    318			/* access_type (byte_acc, word_acc, etc.) */
    319
    320			info->field_flags = (u8)
    321			    ((info->
    322			      field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
    323			     ((u8)((u32)(arg->common.value.integer & 0x07))));
    324
    325			/* access_attribute (attrib_quick, attrib_byte, etc.) */
    326
    327			info->attribute = (u8)
    328			    ((arg->common.value.integer >> 8) & 0xFF);
    329
    330			/* access_length (for serial/buffer protocols) */
    331
    332			info->access_length = (u8)
    333			    ((arg->common.value.integer >> 16) & 0xFF);
    334			break;
    335
    336		case AML_INT_CONNECTION_OP:
    337			/*
    338			 * Clear any previous connection. New connection is used for all
    339			 * fields that follow, similar to access_as
    340			 */
    341			info->resource_buffer = NULL;
    342			info->connection_node = NULL;
    343			info->pin_number_index = 0;
    344
    345			/*
    346			 * A Connection() is either an actual resource descriptor (buffer)
    347			 * or a named reference to a resource template
    348			 */
    349			child = arg->common.value.arg;
    350			if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
    351				info->resource_buffer = child->named.data;
    352				info->resource_length =
    353				    (u16)child->named.value.integer;
    354			} else {
    355				/* Lookup the Connection() namepath, it should already exist */
    356
    357				status = acpi_ns_lookup(walk_state->scope_info,
    358							child->common.value.
    359							name, ACPI_TYPE_ANY,
    360							ACPI_IMODE_EXECUTE,
    361							ACPI_NS_DONT_OPEN_SCOPE,
    362							walk_state,
    363							&info->connection_node);
    364				if (ACPI_FAILURE(status)) {
    365					ACPI_ERROR_NAMESPACE(walk_state->
    366							     scope_info,
    367							     child->common.
    368							     value.name,
    369							     status);
    370					return_ACPI_STATUS(status);
    371				}
    372			}
    373			break;
    374
    375		case AML_INT_NAMEDFIELD_OP:
    376
    377			/* Lookup the name, it should already exist */
    378
    379			status = acpi_ns_lookup(walk_state->scope_info,
    380						(char *)&arg->named.name,
    381						info->field_type,
    382						ACPI_IMODE_EXECUTE,
    383						ACPI_NS_DONT_OPEN_SCOPE,
    384						walk_state, &info->field_node);
    385			if (ACPI_FAILURE(status)) {
    386				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
    387						     (char *)&arg->named.name,
    388						     status);
    389				return_ACPI_STATUS(status);
    390			} else {
    391				arg->common.node = info->field_node;
    392				info->field_bit_length = arg->common.value.size;
    393
    394				/*
    395				 * If there is no object attached to the node, this node was
    396				 * just created and we need to create the field object.
    397				 * Otherwise, this was a lookup of an existing node and we
    398				 * don't want to create the field object again.
    399				 */
    400				if (!acpi_ns_get_attached_object
    401				    (info->field_node)) {
    402					status = acpi_ex_prep_field_value(info);
    403					if (ACPI_FAILURE(status)) {
    404						return_ACPI_STATUS(status);
    405					}
    406#ifdef ACPI_EXEC_APP
    407					name_path =
    408					    acpi_ns_get_external_pathname(info->
    409									  field_node);
    410					if (ACPI_SUCCESS
    411					    (ae_lookup_init_file_entry
    412					     (name_path, &obj_desc))) {
    413						acpi_ex_write_data_to_field
    414						    (obj_desc,
    415						     acpi_ns_get_attached_object
    416						     (info->field_node),
    417						     &result_desc);
    418						acpi_ut_remove_reference
    419						    (obj_desc);
    420					}
    421					ACPI_FREE(name_path);
    422#endif
    423				}
    424			}
    425
    426			/* Keep track of bit position for the next field */
    427
    428			position = (u64)info->field_bit_position +
    429			    (u64)arg->common.value.size;
    430
    431			if (position > ACPI_UINT32_MAX) {
    432				ACPI_ERROR((AE_INFO,
    433					    "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
    434					    ACPI_CAST_PTR(char,
    435							  &info->field_node->
    436							  name)));
    437				return_ACPI_STATUS(AE_SUPPORT);
    438			}
    439
    440			info->field_bit_position += info->field_bit_length;
    441			info->pin_number_index++;	/* Index relative to previous Connection() */
    442			break;
    443
    444		default:
    445
    446			ACPI_ERROR((AE_INFO,
    447				    "Invalid opcode in field list: 0x%X",
    448				    arg->common.aml_opcode));
    449			return_ACPI_STATUS(AE_AML_BAD_OPCODE);
    450		}
    451
    452		arg = arg->common.next;
    453	}
    454
    455	return_ACPI_STATUS(AE_OK);
    456}
    457
    458/*******************************************************************************
    459 *
    460 * FUNCTION:    acpi_ds_create_field
    461 *
    462 * PARAMETERS:  op              - Op containing the Field definition and args
    463 *              region_node     - Object for the containing Operation Region
    464 *  `           walk_state      - Current method state
    465 *
    466 * RETURN:      Status
    467 *
    468 * DESCRIPTION: Create a new field in the specified operation region
    469 *
    470 ******************************************************************************/
    471
    472acpi_status
    473acpi_ds_create_field(union acpi_parse_object *op,
    474		     struct acpi_namespace_node *region_node,
    475		     struct acpi_walk_state *walk_state)
    476{
    477	acpi_status status;
    478	union acpi_parse_object *arg;
    479	struct acpi_create_field_info info;
    480
    481	ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
    482
    483	/* First arg is the name of the parent op_region (must already exist) */
    484
    485	arg = op->common.value.arg;
    486
    487	if (!region_node) {
    488		status =
    489		    acpi_ns_lookup(walk_state->scope_info,
    490				   arg->common.value.name, ACPI_TYPE_REGION,
    491				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
    492				   walk_state, &region_node);
    493#ifdef ACPI_ASL_COMPILER
    494		status = acpi_ds_create_external_region(status, arg,
    495							arg->common.value.name,
    496							walk_state,
    497							&region_node);
    498#endif
    499		if (ACPI_FAILURE(status)) {
    500			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
    501					     arg->common.value.name, status);
    502			return_ACPI_STATUS(status);
    503		}
    504	}
    505
    506	memset(&info, 0, sizeof(struct acpi_create_field_info));
    507
    508	/* Second arg is the field flags */
    509
    510	arg = arg->common.next;
    511	info.field_flags = (u8) arg->common.value.integer;
    512	info.attribute = 0;
    513
    514	/* Each remaining arg is a Named Field */
    515
    516	info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
    517	info.region_node = region_node;
    518
    519	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
    520	if (ACPI_FAILURE(status)) {
    521		return_ACPI_STATUS(status);
    522	}
    523
    524	if (info.region_node->object->region.space_id ==
    525	    ACPI_ADR_SPACE_PLATFORM_COMM) {
    526		region_node->object->field.internal_pcc_buffer =
    527		    ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
    528					 length);
    529		if (!region_node->object->field.internal_pcc_buffer) {
    530			return_ACPI_STATUS(AE_NO_MEMORY);
    531		}
    532	}
    533
    534	return_ACPI_STATUS(status);
    535}
    536
    537/*******************************************************************************
    538 *
    539 * FUNCTION:    acpi_ds_init_field_objects
    540 *
    541 * PARAMETERS:  op              - Op containing the Field definition and args
    542 *  `           walk_state      - Current method state
    543 *
    544 * RETURN:      Status
    545 *
    546 * DESCRIPTION: For each "Field Unit" name in the argument list that is
    547 *              part of the field declaration, enter the name into the
    548 *              namespace.
    549 *
    550 ******************************************************************************/
    551
    552acpi_status
    553acpi_ds_init_field_objects(union acpi_parse_object *op,
    554			   struct acpi_walk_state *walk_state)
    555{
    556	acpi_status status;
    557	union acpi_parse_object *arg = NULL;
    558	struct acpi_namespace_node *node;
    559	u8 type = 0;
    560	u32 flags;
    561
    562	ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
    563
    564	/* Execute flag should always be set when this function is entered */
    565
    566	if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
    567		if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
    568
    569			/* bank_field Op is deferred, just return OK */
    570
    571			return_ACPI_STATUS(AE_OK);
    572		}
    573
    574		ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
    575		return_ACPI_STATUS(AE_AML_INTERNAL);
    576	}
    577
    578	/*
    579	 * Get the field_list argument for this opcode. This is the start of the
    580	 * list of field elements.
    581	 */
    582	switch (walk_state->opcode) {
    583	case AML_FIELD_OP:
    584
    585		arg = acpi_ps_get_arg(op, 2);
    586		type = ACPI_TYPE_LOCAL_REGION_FIELD;
    587		break;
    588
    589	case AML_BANK_FIELD_OP:
    590
    591		arg = acpi_ps_get_arg(op, 4);
    592		type = ACPI_TYPE_LOCAL_BANK_FIELD;
    593		break;
    594
    595	case AML_INDEX_FIELD_OP:
    596
    597		arg = acpi_ps_get_arg(op, 3);
    598		type = ACPI_TYPE_LOCAL_INDEX_FIELD;
    599		break;
    600
    601	default:
    602
    603		return_ACPI_STATUS(AE_BAD_PARAMETER);
    604	}
    605
    606	/* Creating new namespace node(s), should not already exist */
    607
    608	flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
    609	    ACPI_NS_ERROR_IF_FOUND;
    610
    611	/*
    612	 * Mark node(s) temporary if we are executing a normal control
    613	 * method. (Don't mark if this is a module-level code method)
    614	 */
    615	if (walk_state->method_node &&
    616	    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
    617		flags |= ACPI_NS_TEMPORARY;
    618	}
    619#ifdef ACPI_EXEC_APP
    620	flags |= ACPI_NS_OVERRIDE_IF_FOUND;
    621#endif
    622	/*
    623	 * Walk the list of entries in the field_list
    624	 * Note: field_list can be of zero length. In this case, Arg will be NULL.
    625	 */
    626	while (arg) {
    627		/*
    628		 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
    629		 * in the field names in order to enter them into the namespace.
    630		 */
    631		if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
    632			status = acpi_ns_lookup(walk_state->scope_info,
    633						(char *)&arg->named.name, type,
    634						ACPI_IMODE_LOAD_PASS1, flags,
    635						walk_state, &node);
    636			if (ACPI_FAILURE(status)) {
    637				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
    638						     (char *)&arg->named.name,
    639						     status);
    640				if (status != AE_ALREADY_EXISTS) {
    641					return_ACPI_STATUS(status);
    642				}
    643
    644				/* Name already exists, just ignore this error */
    645			}
    646
    647			arg->common.node = node;
    648		}
    649
    650		/* Get the next field element in the list */
    651
    652		arg = arg->common.next;
    653	}
    654
    655	return_ACPI_STATUS(AE_OK);
    656}
    657
    658/*******************************************************************************
    659 *
    660 * FUNCTION:    acpi_ds_create_bank_field
    661 *
    662 * PARAMETERS:  op              - Op containing the Field definition and args
    663 *              region_node     - Object for the containing Operation Region
    664 *              walk_state      - Current method state
    665 *
    666 * RETURN:      Status
    667 *
    668 * DESCRIPTION: Create a new bank field in the specified operation region
    669 *
    670 ******************************************************************************/
    671
    672acpi_status
    673acpi_ds_create_bank_field(union acpi_parse_object *op,
    674			  struct acpi_namespace_node *region_node,
    675			  struct acpi_walk_state *walk_state)
    676{
    677	acpi_status status;
    678	union acpi_parse_object *arg;
    679	struct acpi_create_field_info info;
    680
    681	ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
    682
    683	/* First arg is the name of the parent op_region (must already exist) */
    684
    685	arg = op->common.value.arg;
    686	if (!region_node) {
    687		status =
    688		    acpi_ns_lookup(walk_state->scope_info,
    689				   arg->common.value.name, ACPI_TYPE_REGION,
    690				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
    691				   walk_state, &region_node);
    692#ifdef ACPI_ASL_COMPILER
    693		status = acpi_ds_create_external_region(status, arg,
    694							arg->common.value.name,
    695							walk_state,
    696							&region_node);
    697#endif
    698		if (ACPI_FAILURE(status)) {
    699			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
    700					     arg->common.value.name, status);
    701			return_ACPI_STATUS(status);
    702		}
    703	}
    704
    705	/* Second arg is the Bank Register (Field) (must already exist) */
    706
    707	arg = arg->common.next;
    708	status =
    709	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
    710			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
    711			   ACPI_NS_SEARCH_PARENT, walk_state,
    712			   &info.register_node);
    713	if (ACPI_FAILURE(status)) {
    714		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
    715				     arg->common.value.string, status);
    716		return_ACPI_STATUS(status);
    717	}
    718
    719	/*
    720	 * Third arg is the bank_value
    721	 * This arg is a term_arg, not a constant
    722	 * It will be evaluated later, by acpi_ds_eval_bank_field_operands
    723	 */
    724	arg = arg->common.next;
    725
    726	/* Fourth arg is the field flags */
    727
    728	arg = arg->common.next;
    729	info.field_flags = (u8) arg->common.value.integer;
    730
    731	/* Each remaining arg is a Named Field */
    732
    733	info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
    734	info.region_node = region_node;
    735
    736	/*
    737	 * Use Info.data_register_node to store bank_field Op
    738	 * It's safe because data_register_node will never be used when create
    739	 * bank field \we store aml_start and aml_length in the bank_field Op for
    740	 * late evaluation. Used in acpi_ex_prep_field_value(Info)
    741	 *
    742	 * TBD: Or, should we add a field in struct acpi_create_field_info, like
    743	 * "void *ParentOp"?
    744	 */
    745	info.data_register_node = (struct acpi_namespace_node *)op;
    746
    747	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
    748	return_ACPI_STATUS(status);
    749}
    750
    751/*******************************************************************************
    752 *
    753 * FUNCTION:    acpi_ds_create_index_field
    754 *
    755 * PARAMETERS:  op              - Op containing the Field definition and args
    756 *              region_node     - Object for the containing Operation Region
    757 *  `           walk_state      - Current method state
    758 *
    759 * RETURN:      Status
    760 *
    761 * DESCRIPTION: Create a new index field in the specified operation region
    762 *
    763 ******************************************************************************/
    764
    765acpi_status
    766acpi_ds_create_index_field(union acpi_parse_object *op,
    767			   struct acpi_namespace_node *region_node,
    768			   struct acpi_walk_state *walk_state)
    769{
    770	acpi_status status;
    771	union acpi_parse_object *arg;
    772	struct acpi_create_field_info info;
    773
    774	ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
    775
    776	/* First arg is the name of the Index register (must already exist) */
    777
    778	arg = op->common.value.arg;
    779	status =
    780	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
    781			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
    782			   ACPI_NS_SEARCH_PARENT, walk_state,
    783			   &info.register_node);
    784	if (ACPI_FAILURE(status)) {
    785		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
    786				     arg->common.value.string, status);
    787		return_ACPI_STATUS(status);
    788	}
    789
    790	/* Second arg is the data register (must already exist) */
    791
    792	arg = arg->common.next;
    793	status =
    794	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
    795			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
    796			   ACPI_NS_SEARCH_PARENT, walk_state,
    797			   &info.data_register_node);
    798	if (ACPI_FAILURE(status)) {
    799		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
    800				     arg->common.value.string, status);
    801		return_ACPI_STATUS(status);
    802	}
    803
    804	/* Next arg is the field flags */
    805
    806	arg = arg->common.next;
    807	info.field_flags = (u8) arg->common.value.integer;
    808
    809	/* Each remaining arg is a Named Field */
    810
    811	info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
    812	info.region_node = region_node;
    813
    814	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
    815	return_ACPI_STATUS(status);
    816}