162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: psargs - Parse AML opcode arguments
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 "acparser.h"
1362306a36Sopenharmony_ci#include "amlcode.h"
1462306a36Sopenharmony_ci#include "acnamesp.h"
1562306a36Sopenharmony_ci#include "acdispat.h"
1662306a36Sopenharmony_ci#include "acconvert.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define _COMPONENT          ACPI_PARSER
1962306a36Sopenharmony_ciACPI_MODULE_NAME("psargs")
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/* Local prototypes */
2262306a36Sopenharmony_cistatic u32
2362306a36Sopenharmony_ciacpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistatic union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
2662306a36Sopenharmony_ci						       *parser_state);
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/*******************************************************************************
2962306a36Sopenharmony_ci *
3062306a36Sopenharmony_ci * FUNCTION:    acpi_ps_get_next_package_length
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci * PARAMETERS:  parser_state        - Current parser state object
3362306a36Sopenharmony_ci *
3462306a36Sopenharmony_ci * RETURN:      Decoded package length. On completion, the AML pointer points
3562306a36Sopenharmony_ci *              past the length byte or bytes.
3662306a36Sopenharmony_ci *
3762306a36Sopenharmony_ci * DESCRIPTION: Decode and return a package length field.
3862306a36Sopenharmony_ci *              Note: Largest package length is 28 bits, from ACPI specification
3962306a36Sopenharmony_ci *
4062306a36Sopenharmony_ci ******************************************************************************/
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic u32
4362306a36Sopenharmony_ciacpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
4462306a36Sopenharmony_ci{
4562306a36Sopenharmony_ci	u8 *aml = parser_state->aml;
4662306a36Sopenharmony_ci	u32 package_length = 0;
4762306a36Sopenharmony_ci	u32 byte_count;
4862306a36Sopenharmony_ci	u8 byte_zero_mask = 0x3F;	/* Default [0:5] */
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ps_get_next_package_length);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	/*
5362306a36Sopenharmony_ci	 * Byte 0 bits [6:7] contain the number of additional bytes
5462306a36Sopenharmony_ci	 * used to encode the package length, either 0,1,2, or 3
5562306a36Sopenharmony_ci	 */
5662306a36Sopenharmony_ci	byte_count = (aml[0] >> 6);
5762306a36Sopenharmony_ci	parser_state->aml += ((acpi_size)byte_count + 1);
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	/* Get bytes 3, 2, 1 as needed */
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	while (byte_count) {
6262306a36Sopenharmony_ci		/*
6362306a36Sopenharmony_ci		 * Final bit positions for the package length bytes:
6462306a36Sopenharmony_ci		 *      Byte3->[20:27]
6562306a36Sopenharmony_ci		 *      Byte2->[12:19]
6662306a36Sopenharmony_ci		 *      Byte1->[04:11]
6762306a36Sopenharmony_ci		 *      Byte0->[00:03]
6862306a36Sopenharmony_ci		 */
6962306a36Sopenharmony_ci		package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci		byte_zero_mask = 0x0F;	/* Use bits [0:3] of byte 0 */
7262306a36Sopenharmony_ci		byte_count--;
7362306a36Sopenharmony_ci	}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	/* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	package_length |= (aml[0] & byte_zero_mask);
7862306a36Sopenharmony_ci	return_UINT32(package_length);
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci/*******************************************************************************
8262306a36Sopenharmony_ci *
8362306a36Sopenharmony_ci * FUNCTION:    acpi_ps_get_next_package_end
8462306a36Sopenharmony_ci *
8562306a36Sopenharmony_ci * PARAMETERS:  parser_state        - Current parser state object
8662306a36Sopenharmony_ci *
8762306a36Sopenharmony_ci * RETURN:      Pointer to end-of-package +1
8862306a36Sopenharmony_ci *
8962306a36Sopenharmony_ci * DESCRIPTION: Get next package length and return a pointer past the end of
9062306a36Sopenharmony_ci *              the package. Consumes the package length field
9162306a36Sopenharmony_ci *
9262306a36Sopenharmony_ci ******************************************************************************/
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ciu8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
9562306a36Sopenharmony_ci{
9662306a36Sopenharmony_ci	u8 *start = parser_state->aml;
9762306a36Sopenharmony_ci	u32 package_length;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ps_get_next_package_end);
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	/* Function below updates parser_state->Aml */
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	package_length = acpi_ps_get_next_package_length(parser_state);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	return_PTR(start + package_length);	/* end of package */
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/*******************************************************************************
10962306a36Sopenharmony_ci *
11062306a36Sopenharmony_ci * FUNCTION:    acpi_ps_get_next_namestring
11162306a36Sopenharmony_ci *
11262306a36Sopenharmony_ci * PARAMETERS:  parser_state        - Current parser state object
11362306a36Sopenharmony_ci *
11462306a36Sopenharmony_ci * RETURN:      Pointer to the start of the name string (pointer points into
11562306a36Sopenharmony_ci *              the AML.
11662306a36Sopenharmony_ci *
11762306a36Sopenharmony_ci * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
11862306a36Sopenharmony_ci *              prefix characters. Set parser state to point past the string.
11962306a36Sopenharmony_ci *              (Name is consumed from the AML.)
12062306a36Sopenharmony_ci *
12162306a36Sopenharmony_ci ******************************************************************************/
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cichar *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	u8 *start = parser_state->aml;
12662306a36Sopenharmony_ci	u8 *end = parser_state->aml;
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ps_get_next_namestring);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	/* Point past any namestring prefix characters (backslash or carat) */
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) {
13362306a36Sopenharmony_ci		end++;
13462306a36Sopenharmony_ci	}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	/* Decode the path prefix character */
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	switch (*end) {
13962306a36Sopenharmony_ci	case 0:
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci		/* null_name */
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci		if (end == start) {
14462306a36Sopenharmony_ci			start = NULL;
14562306a36Sopenharmony_ci		}
14662306a36Sopenharmony_ci		end++;
14762306a36Sopenharmony_ci		break;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	case AML_DUAL_NAME_PREFIX:
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci		/* Two name segments */
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci		end += 1 + (2 * ACPI_NAMESEG_SIZE);
15462306a36Sopenharmony_ci		break;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	case AML_MULTI_NAME_PREFIX:
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci		/* Multiple name segments, 4 chars each, count in next byte */
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci		end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE);
16162306a36Sopenharmony_ci		break;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	default:
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci		/* Single name segment */
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci		end += ACPI_NAMESEG_SIZE;
16862306a36Sopenharmony_ci		break;
16962306a36Sopenharmony_ci	}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	parser_state->aml = end;
17262306a36Sopenharmony_ci	return_PTR((char *)start);
17362306a36Sopenharmony_ci}
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci/*******************************************************************************
17662306a36Sopenharmony_ci *
17762306a36Sopenharmony_ci * FUNCTION:    acpi_ps_get_next_namepath
17862306a36Sopenharmony_ci *
17962306a36Sopenharmony_ci * PARAMETERS:  parser_state        - Current parser state object
18062306a36Sopenharmony_ci *              arg                 - Where the namepath will be stored
18162306a36Sopenharmony_ci *              arg_count           - If the namepath points to a control method
18262306a36Sopenharmony_ci *                                    the method's argument is returned here.
18362306a36Sopenharmony_ci *              possible_method_call - Whether the namepath can possibly be the
18462306a36Sopenharmony_ci *                                    start of a method call
18562306a36Sopenharmony_ci *
18662306a36Sopenharmony_ci * RETURN:      Status
18762306a36Sopenharmony_ci *
18862306a36Sopenharmony_ci * DESCRIPTION: Get next name (if method call, return # of required args).
18962306a36Sopenharmony_ci *              Names are looked up in the internal namespace to determine
19062306a36Sopenharmony_ci *              if the name represents a control method. If a method
19162306a36Sopenharmony_ci *              is found, the number of arguments to the method is returned.
19262306a36Sopenharmony_ci *              This information is critical for parsing to continue correctly.
19362306a36Sopenharmony_ci *
19462306a36Sopenharmony_ci ******************************************************************************/
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ciacpi_status
19762306a36Sopenharmony_ciacpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
19862306a36Sopenharmony_ci			  struct acpi_parse_state *parser_state,
19962306a36Sopenharmony_ci			  union acpi_parse_object *arg, u8 possible_method_call)
20062306a36Sopenharmony_ci{
20162306a36Sopenharmony_ci	acpi_status status;
20262306a36Sopenharmony_ci	char *path;
20362306a36Sopenharmony_ci	union acpi_parse_object *name_op;
20462306a36Sopenharmony_ci	union acpi_operand_object *method_desc;
20562306a36Sopenharmony_ci	struct acpi_namespace_node *node;
20662306a36Sopenharmony_ci	u8 *start = parser_state->aml;
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ps_get_next_namepath);
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	path = acpi_ps_get_next_namestring(parser_state);
21162306a36Sopenharmony_ci	acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	/* Null path case is allowed, just exit */
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	if (!path) {
21662306a36Sopenharmony_ci		arg->common.value.name = path;
21762306a36Sopenharmony_ci		return_ACPI_STATUS(AE_OK);
21862306a36Sopenharmony_ci	}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	/*
22162306a36Sopenharmony_ci	 * Lookup the name in the internal namespace, starting with the current
22262306a36Sopenharmony_ci	 * scope. We don't want to add anything new to the namespace here,
22362306a36Sopenharmony_ci	 * however, so we use MODE_EXECUTE.
22462306a36Sopenharmony_ci	 * Allow searching of the parent tree, but don't open a new scope -
22562306a36Sopenharmony_ci	 * we just want to lookup the object (must be mode EXECUTE to perform
22662306a36Sopenharmony_ci	 * the upsearch)
22762306a36Sopenharmony_ci	 */
22862306a36Sopenharmony_ci	status = acpi_ns_lookup(walk_state->scope_info, path,
22962306a36Sopenharmony_ci				ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
23062306a36Sopenharmony_ci				ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
23162306a36Sopenharmony_ci				NULL, &node);
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	/*
23462306a36Sopenharmony_ci	 * If this name is a control method invocation, we must
23562306a36Sopenharmony_ci	 * setup the method call
23662306a36Sopenharmony_ci	 */
23762306a36Sopenharmony_ci	if (ACPI_SUCCESS(status) &&
23862306a36Sopenharmony_ci	    possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
23962306a36Sopenharmony_ci		if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
24062306a36Sopenharmony_ci		     ARGP_SUPERNAME)
24162306a36Sopenharmony_ci		    || (GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
24262306a36Sopenharmony_ci			ARGP_TARGET)) {
24362306a36Sopenharmony_ci			/*
24462306a36Sopenharmony_ci			 * acpi_ps_get_next_namestring has increased the AML pointer past
24562306a36Sopenharmony_ci			 * the method invocation namestring, so we need to restore the
24662306a36Sopenharmony_ci			 * saved AML pointer back to the original method invocation
24762306a36Sopenharmony_ci			 * namestring.
24862306a36Sopenharmony_ci			 */
24962306a36Sopenharmony_ci			walk_state->parser_state.aml = start;
25062306a36Sopenharmony_ci			walk_state->arg_count = 1;
25162306a36Sopenharmony_ci			acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
25262306a36Sopenharmony_ci		}
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci		/* This name is actually a control method invocation */
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci		method_desc = acpi_ns_get_attached_object(node);
25762306a36Sopenharmony_ci		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
25862306a36Sopenharmony_ci				  "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
25962306a36Sopenharmony_ci				  node->name.ascii, node, method_desc, path));
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci		name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start);
26262306a36Sopenharmony_ci		if (!name_op) {
26362306a36Sopenharmony_ci			return_ACPI_STATUS(AE_NO_MEMORY);
26462306a36Sopenharmony_ci		}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci		/* Change Arg into a METHOD CALL and attach name to it */
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci		acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
26962306a36Sopenharmony_ci		name_op->common.value.name = path;
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci		/* Point METHODCALL/NAME to the METHOD Node */
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci		name_op->common.node = node;
27462306a36Sopenharmony_ci		acpi_ps_append_arg(arg, name_op);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci		if (!method_desc) {
27762306a36Sopenharmony_ci			ACPI_ERROR((AE_INFO,
27862306a36Sopenharmony_ci				    "Control Method %p has no attached object",
27962306a36Sopenharmony_ci				    node));
28062306a36Sopenharmony_ci			return_ACPI_STATUS(AE_AML_INTERNAL);
28162306a36Sopenharmony_ci		}
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
28462306a36Sopenharmony_ci				  "Control Method - %p Args %X\n",
28562306a36Sopenharmony_ci				  node, method_desc->method.param_count));
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci		/* Get the number of arguments to expect */
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci		walk_state->arg_count = method_desc->method.param_count;
29062306a36Sopenharmony_ci		return_ACPI_STATUS(AE_OK);
29162306a36Sopenharmony_ci	}
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	/*
29462306a36Sopenharmony_ci	 * Special handling if the name was not found during the lookup -
29562306a36Sopenharmony_ci	 * some not_found cases are allowed
29662306a36Sopenharmony_ci	 */
29762306a36Sopenharmony_ci	if (status == AE_NOT_FOUND) {
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci		/* 1) not_found is ok during load pass 1/2 (allow forward references) */
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
30262306a36Sopenharmony_ci		    ACPI_PARSE_EXECUTE) {
30362306a36Sopenharmony_ci			status = AE_OK;
30462306a36Sopenharmony_ci		}
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci		/* 2) not_found during a cond_ref_of(x) is ok by definition */
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci		else if (walk_state->op->common.aml_opcode ==
30962306a36Sopenharmony_ci			 AML_CONDITIONAL_REF_OF_OP) {
31062306a36Sopenharmony_ci			status = AE_OK;
31162306a36Sopenharmony_ci		}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci		/*
31462306a36Sopenharmony_ci		 * 3) not_found while building a Package is ok at this point, we
31562306a36Sopenharmony_ci		 * may flag as an error later if slack mode is not enabled.
31662306a36Sopenharmony_ci		 * (Some ASL code depends on allowing this behavior)
31762306a36Sopenharmony_ci		 */
31862306a36Sopenharmony_ci		else if ((arg->common.parent) &&
31962306a36Sopenharmony_ci			 ((arg->common.parent->common.aml_opcode ==
32062306a36Sopenharmony_ci			   AML_PACKAGE_OP)
32162306a36Sopenharmony_ci			  || (arg->common.parent->common.aml_opcode ==
32262306a36Sopenharmony_ci			      AML_VARIABLE_PACKAGE_OP))) {
32362306a36Sopenharmony_ci			status = AE_OK;
32462306a36Sopenharmony_ci		}
32562306a36Sopenharmony_ci	}
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	/* Final exception check (may have been changed from code above) */
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
33062306a36Sopenharmony_ci		ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status);
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
33362306a36Sopenharmony_ci		    ACPI_PARSE_EXECUTE) {
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci			/* Report a control method execution error */
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci			status = acpi_ds_method_error(status, walk_state);
33862306a36Sopenharmony_ci		}
33962306a36Sopenharmony_ci	}
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci	/* Save the namepath */
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	arg->common.value.name = path;
34462306a36Sopenharmony_ci	return_ACPI_STATUS(status);
34562306a36Sopenharmony_ci}
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci/*******************************************************************************
34862306a36Sopenharmony_ci *
34962306a36Sopenharmony_ci * FUNCTION:    acpi_ps_get_next_simple_arg
35062306a36Sopenharmony_ci *
35162306a36Sopenharmony_ci * PARAMETERS:  parser_state        - Current parser state object
35262306a36Sopenharmony_ci *              arg_type            - The argument type (AML_*_ARG)
35362306a36Sopenharmony_ci *              arg                 - Where the argument is returned
35462306a36Sopenharmony_ci *
35562306a36Sopenharmony_ci * RETURN:      None
35662306a36Sopenharmony_ci *
35762306a36Sopenharmony_ci * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
35862306a36Sopenharmony_ci *
35962306a36Sopenharmony_ci ******************************************************************************/
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_civoid
36262306a36Sopenharmony_ciacpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
36362306a36Sopenharmony_ci			    u32 arg_type, union acpi_parse_object *arg)
36462306a36Sopenharmony_ci{
36562306a36Sopenharmony_ci	u32 length;
36662306a36Sopenharmony_ci	u16 opcode;
36762306a36Sopenharmony_ci	u8 *aml = parser_state->aml;
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	switch (arg_type) {
37262306a36Sopenharmony_ci	case ARGP_BYTEDATA:
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci		/* Get 1 byte from the AML stream */
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci		opcode = AML_BYTE_OP;
37762306a36Sopenharmony_ci		arg->common.value.integer = (u64) *aml;
37862306a36Sopenharmony_ci		length = 1;
37962306a36Sopenharmony_ci		break;
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	case ARGP_WORDDATA:
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci		/* Get 2 bytes from the AML stream */
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci		opcode = AML_WORD_OP;
38662306a36Sopenharmony_ci		ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
38762306a36Sopenharmony_ci		length = 2;
38862306a36Sopenharmony_ci		break;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	case ARGP_DWORDDATA:
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci		/* Get 4 bytes from the AML stream */
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci		opcode = AML_DWORD_OP;
39562306a36Sopenharmony_ci		ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
39662306a36Sopenharmony_ci		length = 4;
39762306a36Sopenharmony_ci		break;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	case ARGP_QWORDDATA:
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci		/* Get 8 bytes from the AML stream */
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci		opcode = AML_QWORD_OP;
40462306a36Sopenharmony_ci		ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
40562306a36Sopenharmony_ci		length = 8;
40662306a36Sopenharmony_ci		break;
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci	case ARGP_CHARLIST:
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci		/* Get a pointer to the string, point past the string */
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci		opcode = AML_STRING_OP;
41362306a36Sopenharmony_ci		arg->common.value.string = ACPI_CAST_PTR(char, aml);
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci		/* Find the null terminator */
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci		length = 0;
41862306a36Sopenharmony_ci		while (aml[length]) {
41962306a36Sopenharmony_ci			length++;
42062306a36Sopenharmony_ci		}
42162306a36Sopenharmony_ci		length++;
42262306a36Sopenharmony_ci		break;
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci	case ARGP_NAME:
42562306a36Sopenharmony_ci	case ARGP_NAMESTRING:
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci		acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
42862306a36Sopenharmony_ci		arg->common.value.name =
42962306a36Sopenharmony_ci		    acpi_ps_get_next_namestring(parser_state);
43062306a36Sopenharmony_ci		return_VOID;
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci	default:
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci		ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type));
43562306a36Sopenharmony_ci		return_VOID;
43662306a36Sopenharmony_ci	}
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	acpi_ps_init_op(arg, opcode);
43962306a36Sopenharmony_ci	parser_state->aml += length;
44062306a36Sopenharmony_ci	return_VOID;
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci/*******************************************************************************
44462306a36Sopenharmony_ci *
44562306a36Sopenharmony_ci * FUNCTION:    acpi_ps_get_next_field
44662306a36Sopenharmony_ci *
44762306a36Sopenharmony_ci * PARAMETERS:  parser_state        - Current parser state object
44862306a36Sopenharmony_ci *
44962306a36Sopenharmony_ci * RETURN:      A newly allocated FIELD op
45062306a36Sopenharmony_ci *
45162306a36Sopenharmony_ci * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
45262306a36Sopenharmony_ci *
45362306a36Sopenharmony_ci ******************************************************************************/
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_cistatic union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
45662306a36Sopenharmony_ci						       *parser_state)
45762306a36Sopenharmony_ci{
45862306a36Sopenharmony_ci	u8 *aml;
45962306a36Sopenharmony_ci	union acpi_parse_object *field;
46062306a36Sopenharmony_ci	union acpi_parse_object *arg = NULL;
46162306a36Sopenharmony_ci	u16 opcode;
46262306a36Sopenharmony_ci	u32 name;
46362306a36Sopenharmony_ci	u8 access_type;
46462306a36Sopenharmony_ci	u8 access_attribute;
46562306a36Sopenharmony_ci	u8 access_length;
46662306a36Sopenharmony_ci	u32 pkg_length;
46762306a36Sopenharmony_ci	u8 *pkg_end;
46862306a36Sopenharmony_ci	u32 buffer_length;
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ps_get_next_field);
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
47362306a36Sopenharmony_ci	aml = parser_state->aml;
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci	/* Determine field type */
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci	switch (ACPI_GET8(parser_state->aml)) {
47862306a36Sopenharmony_ci	case AML_FIELD_OFFSET_OP:
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci		opcode = AML_INT_RESERVEDFIELD_OP;
48162306a36Sopenharmony_ci		parser_state->aml++;
48262306a36Sopenharmony_ci		break;
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	case AML_FIELD_ACCESS_OP:
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci		opcode = AML_INT_ACCESSFIELD_OP;
48762306a36Sopenharmony_ci		parser_state->aml++;
48862306a36Sopenharmony_ci		break;
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci	case AML_FIELD_CONNECTION_OP:
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci		opcode = AML_INT_CONNECTION_OP;
49362306a36Sopenharmony_ci		parser_state->aml++;
49462306a36Sopenharmony_ci		break;
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci	case AML_FIELD_EXT_ACCESS_OP:
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci		opcode = AML_INT_EXTACCESSFIELD_OP;
49962306a36Sopenharmony_ci		parser_state->aml++;
50062306a36Sopenharmony_ci		break;
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	default:
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci		opcode = AML_INT_NAMEDFIELD_OP;
50562306a36Sopenharmony_ci		break;
50662306a36Sopenharmony_ci	}
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	/* Allocate a new field op */
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci	field = acpi_ps_alloc_op(opcode, aml);
51162306a36Sopenharmony_ci	if (!field) {
51262306a36Sopenharmony_ci		return_PTR(NULL);
51362306a36Sopenharmony_ci	}
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci	/* Decode the field type */
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
51862306a36Sopenharmony_ci	switch (opcode) {
51962306a36Sopenharmony_ci	case AML_INT_NAMEDFIELD_OP:
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci		/* Get the 4-character name */
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci		ACPI_MOVE_32_TO_32(&name, parser_state->aml);
52462306a36Sopenharmony_ci		acpi_ps_set_name(field, name);
52562306a36Sopenharmony_ci		parser_state->aml += ACPI_NAMESEG_SIZE;
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci		ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci#ifdef ACPI_ASL_COMPILER
53062306a36Sopenharmony_ci		/*
53162306a36Sopenharmony_ci		 * Because the package length isn't represented as a parse tree object,
53262306a36Sopenharmony_ci		 * take comments surrounding this and add to the previously created
53362306a36Sopenharmony_ci		 * parse node.
53462306a36Sopenharmony_ci		 */
53562306a36Sopenharmony_ci		if (field->common.inline_comment) {
53662306a36Sopenharmony_ci			field->common.name_comment =
53762306a36Sopenharmony_ci			    field->common.inline_comment;
53862306a36Sopenharmony_ci		}
53962306a36Sopenharmony_ci		field->common.inline_comment = acpi_gbl_current_inline_comment;
54062306a36Sopenharmony_ci		acpi_gbl_current_inline_comment = NULL;
54162306a36Sopenharmony_ci#endif
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci		/* Get the length which is encoded as a package length */
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci		field->common.value.size =
54662306a36Sopenharmony_ci		    acpi_ps_get_next_package_length(parser_state);
54762306a36Sopenharmony_ci		break;
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	case AML_INT_RESERVEDFIELD_OP:
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci		/* Get the length which is encoded as a package length */
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci		field->common.value.size =
55462306a36Sopenharmony_ci		    acpi_ps_get_next_package_length(parser_state);
55562306a36Sopenharmony_ci		break;
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	case AML_INT_ACCESSFIELD_OP:
55862306a36Sopenharmony_ci	case AML_INT_EXTACCESSFIELD_OP:
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci		/*
56162306a36Sopenharmony_ci		 * Get access_type and access_attrib and merge into the field Op
56262306a36Sopenharmony_ci		 * access_type is first operand, access_attribute is second. stuff
56362306a36Sopenharmony_ci		 * these bytes into the node integer value for convenience.
56462306a36Sopenharmony_ci		 */
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ci		/* Get the two bytes (Type/Attribute) */
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci		access_type = ACPI_GET8(parser_state->aml);
56962306a36Sopenharmony_ci		parser_state->aml++;
57062306a36Sopenharmony_ci		access_attribute = ACPI_GET8(parser_state->aml);
57162306a36Sopenharmony_ci		parser_state->aml++;
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci		field->common.value.integer = (u8)access_type;
57462306a36Sopenharmony_ci		field->common.value.integer |= (u16)(access_attribute << 8);
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci		/* This opcode has a third byte, access_length */
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci		if (opcode == AML_INT_EXTACCESSFIELD_OP) {
57962306a36Sopenharmony_ci			access_length = ACPI_GET8(parser_state->aml);
58062306a36Sopenharmony_ci			parser_state->aml++;
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci			field->common.value.integer |=
58362306a36Sopenharmony_ci			    (u32)(access_length << 16);
58462306a36Sopenharmony_ci		}
58562306a36Sopenharmony_ci		break;
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci	case AML_INT_CONNECTION_OP:
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci		/*
59062306a36Sopenharmony_ci		 * Argument for Connection operator can be either a Buffer
59162306a36Sopenharmony_ci		 * (resource descriptor), or a name_string.
59262306a36Sopenharmony_ci		 */
59362306a36Sopenharmony_ci		aml = parser_state->aml;
59462306a36Sopenharmony_ci		if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
59562306a36Sopenharmony_ci			parser_state->aml++;
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci			ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
59862306a36Sopenharmony_ci			pkg_end = parser_state->aml;
59962306a36Sopenharmony_ci			pkg_length =
60062306a36Sopenharmony_ci			    acpi_ps_get_next_package_length(parser_state);
60162306a36Sopenharmony_ci			pkg_end += pkg_length;
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci			ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
60462306a36Sopenharmony_ci			if (parser_state->aml < pkg_end) {
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci				/* Non-empty list */
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci				arg =
60962306a36Sopenharmony_ci				    acpi_ps_alloc_op(AML_INT_BYTELIST_OP, aml);
61062306a36Sopenharmony_ci				if (!arg) {
61162306a36Sopenharmony_ci					acpi_ps_free_op(field);
61262306a36Sopenharmony_ci					return_PTR(NULL);
61362306a36Sopenharmony_ci				}
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci				/* Get the actual buffer length argument */
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci				opcode = ACPI_GET8(parser_state->aml);
61862306a36Sopenharmony_ci				parser_state->aml++;
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci				ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
62162306a36Sopenharmony_ci				switch (opcode) {
62262306a36Sopenharmony_ci				case AML_BYTE_OP:	/* AML_BYTEDATA_ARG */
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci					buffer_length =
62562306a36Sopenharmony_ci					    ACPI_GET8(parser_state->aml);
62662306a36Sopenharmony_ci					parser_state->aml += 1;
62762306a36Sopenharmony_ci					break;
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci				case AML_WORD_OP:	/* AML_WORDDATA_ARG */
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci					buffer_length =
63262306a36Sopenharmony_ci					    ACPI_GET16(parser_state->aml);
63362306a36Sopenharmony_ci					parser_state->aml += 2;
63462306a36Sopenharmony_ci					break;
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci				case AML_DWORD_OP:	/* AML_DWORDATA_ARG */
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci					buffer_length =
63962306a36Sopenharmony_ci					    ACPI_GET32(parser_state->aml);
64062306a36Sopenharmony_ci					parser_state->aml += 4;
64162306a36Sopenharmony_ci					break;
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci				default:
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci					buffer_length = 0;
64662306a36Sopenharmony_ci					break;
64762306a36Sopenharmony_ci				}
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci				/* Fill in bytelist data */
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci				ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
65262306a36Sopenharmony_ci				arg->named.value.size = buffer_length;
65362306a36Sopenharmony_ci				arg->named.data = parser_state->aml;
65462306a36Sopenharmony_ci			}
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci			/* Skip to End of byte data */
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci			parser_state->aml = pkg_end;
65962306a36Sopenharmony_ci		} else {
66062306a36Sopenharmony_ci			arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, aml);
66162306a36Sopenharmony_ci			if (!arg) {
66262306a36Sopenharmony_ci				acpi_ps_free_op(field);
66362306a36Sopenharmony_ci				return_PTR(NULL);
66462306a36Sopenharmony_ci			}
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_ci			/* Get the Namestring argument */
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci			arg->common.value.name =
66962306a36Sopenharmony_ci			    acpi_ps_get_next_namestring(parser_state);
67062306a36Sopenharmony_ci		}
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci		/* Link the buffer/namestring to parent (CONNECTION_OP) */
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci		acpi_ps_append_arg(field, arg);
67562306a36Sopenharmony_ci		break;
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci	default:
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci		/* Opcode was set in previous switch */
68062306a36Sopenharmony_ci		break;
68162306a36Sopenharmony_ci	}
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci	return_PTR(field);
68462306a36Sopenharmony_ci}
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci/*******************************************************************************
68762306a36Sopenharmony_ci *
68862306a36Sopenharmony_ci * FUNCTION:    acpi_ps_get_next_arg
68962306a36Sopenharmony_ci *
69062306a36Sopenharmony_ci * PARAMETERS:  walk_state          - Current state
69162306a36Sopenharmony_ci *              parser_state        - Current parser state object
69262306a36Sopenharmony_ci *              arg_type            - The argument type (AML_*_ARG)
69362306a36Sopenharmony_ci *              return_arg          - Where the next arg is returned
69462306a36Sopenharmony_ci *
69562306a36Sopenharmony_ci * RETURN:      Status, and an op object containing the next argument.
69662306a36Sopenharmony_ci *
69762306a36Sopenharmony_ci * DESCRIPTION: Get next argument (including complex list arguments that require
69862306a36Sopenharmony_ci *              pushing the parser stack)
69962306a36Sopenharmony_ci *
70062306a36Sopenharmony_ci ******************************************************************************/
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ciacpi_status
70362306a36Sopenharmony_ciacpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
70462306a36Sopenharmony_ci		     struct acpi_parse_state *parser_state,
70562306a36Sopenharmony_ci		     u32 arg_type, union acpi_parse_object **return_arg)
70662306a36Sopenharmony_ci{
70762306a36Sopenharmony_ci	union acpi_parse_object *arg = NULL;
70862306a36Sopenharmony_ci	union acpi_parse_object *prev = NULL;
70962306a36Sopenharmony_ci	union acpi_parse_object *field;
71062306a36Sopenharmony_ci	u32 subop;
71162306a36Sopenharmony_ci	acpi_status status = AE_OK;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
71662306a36Sopenharmony_ci			  "Expected argument type ARGP: %s (%2.2X)\n",
71762306a36Sopenharmony_ci			  acpi_ut_get_argument_type_name(arg_type), arg_type));
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci	switch (arg_type) {
72062306a36Sopenharmony_ci	case ARGP_BYTEDATA:
72162306a36Sopenharmony_ci	case ARGP_WORDDATA:
72262306a36Sopenharmony_ci	case ARGP_DWORDDATA:
72362306a36Sopenharmony_ci	case ARGP_CHARLIST:
72462306a36Sopenharmony_ci	case ARGP_NAME:
72562306a36Sopenharmony_ci	case ARGP_NAMESTRING:
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci		/* Constants, strings, and namestrings are all the same size */
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci		arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml);
73062306a36Sopenharmony_ci		if (!arg) {
73162306a36Sopenharmony_ci			return_ACPI_STATUS(AE_NO_MEMORY);
73262306a36Sopenharmony_ci		}
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci		acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
73562306a36Sopenharmony_ci		break;
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	case ARGP_PKGLENGTH:
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci		/* Package length, nothing returned */
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci		parser_state->pkg_end =
74262306a36Sopenharmony_ci		    acpi_ps_get_next_package_end(parser_state);
74362306a36Sopenharmony_ci		break;
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci	case ARGP_FIELDLIST:
74662306a36Sopenharmony_ci
74762306a36Sopenharmony_ci		if (parser_state->aml < parser_state->pkg_end) {
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci			/* Non-empty list */
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci			while (parser_state->aml < parser_state->pkg_end) {
75262306a36Sopenharmony_ci				field = acpi_ps_get_next_field(parser_state);
75362306a36Sopenharmony_ci				if (!field) {
75462306a36Sopenharmony_ci					return_ACPI_STATUS(AE_NO_MEMORY);
75562306a36Sopenharmony_ci				}
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci				if (prev) {
75862306a36Sopenharmony_ci					prev->common.next = field;
75962306a36Sopenharmony_ci				} else {
76062306a36Sopenharmony_ci					arg = field;
76162306a36Sopenharmony_ci				}
76262306a36Sopenharmony_ci				prev = field;
76362306a36Sopenharmony_ci			}
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci			/* Skip to End of byte data */
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci			parser_state->aml = parser_state->pkg_end;
76862306a36Sopenharmony_ci		}
76962306a36Sopenharmony_ci		break;
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci	case ARGP_BYTELIST:
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ci		if (parser_state->aml < parser_state->pkg_end) {
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci			/* Non-empty list */
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci			arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP,
77862306a36Sopenharmony_ci					       parser_state->aml);
77962306a36Sopenharmony_ci			if (!arg) {
78062306a36Sopenharmony_ci				return_ACPI_STATUS(AE_NO_MEMORY);
78162306a36Sopenharmony_ci			}
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ci			/* Fill in bytelist data */
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci			arg->common.value.size = (u32)
78662306a36Sopenharmony_ci			    ACPI_PTR_DIFF(parser_state->pkg_end,
78762306a36Sopenharmony_ci					  parser_state->aml);
78862306a36Sopenharmony_ci			arg->named.data = parser_state->aml;
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci			/* Skip to End of byte data */
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci			parser_state->aml = parser_state->pkg_end;
79362306a36Sopenharmony_ci		}
79462306a36Sopenharmony_ci		break;
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	case ARGP_SIMPLENAME:
79762306a36Sopenharmony_ci	case ARGP_NAME_OR_REF:
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
80062306a36Sopenharmony_ci				  "**** SimpleName/NameOrRef: %s (%2.2X)\n",
80162306a36Sopenharmony_ci				  acpi_ut_get_argument_type_name(arg_type),
80262306a36Sopenharmony_ci				  arg_type));
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci		subop = acpi_ps_peek_opcode(parser_state);
80562306a36Sopenharmony_ci		if (subop == 0 ||
80662306a36Sopenharmony_ci		    acpi_ps_is_leading_char(subop) ||
80762306a36Sopenharmony_ci		    ACPI_IS_ROOT_PREFIX(subop) ||
80862306a36Sopenharmony_ci		    ACPI_IS_PARENT_PREFIX(subop)) {
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci			/* null_name or name_string */
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci			arg =
81362306a36Sopenharmony_ci			    acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
81462306a36Sopenharmony_ci					     parser_state->aml);
81562306a36Sopenharmony_ci			if (!arg) {
81662306a36Sopenharmony_ci				return_ACPI_STATUS(AE_NO_MEMORY);
81762306a36Sopenharmony_ci			}
81862306a36Sopenharmony_ci
81962306a36Sopenharmony_ci			status =
82062306a36Sopenharmony_ci			    acpi_ps_get_next_namepath(walk_state, parser_state,
82162306a36Sopenharmony_ci						      arg,
82262306a36Sopenharmony_ci						      ACPI_NOT_METHOD_CALL);
82362306a36Sopenharmony_ci		} else {
82462306a36Sopenharmony_ci			/* Single complex argument, nothing returned */
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci			walk_state->arg_count = 1;
82762306a36Sopenharmony_ci		}
82862306a36Sopenharmony_ci		break;
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	case ARGP_TARGET:
83162306a36Sopenharmony_ci	case ARGP_SUPERNAME:
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
83462306a36Sopenharmony_ci				  "**** Target/Supername: %s (%2.2X)\n",
83562306a36Sopenharmony_ci				  acpi_ut_get_argument_type_name(arg_type),
83662306a36Sopenharmony_ci				  arg_type));
83762306a36Sopenharmony_ci
83862306a36Sopenharmony_ci		subop = acpi_ps_peek_opcode(parser_state);
83962306a36Sopenharmony_ci		if (subop == 0 ||
84062306a36Sopenharmony_ci		    acpi_ps_is_leading_char(subop) ||
84162306a36Sopenharmony_ci		    ACPI_IS_ROOT_PREFIX(subop) ||
84262306a36Sopenharmony_ci		    ACPI_IS_PARENT_PREFIX(subop)) {
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci			/* NULL target (zero). Convert to a NULL namepath */
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ci			arg =
84762306a36Sopenharmony_ci			    acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
84862306a36Sopenharmony_ci					     parser_state->aml);
84962306a36Sopenharmony_ci			if (!arg) {
85062306a36Sopenharmony_ci				return_ACPI_STATUS(AE_NO_MEMORY);
85162306a36Sopenharmony_ci			}
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci			status =
85462306a36Sopenharmony_ci			    acpi_ps_get_next_namepath(walk_state, parser_state,
85562306a36Sopenharmony_ci						      arg,
85662306a36Sopenharmony_ci						      ACPI_POSSIBLE_METHOD_CALL);
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci			if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci				/* Free method call op and corresponding namestring sub-ob */
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci				acpi_ps_free_op(arg->common.value.arg);
86362306a36Sopenharmony_ci				acpi_ps_free_op(arg);
86462306a36Sopenharmony_ci				arg = NULL;
86562306a36Sopenharmony_ci				walk_state->arg_count = 1;
86662306a36Sopenharmony_ci			}
86762306a36Sopenharmony_ci		} else {
86862306a36Sopenharmony_ci			/* Single complex argument, nothing returned */
86962306a36Sopenharmony_ci
87062306a36Sopenharmony_ci			walk_state->arg_count = 1;
87162306a36Sopenharmony_ci		}
87262306a36Sopenharmony_ci		break;
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci	case ARGP_DATAOBJ:
87562306a36Sopenharmony_ci	case ARGP_TERMARG:
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
87862306a36Sopenharmony_ci				  "**** TermArg/DataObj: %s (%2.2X)\n",
87962306a36Sopenharmony_ci				  acpi_ut_get_argument_type_name(arg_type),
88062306a36Sopenharmony_ci				  arg_type));
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci		/* Single complex argument, nothing returned */
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ci		walk_state->arg_count = 1;
88562306a36Sopenharmony_ci		break;
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci	case ARGP_DATAOBJLIST:
88862306a36Sopenharmony_ci	case ARGP_TERMLIST:
88962306a36Sopenharmony_ci	case ARGP_OBJLIST:
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci		if (parser_state->aml < parser_state->pkg_end) {
89262306a36Sopenharmony_ci
89362306a36Sopenharmony_ci			/* Non-empty list of variable arguments, nothing returned */
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci			walk_state->arg_count = ACPI_VAR_ARGS;
89662306a36Sopenharmony_ci		}
89762306a36Sopenharmony_ci		break;
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci	default:
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci		ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type));
90262306a36Sopenharmony_ci		status = AE_AML_OPERAND_TYPE;
90362306a36Sopenharmony_ci		break;
90462306a36Sopenharmony_ci	}
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_ci	*return_arg = arg;
90762306a36Sopenharmony_ci	return_ACPI_STATUS(status);
90862306a36Sopenharmony_ci}
909