162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: dsfield - Dispatcher field routines
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2000 - 2023, Intel Corp.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *****************************************************************************/
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <acpi/acpi.h>
1162306a36Sopenharmony_ci#include "accommon.h"
1262306a36Sopenharmony_ci#include "amlcode.h"
1362306a36Sopenharmony_ci#include "acdispat.h"
1462306a36Sopenharmony_ci#include "acinterp.h"
1562306a36Sopenharmony_ci#include "acnamesp.h"
1662306a36Sopenharmony_ci#include "acparser.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#ifdef ACPI_EXEC_APP
1962306a36Sopenharmony_ci#include "aecommon.h"
2062306a36Sopenharmony_ci#endif
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define _COMPONENT          ACPI_DISPATCHER
2362306a36Sopenharmony_ciACPI_MODULE_NAME("dsfield")
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/* Local prototypes */
2662306a36Sopenharmony_ci#ifdef ACPI_ASL_COMPILER
2762306a36Sopenharmony_ci#include "acdisasm.h"
2862306a36Sopenharmony_cistatic acpi_status
2962306a36Sopenharmony_ciacpi_ds_create_external_region(acpi_status lookup_status,
3062306a36Sopenharmony_ci			       union acpi_parse_object *op,
3162306a36Sopenharmony_ci			       char *path,
3262306a36Sopenharmony_ci			       struct acpi_walk_state *walk_state,
3362306a36Sopenharmony_ci			       struct acpi_namespace_node **node);
3462306a36Sopenharmony_ci#endif
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistatic acpi_status
3762306a36Sopenharmony_ciacpi_ds_get_field_names(struct acpi_create_field_info *info,
3862306a36Sopenharmony_ci			struct acpi_walk_state *walk_state,
3962306a36Sopenharmony_ci			union acpi_parse_object *arg);
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#ifdef ACPI_ASL_COMPILER
4262306a36Sopenharmony_ci/*******************************************************************************
4362306a36Sopenharmony_ci *
4462306a36Sopenharmony_ci * FUNCTION:    acpi_ds_create_external_region (iASL Disassembler only)
4562306a36Sopenharmony_ci *
4662306a36Sopenharmony_ci * PARAMETERS:  lookup_status   - Status from ns_lookup operation
4762306a36Sopenharmony_ci *              op              - Op containing the Field definition and args
4862306a36Sopenharmony_ci *              path            - Pathname of the region
4962306a36Sopenharmony_ci *  `           walk_state      - Current method state
5062306a36Sopenharmony_ci *              node            - Where the new region node is returned
5162306a36Sopenharmony_ci *
5262306a36Sopenharmony_ci * RETURN:      Status
5362306a36Sopenharmony_ci *
5462306a36Sopenharmony_ci * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
5562306a36Sopenharmony_ci *              region node/object.
5662306a36Sopenharmony_ci *
5762306a36Sopenharmony_ci ******************************************************************************/
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic acpi_status
6062306a36Sopenharmony_ciacpi_ds_create_external_region(acpi_status lookup_status,
6162306a36Sopenharmony_ci			       union acpi_parse_object *op,
6262306a36Sopenharmony_ci			       char *path,
6362306a36Sopenharmony_ci			       struct acpi_walk_state *walk_state,
6462306a36Sopenharmony_ci			       struct acpi_namespace_node **node)
6562306a36Sopenharmony_ci{
6662306a36Sopenharmony_ci	acpi_status status;
6762306a36Sopenharmony_ci	union acpi_operand_object *obj_desc;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	if (lookup_status != AE_NOT_FOUND) {
7062306a36Sopenharmony_ci		return (lookup_status);
7162306a36Sopenharmony_ci	}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	/*
7462306a36Sopenharmony_ci	 * Table disassembly:
7562306a36Sopenharmony_ci	 * operation_region not found. Generate an External for it, and
7662306a36Sopenharmony_ci	 * insert the name into the namespace.
7762306a36Sopenharmony_ci	 */
7862306a36Sopenharmony_ci	acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
8162306a36Sopenharmony_ci				ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
8262306a36Sopenharmony_ci				walk_state, node);
8362306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
8462306a36Sopenharmony_ci		return (status);
8562306a36Sopenharmony_ci	}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	/* Must create and install a region object for the new node */
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
9062306a36Sopenharmony_ci	if (!obj_desc) {
9162306a36Sopenharmony_ci		return (AE_NO_MEMORY);
9262306a36Sopenharmony_ci	}
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	obj_desc->region.node = *node;
9562306a36Sopenharmony_ci	status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
9662306a36Sopenharmony_ci	return (status);
9762306a36Sopenharmony_ci}
9862306a36Sopenharmony_ci#endif
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci/*******************************************************************************
10162306a36Sopenharmony_ci *
10262306a36Sopenharmony_ci * FUNCTION:    acpi_ds_create_buffer_field
10362306a36Sopenharmony_ci *
10462306a36Sopenharmony_ci * PARAMETERS:  op                  - Current parse op (create_XXField)
10562306a36Sopenharmony_ci *              walk_state          - Current state
10662306a36Sopenharmony_ci *
10762306a36Sopenharmony_ci * RETURN:      Status
10862306a36Sopenharmony_ci *
10962306a36Sopenharmony_ci * DESCRIPTION: Execute the create_field operators:
11062306a36Sopenharmony_ci *              create_bit_field_op,
11162306a36Sopenharmony_ci *              create_byte_field_op,
11262306a36Sopenharmony_ci *              create_word_field_op,
11362306a36Sopenharmony_ci *              create_dword_field_op,
11462306a36Sopenharmony_ci *              create_qword_field_op,
11562306a36Sopenharmony_ci *              create_field_op     (all of which define a field in a buffer)
11662306a36Sopenharmony_ci *
11762306a36Sopenharmony_ci ******************************************************************************/
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ciacpi_status
12062306a36Sopenharmony_ciacpi_ds_create_buffer_field(union acpi_parse_object *op,
12162306a36Sopenharmony_ci			    struct acpi_walk_state *walk_state)
12262306a36Sopenharmony_ci{
12362306a36Sopenharmony_ci	union acpi_parse_object *arg;
12462306a36Sopenharmony_ci	struct acpi_namespace_node *node;
12562306a36Sopenharmony_ci	acpi_status status;
12662306a36Sopenharmony_ci	union acpi_operand_object *obj_desc;
12762306a36Sopenharmony_ci	union acpi_operand_object *second_desc = NULL;
12862306a36Sopenharmony_ci	u32 flags;
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ds_create_buffer_field);
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	/*
13362306a36Sopenharmony_ci	 * Get the name_string argument (name of the new buffer_field)
13462306a36Sopenharmony_ci	 */
13562306a36Sopenharmony_ci	if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci		/* For create_field, name is the 4th argument */
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci		arg = acpi_ps_get_arg(op, 3);
14062306a36Sopenharmony_ci	} else {
14162306a36Sopenharmony_ci		/* For all other create_XXXField operators, name is the 3rd argument */
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci		arg = acpi_ps_get_arg(op, 2);
14462306a36Sopenharmony_ci	}
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	if (!arg) {
14762306a36Sopenharmony_ci		return_ACPI_STATUS(AE_AML_NO_OPERAND);
14862306a36Sopenharmony_ci	}
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	if (walk_state->deferred_node) {
15162306a36Sopenharmony_ci		node = walk_state->deferred_node;
15262306a36Sopenharmony_ci	} else {
15362306a36Sopenharmony_ci		/* Execute flag should always be set when this function is entered */
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci		if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
15662306a36Sopenharmony_ci			ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
15762306a36Sopenharmony_ci			return_ACPI_STATUS(AE_AML_INTERNAL);
15862306a36Sopenharmony_ci		}
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci		/* Creating new namespace node, should not already exist */
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci		flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
16362306a36Sopenharmony_ci		    ACPI_NS_ERROR_IF_FOUND;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci		/*
16662306a36Sopenharmony_ci		 * Mark node temporary if we are executing a normal control
16762306a36Sopenharmony_ci		 * method. (Don't mark if this is a module-level code method)
16862306a36Sopenharmony_ci		 */
16962306a36Sopenharmony_ci		if (walk_state->method_node &&
17062306a36Sopenharmony_ci		    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
17162306a36Sopenharmony_ci			flags |= ACPI_NS_TEMPORARY;
17262306a36Sopenharmony_ci		}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci		/* Enter the name_string into the namespace */
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci		status = acpi_ns_lookup(walk_state->scope_info,
17762306a36Sopenharmony_ci					arg->common.value.string, ACPI_TYPE_ANY,
17862306a36Sopenharmony_ci					ACPI_IMODE_LOAD_PASS1, flags,
17962306a36Sopenharmony_ci					walk_state, &node);
18062306a36Sopenharmony_ci		if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE)
18162306a36Sopenharmony_ci		    && status == AE_ALREADY_EXISTS) {
18262306a36Sopenharmony_ci			status = AE_OK;
18362306a36Sopenharmony_ci		} else if (ACPI_FAILURE(status)) {
18462306a36Sopenharmony_ci			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
18562306a36Sopenharmony_ci					     arg->common.value.string, status);
18662306a36Sopenharmony_ci			return_ACPI_STATUS(status);
18762306a36Sopenharmony_ci		}
18862306a36Sopenharmony_ci	}
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	/*
19162306a36Sopenharmony_ci	 * We could put the returned object (Node) on the object stack for later,
19262306a36Sopenharmony_ci	 * but for now, we will put it in the "op" object that the parser uses,
19362306a36Sopenharmony_ci	 * so we can get it again at the end of this scope.
19462306a36Sopenharmony_ci	 */
19562306a36Sopenharmony_ci	op->common.node = node;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	/*
19862306a36Sopenharmony_ci	 * If there is no object attached to the node, this node was just created
19962306a36Sopenharmony_ci	 * and we need to create the field object. Otherwise, this was a lookup
20062306a36Sopenharmony_ci	 * of an existing node and we don't want to create the field object again.
20162306a36Sopenharmony_ci	 */
20262306a36Sopenharmony_ci	obj_desc = acpi_ns_get_attached_object(node);
20362306a36Sopenharmony_ci	if (obj_desc) {
20462306a36Sopenharmony_ci		return_ACPI_STATUS(AE_OK);
20562306a36Sopenharmony_ci	}
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	/*
20862306a36Sopenharmony_ci	 * The Field definition is not fully parsed at this time.
20962306a36Sopenharmony_ci	 * (We must save the address of the AML for the buffer and index operands)
21062306a36Sopenharmony_ci	 */
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	/* Create the buffer field object */
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
21562306a36Sopenharmony_ci	if (!obj_desc) {
21662306a36Sopenharmony_ci		status = AE_NO_MEMORY;
21762306a36Sopenharmony_ci		goto cleanup;
21862306a36Sopenharmony_ci	}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	/*
22162306a36Sopenharmony_ci	 * Remember location in AML stream of the field unit opcode and operands
22262306a36Sopenharmony_ci	 * -- since the buffer and index operands must be evaluated.
22362306a36Sopenharmony_ci	 */
22462306a36Sopenharmony_ci	second_desc = obj_desc->common.next_object;
22562306a36Sopenharmony_ci	second_desc->extra.aml_start = op->named.data;
22662306a36Sopenharmony_ci	second_desc->extra.aml_length = op->named.length;
22762306a36Sopenharmony_ci	obj_desc->buffer_field.node = node;
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	/* Attach constructed field descriptors to parent node */
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
23262306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
23362306a36Sopenharmony_ci		goto cleanup;
23462306a36Sopenharmony_ci	}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cicleanup:
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	/* Remove local reference to the object */
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	acpi_ut_remove_reference(obj_desc);
24162306a36Sopenharmony_ci	return_ACPI_STATUS(status);
24262306a36Sopenharmony_ci}
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci/*******************************************************************************
24562306a36Sopenharmony_ci *
24662306a36Sopenharmony_ci * FUNCTION:    acpi_ds_get_field_names
24762306a36Sopenharmony_ci *
24862306a36Sopenharmony_ci * PARAMETERS:  info            - create_field info structure
24962306a36Sopenharmony_ci *              walk_state      - Current method state
25062306a36Sopenharmony_ci *              arg             - First parser arg for the field name list
25162306a36Sopenharmony_ci *
25262306a36Sopenharmony_ci * RETURN:      Status
25362306a36Sopenharmony_ci *
25462306a36Sopenharmony_ci * DESCRIPTION: Process all named fields in a field declaration. Names are
25562306a36Sopenharmony_ci *              entered into the namespace.
25662306a36Sopenharmony_ci *
25762306a36Sopenharmony_ci ******************************************************************************/
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_cistatic acpi_status
26062306a36Sopenharmony_ciacpi_ds_get_field_names(struct acpi_create_field_info *info,
26162306a36Sopenharmony_ci			struct acpi_walk_state *walk_state,
26262306a36Sopenharmony_ci			union acpi_parse_object *arg)
26362306a36Sopenharmony_ci{
26462306a36Sopenharmony_ci	acpi_status status;
26562306a36Sopenharmony_ci	u64 position;
26662306a36Sopenharmony_ci	union acpi_parse_object *child;
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci#ifdef ACPI_EXEC_APP
26962306a36Sopenharmony_ci	union acpi_operand_object *result_desc;
27062306a36Sopenharmony_ci	union acpi_operand_object *obj_desc;
27162306a36Sopenharmony_ci	char *name_path;
27262306a36Sopenharmony_ci#endif
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	/* First field starts at bit zero */
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	info->field_bit_position = 0;
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	/* Process all elements in the field list (of parse nodes) */
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	while (arg) {
28362306a36Sopenharmony_ci		/*
28462306a36Sopenharmony_ci		 * Four types of field elements are handled:
28562306a36Sopenharmony_ci		 * 1) name - Enters a new named field into the namespace
28662306a36Sopenharmony_ci		 * 2) offset - specifies a bit offset
28762306a36Sopenharmony_ci		 * 3) access_as - changes the access mode/attributes
28862306a36Sopenharmony_ci		 * 4) connection - Associate a resource template with the field
28962306a36Sopenharmony_ci		 */
29062306a36Sopenharmony_ci		switch (arg->common.aml_opcode) {
29162306a36Sopenharmony_ci		case AML_INT_RESERVEDFIELD_OP:
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci			position = (u64)info->field_bit_position +
29462306a36Sopenharmony_ci			    (u64)arg->common.value.size;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci			if (position > ACPI_UINT32_MAX) {
29762306a36Sopenharmony_ci				ACPI_ERROR((AE_INFO,
29862306a36Sopenharmony_ci					    "Bit offset within field too large (> 0xFFFFFFFF)"));
29962306a36Sopenharmony_ci				return_ACPI_STATUS(AE_SUPPORT);
30062306a36Sopenharmony_ci			}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci			info->field_bit_position = (u32) position;
30362306a36Sopenharmony_ci			break;
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci		case AML_INT_ACCESSFIELD_OP:
30662306a36Sopenharmony_ci		case AML_INT_EXTACCESSFIELD_OP:
30762306a36Sopenharmony_ci			/*
30862306a36Sopenharmony_ci			 * Get new access_type, access_attribute, and access_length fields
30962306a36Sopenharmony_ci			 * -- to be used for all field units that follow, until the
31062306a36Sopenharmony_ci			 * end-of-field or another access_as keyword is encountered.
31162306a36Sopenharmony_ci			 * NOTE. These three bytes are encoded in the integer value
31262306a36Sopenharmony_ci			 * of the parseop for convenience.
31362306a36Sopenharmony_ci			 *
31462306a36Sopenharmony_ci			 * In field_flags, preserve the flag bits other than the
31562306a36Sopenharmony_ci			 * ACCESS_TYPE bits.
31662306a36Sopenharmony_ci			 */
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci			/* access_type (byte_acc, word_acc, etc.) */
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci			info->field_flags = (u8)
32162306a36Sopenharmony_ci			    ((info->
32262306a36Sopenharmony_ci			      field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
32362306a36Sopenharmony_ci			     ((u8)((u32)(arg->common.value.integer & 0x07))));
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci			/* access_attribute (attrib_quick, attrib_byte, etc.) */
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci			info->attribute = (u8)
32862306a36Sopenharmony_ci			    ((arg->common.value.integer >> 8) & 0xFF);
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci			/* access_length (for serial/buffer protocols) */
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci			info->access_length = (u8)
33362306a36Sopenharmony_ci			    ((arg->common.value.integer >> 16) & 0xFF);
33462306a36Sopenharmony_ci			break;
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci		case AML_INT_CONNECTION_OP:
33762306a36Sopenharmony_ci			/*
33862306a36Sopenharmony_ci			 * Clear any previous connection. New connection is used for all
33962306a36Sopenharmony_ci			 * fields that follow, similar to access_as
34062306a36Sopenharmony_ci			 */
34162306a36Sopenharmony_ci			info->resource_buffer = NULL;
34262306a36Sopenharmony_ci			info->connection_node = NULL;
34362306a36Sopenharmony_ci			info->pin_number_index = 0;
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci			/*
34662306a36Sopenharmony_ci			 * A Connection() is either an actual resource descriptor (buffer)
34762306a36Sopenharmony_ci			 * or a named reference to a resource template
34862306a36Sopenharmony_ci			 */
34962306a36Sopenharmony_ci			child = arg->common.value.arg;
35062306a36Sopenharmony_ci			if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
35162306a36Sopenharmony_ci				info->resource_buffer = child->named.data;
35262306a36Sopenharmony_ci				info->resource_length =
35362306a36Sopenharmony_ci				    (u16)child->named.value.integer;
35462306a36Sopenharmony_ci			} else {
35562306a36Sopenharmony_ci				/* Lookup the Connection() namepath, it should already exist */
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci				status = acpi_ns_lookup(walk_state->scope_info,
35862306a36Sopenharmony_ci							child->common.value.
35962306a36Sopenharmony_ci							name, ACPI_TYPE_ANY,
36062306a36Sopenharmony_ci							ACPI_IMODE_EXECUTE,
36162306a36Sopenharmony_ci							ACPI_NS_DONT_OPEN_SCOPE,
36262306a36Sopenharmony_ci							walk_state,
36362306a36Sopenharmony_ci							&info->connection_node);
36462306a36Sopenharmony_ci				if (ACPI_FAILURE(status)) {
36562306a36Sopenharmony_ci					ACPI_ERROR_NAMESPACE(walk_state->
36662306a36Sopenharmony_ci							     scope_info,
36762306a36Sopenharmony_ci							     child->common.
36862306a36Sopenharmony_ci							     value.name,
36962306a36Sopenharmony_ci							     status);
37062306a36Sopenharmony_ci					return_ACPI_STATUS(status);
37162306a36Sopenharmony_ci				}
37262306a36Sopenharmony_ci			}
37362306a36Sopenharmony_ci			break;
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci		case AML_INT_NAMEDFIELD_OP:
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci			/* Lookup the name, it should already exist */
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci			status = acpi_ns_lookup(walk_state->scope_info,
38062306a36Sopenharmony_ci						(char *)&arg->named.name,
38162306a36Sopenharmony_ci						info->field_type,
38262306a36Sopenharmony_ci						ACPI_IMODE_EXECUTE,
38362306a36Sopenharmony_ci						ACPI_NS_DONT_OPEN_SCOPE,
38462306a36Sopenharmony_ci						walk_state, &info->field_node);
38562306a36Sopenharmony_ci			if (ACPI_FAILURE(status)) {
38662306a36Sopenharmony_ci				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
38762306a36Sopenharmony_ci						     (char *)&arg->named.name,
38862306a36Sopenharmony_ci						     status);
38962306a36Sopenharmony_ci				return_ACPI_STATUS(status);
39062306a36Sopenharmony_ci			} else {
39162306a36Sopenharmony_ci				arg->common.node = info->field_node;
39262306a36Sopenharmony_ci				info->field_bit_length = arg->common.value.size;
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci				/*
39562306a36Sopenharmony_ci				 * If there is no object attached to the node, this node was
39662306a36Sopenharmony_ci				 * just created and we need to create the field object.
39762306a36Sopenharmony_ci				 * Otherwise, this was a lookup of an existing node and we
39862306a36Sopenharmony_ci				 * don't want to create the field object again.
39962306a36Sopenharmony_ci				 */
40062306a36Sopenharmony_ci				if (!acpi_ns_get_attached_object
40162306a36Sopenharmony_ci				    (info->field_node)) {
40262306a36Sopenharmony_ci					status = acpi_ex_prep_field_value(info);
40362306a36Sopenharmony_ci					if (ACPI_FAILURE(status)) {
40462306a36Sopenharmony_ci						return_ACPI_STATUS(status);
40562306a36Sopenharmony_ci					}
40662306a36Sopenharmony_ci#ifdef ACPI_EXEC_APP
40762306a36Sopenharmony_ci					name_path =
40862306a36Sopenharmony_ci					    acpi_ns_get_external_pathname(info->
40962306a36Sopenharmony_ci									  field_node);
41062306a36Sopenharmony_ci					if (ACPI_SUCCESS
41162306a36Sopenharmony_ci					    (ae_lookup_init_file_entry
41262306a36Sopenharmony_ci					     (name_path, &obj_desc))) {
41362306a36Sopenharmony_ci						acpi_ex_write_data_to_field
41462306a36Sopenharmony_ci						    (obj_desc,
41562306a36Sopenharmony_ci						     acpi_ns_get_attached_object
41662306a36Sopenharmony_ci						     (info->field_node),
41762306a36Sopenharmony_ci						     &result_desc);
41862306a36Sopenharmony_ci						acpi_ut_remove_reference
41962306a36Sopenharmony_ci						    (obj_desc);
42062306a36Sopenharmony_ci					}
42162306a36Sopenharmony_ci					ACPI_FREE(name_path);
42262306a36Sopenharmony_ci#endif
42362306a36Sopenharmony_ci				}
42462306a36Sopenharmony_ci			}
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci			/* Keep track of bit position for the next field */
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci			position = (u64)info->field_bit_position +
42962306a36Sopenharmony_ci			    (u64)arg->common.value.size;
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci			if (position > ACPI_UINT32_MAX) {
43262306a36Sopenharmony_ci				ACPI_ERROR((AE_INFO,
43362306a36Sopenharmony_ci					    "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
43462306a36Sopenharmony_ci					    ACPI_CAST_PTR(char,
43562306a36Sopenharmony_ci							  &info->field_node->
43662306a36Sopenharmony_ci							  name)));
43762306a36Sopenharmony_ci				return_ACPI_STATUS(AE_SUPPORT);
43862306a36Sopenharmony_ci			}
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci			info->field_bit_position += info->field_bit_length;
44162306a36Sopenharmony_ci			info->pin_number_index++;	/* Index relative to previous Connection() */
44262306a36Sopenharmony_ci			break;
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci		default:
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci			ACPI_ERROR((AE_INFO,
44762306a36Sopenharmony_ci				    "Invalid opcode in field list: 0x%X",
44862306a36Sopenharmony_ci				    arg->common.aml_opcode));
44962306a36Sopenharmony_ci			return_ACPI_STATUS(AE_AML_BAD_OPCODE);
45062306a36Sopenharmony_ci		}
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci		arg = arg->common.next;
45362306a36Sopenharmony_ci	}
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	return_ACPI_STATUS(AE_OK);
45662306a36Sopenharmony_ci}
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci/*******************************************************************************
45962306a36Sopenharmony_ci *
46062306a36Sopenharmony_ci * FUNCTION:    acpi_ds_create_field
46162306a36Sopenharmony_ci *
46262306a36Sopenharmony_ci * PARAMETERS:  op              - Op containing the Field definition and args
46362306a36Sopenharmony_ci *              region_node     - Object for the containing Operation Region
46462306a36Sopenharmony_ci *  `           walk_state      - Current method state
46562306a36Sopenharmony_ci *
46662306a36Sopenharmony_ci * RETURN:      Status
46762306a36Sopenharmony_ci *
46862306a36Sopenharmony_ci * DESCRIPTION: Create a new field in the specified operation region
46962306a36Sopenharmony_ci *
47062306a36Sopenharmony_ci ******************************************************************************/
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ciacpi_status
47362306a36Sopenharmony_ciacpi_ds_create_field(union acpi_parse_object *op,
47462306a36Sopenharmony_ci		     struct acpi_namespace_node *region_node,
47562306a36Sopenharmony_ci		     struct acpi_walk_state *walk_state)
47662306a36Sopenharmony_ci{
47762306a36Sopenharmony_ci	acpi_status status;
47862306a36Sopenharmony_ci	union acpi_parse_object *arg;
47962306a36Sopenharmony_ci	struct acpi_create_field_info info;
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci	/* First arg is the name of the parent op_region (must already exist) */
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	arg = op->common.value.arg;
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	if (!region_node) {
48862306a36Sopenharmony_ci		status =
48962306a36Sopenharmony_ci		    acpi_ns_lookup(walk_state->scope_info,
49062306a36Sopenharmony_ci				   arg->common.value.name, ACPI_TYPE_REGION,
49162306a36Sopenharmony_ci				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
49262306a36Sopenharmony_ci				   walk_state, &region_node);
49362306a36Sopenharmony_ci#ifdef ACPI_ASL_COMPILER
49462306a36Sopenharmony_ci		status = acpi_ds_create_external_region(status, arg,
49562306a36Sopenharmony_ci							arg->common.value.name,
49662306a36Sopenharmony_ci							walk_state,
49762306a36Sopenharmony_ci							&region_node);
49862306a36Sopenharmony_ci#endif
49962306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
50062306a36Sopenharmony_ci			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
50162306a36Sopenharmony_ci					     arg->common.value.name, status);
50262306a36Sopenharmony_ci			return_ACPI_STATUS(status);
50362306a36Sopenharmony_ci		}
50462306a36Sopenharmony_ci	}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	memset(&info, 0, sizeof(struct acpi_create_field_info));
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	/* Second arg is the field flags */
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci	arg = arg->common.next;
51162306a36Sopenharmony_ci	info.field_flags = (u8) arg->common.value.integer;
51262306a36Sopenharmony_ci	info.attribute = 0;
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	/* Each remaining arg is a Named Field */
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
51762306a36Sopenharmony_ci	info.region_node = region_node;
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
52062306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
52162306a36Sopenharmony_ci		return_ACPI_STATUS(status);
52262306a36Sopenharmony_ci	}
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	if (info.region_node->object->region.space_id ==
52562306a36Sopenharmony_ci	    ACPI_ADR_SPACE_PLATFORM_COMM) {
52662306a36Sopenharmony_ci		region_node->object->field.internal_pcc_buffer =
52762306a36Sopenharmony_ci		    ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
52862306a36Sopenharmony_ci					 length);
52962306a36Sopenharmony_ci		if (!region_node->object->field.internal_pcc_buffer) {
53062306a36Sopenharmony_ci			return_ACPI_STATUS(AE_NO_MEMORY);
53162306a36Sopenharmony_ci		}
53262306a36Sopenharmony_ci	}
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci	return_ACPI_STATUS(status);
53562306a36Sopenharmony_ci}
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci/*******************************************************************************
53862306a36Sopenharmony_ci *
53962306a36Sopenharmony_ci * FUNCTION:    acpi_ds_init_field_objects
54062306a36Sopenharmony_ci *
54162306a36Sopenharmony_ci * PARAMETERS:  op              - Op containing the Field definition and args
54262306a36Sopenharmony_ci *  `           walk_state      - Current method state
54362306a36Sopenharmony_ci *
54462306a36Sopenharmony_ci * RETURN:      Status
54562306a36Sopenharmony_ci *
54662306a36Sopenharmony_ci * DESCRIPTION: For each "Field Unit" name in the argument list that is
54762306a36Sopenharmony_ci *              part of the field declaration, enter the name into the
54862306a36Sopenharmony_ci *              namespace.
54962306a36Sopenharmony_ci *
55062306a36Sopenharmony_ci ******************************************************************************/
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ciacpi_status
55362306a36Sopenharmony_ciacpi_ds_init_field_objects(union acpi_parse_object *op,
55462306a36Sopenharmony_ci			   struct acpi_walk_state *walk_state)
55562306a36Sopenharmony_ci{
55662306a36Sopenharmony_ci	acpi_status status;
55762306a36Sopenharmony_ci	union acpi_parse_object *arg = NULL;
55862306a36Sopenharmony_ci	struct acpi_namespace_node *node;
55962306a36Sopenharmony_ci	u8 type = 0;
56062306a36Sopenharmony_ci	u32 flags;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci	/* Execute flag should always be set when this function is entered */
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ci	if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
56762306a36Sopenharmony_ci		if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci			/* bank_field Op is deferred, just return OK */
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci			return_ACPI_STATUS(AE_OK);
57262306a36Sopenharmony_ci		}
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_ci		ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
57562306a36Sopenharmony_ci		return_ACPI_STATUS(AE_AML_INTERNAL);
57662306a36Sopenharmony_ci	}
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci	/*
57962306a36Sopenharmony_ci	 * Get the field_list argument for this opcode. This is the start of the
58062306a36Sopenharmony_ci	 * list of field elements.
58162306a36Sopenharmony_ci	 */
58262306a36Sopenharmony_ci	switch (walk_state->opcode) {
58362306a36Sopenharmony_ci	case AML_FIELD_OP:
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci		arg = acpi_ps_get_arg(op, 2);
58662306a36Sopenharmony_ci		type = ACPI_TYPE_LOCAL_REGION_FIELD;
58762306a36Sopenharmony_ci		break;
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	case AML_BANK_FIELD_OP:
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci		arg = acpi_ps_get_arg(op, 4);
59262306a36Sopenharmony_ci		type = ACPI_TYPE_LOCAL_BANK_FIELD;
59362306a36Sopenharmony_ci		break;
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	case AML_INDEX_FIELD_OP:
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci		arg = acpi_ps_get_arg(op, 3);
59862306a36Sopenharmony_ci		type = ACPI_TYPE_LOCAL_INDEX_FIELD;
59962306a36Sopenharmony_ci		break;
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	default:
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci		return_ACPI_STATUS(AE_BAD_PARAMETER);
60462306a36Sopenharmony_ci	}
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci	/* Creating new namespace node(s), should not already exist */
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci	flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
60962306a36Sopenharmony_ci	    ACPI_NS_ERROR_IF_FOUND;
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci	/*
61262306a36Sopenharmony_ci	 * Mark node(s) temporary if we are executing a normal control
61362306a36Sopenharmony_ci	 * method. (Don't mark if this is a module-level code method)
61462306a36Sopenharmony_ci	 */
61562306a36Sopenharmony_ci	if (walk_state->method_node &&
61662306a36Sopenharmony_ci	    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
61762306a36Sopenharmony_ci		flags |= ACPI_NS_TEMPORARY;
61862306a36Sopenharmony_ci	}
61962306a36Sopenharmony_ci#ifdef ACPI_EXEC_APP
62062306a36Sopenharmony_ci	flags |= ACPI_NS_OVERRIDE_IF_FOUND;
62162306a36Sopenharmony_ci#endif
62262306a36Sopenharmony_ci	/*
62362306a36Sopenharmony_ci	 * Walk the list of entries in the field_list
62462306a36Sopenharmony_ci	 * Note: field_list can be of zero length. In this case, Arg will be NULL.
62562306a36Sopenharmony_ci	 */
62662306a36Sopenharmony_ci	while (arg) {
62762306a36Sopenharmony_ci		/*
62862306a36Sopenharmony_ci		 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
62962306a36Sopenharmony_ci		 * in the field names in order to enter them into the namespace.
63062306a36Sopenharmony_ci		 */
63162306a36Sopenharmony_ci		if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
63262306a36Sopenharmony_ci			status = acpi_ns_lookup(walk_state->scope_info,
63362306a36Sopenharmony_ci						(char *)&arg->named.name, type,
63462306a36Sopenharmony_ci						ACPI_IMODE_LOAD_PASS1, flags,
63562306a36Sopenharmony_ci						walk_state, &node);
63662306a36Sopenharmony_ci			if (ACPI_FAILURE(status)) {
63762306a36Sopenharmony_ci				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
63862306a36Sopenharmony_ci						     (char *)&arg->named.name,
63962306a36Sopenharmony_ci						     status);
64062306a36Sopenharmony_ci				if (status != AE_ALREADY_EXISTS) {
64162306a36Sopenharmony_ci					return_ACPI_STATUS(status);
64262306a36Sopenharmony_ci				}
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci				/* Name already exists, just ignore this error */
64562306a36Sopenharmony_ci			}
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci			arg->common.node = node;
64862306a36Sopenharmony_ci		}
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci		/* Get the next field element in the list */
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci		arg = arg->common.next;
65362306a36Sopenharmony_ci	}
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci	return_ACPI_STATUS(AE_OK);
65662306a36Sopenharmony_ci}
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci/*******************************************************************************
65962306a36Sopenharmony_ci *
66062306a36Sopenharmony_ci * FUNCTION:    acpi_ds_create_bank_field
66162306a36Sopenharmony_ci *
66262306a36Sopenharmony_ci * PARAMETERS:  op              - Op containing the Field definition and args
66362306a36Sopenharmony_ci *              region_node     - Object for the containing Operation Region
66462306a36Sopenharmony_ci *              walk_state      - Current method state
66562306a36Sopenharmony_ci *
66662306a36Sopenharmony_ci * RETURN:      Status
66762306a36Sopenharmony_ci *
66862306a36Sopenharmony_ci * DESCRIPTION: Create a new bank field in the specified operation region
66962306a36Sopenharmony_ci *
67062306a36Sopenharmony_ci ******************************************************************************/
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ciacpi_status
67362306a36Sopenharmony_ciacpi_ds_create_bank_field(union acpi_parse_object *op,
67462306a36Sopenharmony_ci			  struct acpi_namespace_node *region_node,
67562306a36Sopenharmony_ci			  struct acpi_walk_state *walk_state)
67662306a36Sopenharmony_ci{
67762306a36Sopenharmony_ci	acpi_status status;
67862306a36Sopenharmony_ci	union acpi_parse_object *arg;
67962306a36Sopenharmony_ci	struct acpi_create_field_info info;
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci	/* First arg is the name of the parent op_region (must already exist) */
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_ci	arg = op->common.value.arg;
68662306a36Sopenharmony_ci	if (!region_node) {
68762306a36Sopenharmony_ci		status =
68862306a36Sopenharmony_ci		    acpi_ns_lookup(walk_state->scope_info,
68962306a36Sopenharmony_ci				   arg->common.value.name, ACPI_TYPE_REGION,
69062306a36Sopenharmony_ci				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
69162306a36Sopenharmony_ci				   walk_state, &region_node);
69262306a36Sopenharmony_ci#ifdef ACPI_ASL_COMPILER
69362306a36Sopenharmony_ci		status = acpi_ds_create_external_region(status, arg,
69462306a36Sopenharmony_ci							arg->common.value.name,
69562306a36Sopenharmony_ci							walk_state,
69662306a36Sopenharmony_ci							&region_node);
69762306a36Sopenharmony_ci#endif
69862306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
69962306a36Sopenharmony_ci			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
70062306a36Sopenharmony_ci					     arg->common.value.name, status);
70162306a36Sopenharmony_ci			return_ACPI_STATUS(status);
70262306a36Sopenharmony_ci		}
70362306a36Sopenharmony_ci	}
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci	/* Second arg is the Bank Register (Field) (must already exist) */
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci	arg = arg->common.next;
70862306a36Sopenharmony_ci	status =
70962306a36Sopenharmony_ci	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
71062306a36Sopenharmony_ci			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
71162306a36Sopenharmony_ci			   ACPI_NS_SEARCH_PARENT, walk_state,
71262306a36Sopenharmony_ci			   &info.register_node);
71362306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
71462306a36Sopenharmony_ci		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
71562306a36Sopenharmony_ci				     arg->common.value.string, status);
71662306a36Sopenharmony_ci		return_ACPI_STATUS(status);
71762306a36Sopenharmony_ci	}
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci	/*
72062306a36Sopenharmony_ci	 * Third arg is the bank_value
72162306a36Sopenharmony_ci	 * This arg is a term_arg, not a constant
72262306a36Sopenharmony_ci	 * It will be evaluated later, by acpi_ds_eval_bank_field_operands
72362306a36Sopenharmony_ci	 */
72462306a36Sopenharmony_ci	arg = arg->common.next;
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_ci	/* Fourth arg is the field flags */
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	arg = arg->common.next;
72962306a36Sopenharmony_ci	info.field_flags = (u8) arg->common.value.integer;
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	/* Each remaining arg is a Named Field */
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
73462306a36Sopenharmony_ci	info.region_node = region_node;
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci	/*
73762306a36Sopenharmony_ci	 * Use Info.data_register_node to store bank_field Op
73862306a36Sopenharmony_ci	 * It's safe because data_register_node will never be used when create
73962306a36Sopenharmony_ci	 * bank field \we store aml_start and aml_length in the bank_field Op for
74062306a36Sopenharmony_ci	 * late evaluation. Used in acpi_ex_prep_field_value(Info)
74162306a36Sopenharmony_ci	 *
74262306a36Sopenharmony_ci	 * TBD: Or, should we add a field in struct acpi_create_field_info, like
74362306a36Sopenharmony_ci	 * "void *ParentOp"?
74462306a36Sopenharmony_ci	 */
74562306a36Sopenharmony_ci	info.data_register_node = (struct acpi_namespace_node *)op;
74662306a36Sopenharmony_ci
74762306a36Sopenharmony_ci	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
74862306a36Sopenharmony_ci	return_ACPI_STATUS(status);
74962306a36Sopenharmony_ci}
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci/*******************************************************************************
75262306a36Sopenharmony_ci *
75362306a36Sopenharmony_ci * FUNCTION:    acpi_ds_create_index_field
75462306a36Sopenharmony_ci *
75562306a36Sopenharmony_ci * PARAMETERS:  op              - Op containing the Field definition and args
75662306a36Sopenharmony_ci *              region_node     - Object for the containing Operation Region
75762306a36Sopenharmony_ci *  `           walk_state      - Current method state
75862306a36Sopenharmony_ci *
75962306a36Sopenharmony_ci * RETURN:      Status
76062306a36Sopenharmony_ci *
76162306a36Sopenharmony_ci * DESCRIPTION: Create a new index field in the specified operation region
76262306a36Sopenharmony_ci *
76362306a36Sopenharmony_ci ******************************************************************************/
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ciacpi_status
76662306a36Sopenharmony_ciacpi_ds_create_index_field(union acpi_parse_object *op,
76762306a36Sopenharmony_ci			   struct acpi_namespace_node *region_node,
76862306a36Sopenharmony_ci			   struct acpi_walk_state *walk_state)
76962306a36Sopenharmony_ci{
77062306a36Sopenharmony_ci	acpi_status status;
77162306a36Sopenharmony_ci	union acpi_parse_object *arg;
77262306a36Sopenharmony_ci	struct acpi_create_field_info info;
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci	/* First arg is the name of the Index register (must already exist) */
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ci	arg = op->common.value.arg;
77962306a36Sopenharmony_ci	status =
78062306a36Sopenharmony_ci	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
78162306a36Sopenharmony_ci			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
78262306a36Sopenharmony_ci			   ACPI_NS_SEARCH_PARENT, walk_state,
78362306a36Sopenharmony_ci			   &info.register_node);
78462306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
78562306a36Sopenharmony_ci		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
78662306a36Sopenharmony_ci				     arg->common.value.string, status);
78762306a36Sopenharmony_ci		return_ACPI_STATUS(status);
78862306a36Sopenharmony_ci	}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci	/* Second arg is the data register (must already exist) */
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci	arg = arg->common.next;
79362306a36Sopenharmony_ci	status =
79462306a36Sopenharmony_ci	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
79562306a36Sopenharmony_ci			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
79662306a36Sopenharmony_ci			   ACPI_NS_SEARCH_PARENT, walk_state,
79762306a36Sopenharmony_ci			   &info.data_register_node);
79862306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
79962306a36Sopenharmony_ci		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
80062306a36Sopenharmony_ci				     arg->common.value.string, status);
80162306a36Sopenharmony_ci		return_ACPI_STATUS(status);
80262306a36Sopenharmony_ci	}
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	/* Next arg is the field flags */
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci	arg = arg->common.next;
80762306a36Sopenharmony_ci	info.field_flags = (u8) arg->common.value.integer;
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci	/* Each remaining arg is a Named Field */
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci	info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
81262306a36Sopenharmony_ci	info.region_node = region_node;
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
81562306a36Sopenharmony_ci	return_ACPI_STATUS(status);
81662306a36Sopenharmony_ci}
817