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

psargs.c (22686B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: psargs - Parse AML opcode arguments
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "acparser.h"
     13#include "amlcode.h"
     14#include "acnamesp.h"
     15#include "acdispat.h"
     16#include "acconvert.h"
     17
     18#define _COMPONENT          ACPI_PARSER
     19ACPI_MODULE_NAME("psargs")
     20
     21/* Local prototypes */
     22static u32
     23acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
     24
     25static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
     26						       *parser_state);
     27
     28/*******************************************************************************
     29 *
     30 * FUNCTION:    acpi_ps_get_next_package_length
     31 *
     32 * PARAMETERS:  parser_state        - Current parser state object
     33 *
     34 * RETURN:      Decoded package length. On completion, the AML pointer points
     35 *              past the length byte or bytes.
     36 *
     37 * DESCRIPTION: Decode and return a package length field.
     38 *              Note: Largest package length is 28 bits, from ACPI specification
     39 *
     40 ******************************************************************************/
     41
     42static u32
     43acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
     44{
     45	u8 *aml = parser_state->aml;
     46	u32 package_length = 0;
     47	u32 byte_count;
     48	u8 byte_zero_mask = 0x3F;	/* Default [0:5] */
     49
     50	ACPI_FUNCTION_TRACE(ps_get_next_package_length);
     51
     52	/*
     53	 * Byte 0 bits [6:7] contain the number of additional bytes
     54	 * used to encode the package length, either 0,1,2, or 3
     55	 */
     56	byte_count = (aml[0] >> 6);
     57	parser_state->aml += ((acpi_size)byte_count + 1);
     58
     59	/* Get bytes 3, 2, 1 as needed */
     60
     61	while (byte_count) {
     62		/*
     63		 * Final bit positions for the package length bytes:
     64		 *      Byte3->[20:27]
     65		 *      Byte2->[12:19]
     66		 *      Byte1->[04:11]
     67		 *      Byte0->[00:03]
     68		 */
     69		package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
     70
     71		byte_zero_mask = 0x0F;	/* Use bits [0:3] of byte 0 */
     72		byte_count--;
     73	}
     74
     75	/* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
     76
     77	package_length |= (aml[0] & byte_zero_mask);
     78	return_UINT32(package_length);
     79}
     80
     81/*******************************************************************************
     82 *
     83 * FUNCTION:    acpi_ps_get_next_package_end
     84 *
     85 * PARAMETERS:  parser_state        - Current parser state object
     86 *
     87 * RETURN:      Pointer to end-of-package +1
     88 *
     89 * DESCRIPTION: Get next package length and return a pointer past the end of
     90 *              the package. Consumes the package length field
     91 *
     92 ******************************************************************************/
     93
     94u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
     95{
     96	u8 *start = parser_state->aml;
     97	u32 package_length;
     98
     99	ACPI_FUNCTION_TRACE(ps_get_next_package_end);
    100
    101	/* Function below updates parser_state->Aml */
    102
    103	package_length = acpi_ps_get_next_package_length(parser_state);
    104
    105	return_PTR(start + package_length);	/* end of package */
    106}
    107
    108/*******************************************************************************
    109 *
    110 * FUNCTION:    acpi_ps_get_next_namestring
    111 *
    112 * PARAMETERS:  parser_state        - Current parser state object
    113 *
    114 * RETURN:      Pointer to the start of the name string (pointer points into
    115 *              the AML.
    116 *
    117 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
    118 *              prefix characters. Set parser state to point past the string.
    119 *              (Name is consumed from the AML.)
    120 *
    121 ******************************************************************************/
    122
    123char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
    124{
    125	u8 *start = parser_state->aml;
    126	u8 *end = parser_state->aml;
    127
    128	ACPI_FUNCTION_TRACE(ps_get_next_namestring);
    129
    130	/* Point past any namestring prefix characters (backslash or carat) */
    131
    132	while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) {
    133		end++;
    134	}
    135
    136	/* Decode the path prefix character */
    137
    138	switch (*end) {
    139	case 0:
    140
    141		/* null_name */
    142
    143		if (end == start) {
    144			start = NULL;
    145		}
    146		end++;
    147		break;
    148
    149	case AML_DUAL_NAME_PREFIX:
    150
    151		/* Two name segments */
    152
    153		end += 1 + (2 * ACPI_NAMESEG_SIZE);
    154		break;
    155
    156	case AML_MULTI_NAME_PREFIX:
    157
    158		/* Multiple name segments, 4 chars each, count in next byte */
    159
    160		end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE);
    161		break;
    162
    163	default:
    164
    165		/* Single name segment */
    166
    167		end += ACPI_NAMESEG_SIZE;
    168		break;
    169	}
    170
    171	parser_state->aml = end;
    172	return_PTR((char *)start);
    173}
    174
    175/*******************************************************************************
    176 *
    177 * FUNCTION:    acpi_ps_get_next_namepath
    178 *
    179 * PARAMETERS:  parser_state        - Current parser state object
    180 *              arg                 - Where the namepath will be stored
    181 *              arg_count           - If the namepath points to a control method
    182 *                                    the method's argument is returned here.
    183 *              possible_method_call - Whether the namepath can possibly be the
    184 *                                    start of a method call
    185 *
    186 * RETURN:      Status
    187 *
    188 * DESCRIPTION: Get next name (if method call, return # of required args).
    189 *              Names are looked up in the internal namespace to determine
    190 *              if the name represents a control method. If a method
    191 *              is found, the number of arguments to the method is returned.
    192 *              This information is critical for parsing to continue correctly.
    193 *
    194 ******************************************************************************/
    195
    196acpi_status
    197acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
    198			  struct acpi_parse_state *parser_state,
    199			  union acpi_parse_object *arg, u8 possible_method_call)
    200{
    201	acpi_status status;
    202	char *path;
    203	union acpi_parse_object *name_op;
    204	union acpi_operand_object *method_desc;
    205	struct acpi_namespace_node *node;
    206	u8 *start = parser_state->aml;
    207
    208	ACPI_FUNCTION_TRACE(ps_get_next_namepath);
    209
    210	path = acpi_ps_get_next_namestring(parser_state);
    211	acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
    212
    213	/* Null path case is allowed, just exit */
    214
    215	if (!path) {
    216		arg->common.value.name = path;
    217		return_ACPI_STATUS(AE_OK);
    218	}
    219
    220	/*
    221	 * Lookup the name in the internal namespace, starting with the current
    222	 * scope. We don't want to add anything new to the namespace here,
    223	 * however, so we use MODE_EXECUTE.
    224	 * Allow searching of the parent tree, but don't open a new scope -
    225	 * we just want to lookup the object (must be mode EXECUTE to perform
    226	 * the upsearch)
    227	 */
    228	status = acpi_ns_lookup(walk_state->scope_info, path,
    229				ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
    230				ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
    231				NULL, &node);
    232
    233	/*
    234	 * If this name is a control method invocation, we must
    235	 * setup the method call
    236	 */
    237	if (ACPI_SUCCESS(status) &&
    238	    possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
    239		if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
    240		     ARGP_SUPERNAME)
    241		    || (GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
    242			ARGP_TARGET)) {
    243			/*
    244			 * acpi_ps_get_next_namestring has increased the AML pointer past
    245			 * the method invocation namestring, so we need to restore the
    246			 * saved AML pointer back to the original method invocation
    247			 * namestring.
    248			 */
    249			walk_state->parser_state.aml = start;
    250			walk_state->arg_count = 1;
    251			acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
    252		}
    253
    254		/* This name is actually a control method invocation */
    255
    256		method_desc = acpi_ns_get_attached_object(node);
    257		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
    258				  "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
    259				  node->name.ascii, node, method_desc, path));
    260
    261		name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start);
    262		if (!name_op) {
    263			return_ACPI_STATUS(AE_NO_MEMORY);
    264		}
    265
    266		/* Change Arg into a METHOD CALL and attach name to it */
    267
    268		acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
    269		name_op->common.value.name = path;
    270
    271		/* Point METHODCALL/NAME to the METHOD Node */
    272
    273		name_op->common.node = node;
    274		acpi_ps_append_arg(arg, name_op);
    275
    276		if (!method_desc) {
    277			ACPI_ERROR((AE_INFO,
    278				    "Control Method %p has no attached object",
    279				    node));
    280			return_ACPI_STATUS(AE_AML_INTERNAL);
    281		}
    282
    283		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
    284				  "Control Method - %p Args %X\n",
    285				  node, method_desc->method.param_count));
    286
    287		/* Get the number of arguments to expect */
    288
    289		walk_state->arg_count = method_desc->method.param_count;
    290		return_ACPI_STATUS(AE_OK);
    291	}
    292
    293	/*
    294	 * Special handling if the name was not found during the lookup -
    295	 * some not_found cases are allowed
    296	 */
    297	if (status == AE_NOT_FOUND) {
    298
    299		/* 1) not_found is ok during load pass 1/2 (allow forward references) */
    300
    301		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
    302		    ACPI_PARSE_EXECUTE) {
    303			status = AE_OK;
    304		}
    305
    306		/* 2) not_found during a cond_ref_of(x) is ok by definition */
    307
    308		else if (walk_state->op->common.aml_opcode ==
    309			 AML_CONDITIONAL_REF_OF_OP) {
    310			status = AE_OK;
    311		}
    312
    313		/*
    314		 * 3) not_found while building a Package is ok at this point, we
    315		 * may flag as an error later if slack mode is not enabled.
    316		 * (Some ASL code depends on allowing this behavior)
    317		 */
    318		else if ((arg->common.parent) &&
    319			 ((arg->common.parent->common.aml_opcode ==
    320			   AML_PACKAGE_OP)
    321			  || (arg->common.parent->common.aml_opcode ==
    322			      AML_VARIABLE_PACKAGE_OP))) {
    323			status = AE_OK;
    324		}
    325	}
    326
    327	/* Final exception check (may have been changed from code above) */
    328
    329	if (ACPI_FAILURE(status)) {
    330		ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status);
    331
    332		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
    333		    ACPI_PARSE_EXECUTE) {
    334
    335			/* Report a control method execution error */
    336
    337			status = acpi_ds_method_error(status, walk_state);
    338		}
    339	}
    340
    341	/* Save the namepath */
    342
    343	arg->common.value.name = path;
    344	return_ACPI_STATUS(status);
    345}
    346
    347/*******************************************************************************
    348 *
    349 * FUNCTION:    acpi_ps_get_next_simple_arg
    350 *
    351 * PARAMETERS:  parser_state        - Current parser state object
    352 *              arg_type            - The argument type (AML_*_ARG)
    353 *              arg                 - Where the argument is returned
    354 *
    355 * RETURN:      None
    356 *
    357 * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
    358 *
    359 ******************************************************************************/
    360
    361void
    362acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
    363			    u32 arg_type, union acpi_parse_object *arg)
    364{
    365	u32 length;
    366	u16 opcode;
    367	u8 *aml = parser_state->aml;
    368
    369	ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
    370
    371	switch (arg_type) {
    372	case ARGP_BYTEDATA:
    373
    374		/* Get 1 byte from the AML stream */
    375
    376		opcode = AML_BYTE_OP;
    377		arg->common.value.integer = (u64) *aml;
    378		length = 1;
    379		break;
    380
    381	case ARGP_WORDDATA:
    382
    383		/* Get 2 bytes from the AML stream */
    384
    385		opcode = AML_WORD_OP;
    386		ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
    387		length = 2;
    388		break;
    389
    390	case ARGP_DWORDDATA:
    391
    392		/* Get 4 bytes from the AML stream */
    393
    394		opcode = AML_DWORD_OP;
    395		ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
    396		length = 4;
    397		break;
    398
    399	case ARGP_QWORDDATA:
    400
    401		/* Get 8 bytes from the AML stream */
    402
    403		opcode = AML_QWORD_OP;
    404		ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
    405		length = 8;
    406		break;
    407
    408	case ARGP_CHARLIST:
    409
    410		/* Get a pointer to the string, point past the string */
    411
    412		opcode = AML_STRING_OP;
    413		arg->common.value.string = ACPI_CAST_PTR(char, aml);
    414
    415		/* Find the null terminator */
    416
    417		length = 0;
    418		while (aml[length]) {
    419			length++;
    420		}
    421		length++;
    422		break;
    423
    424	case ARGP_NAME:
    425	case ARGP_NAMESTRING:
    426
    427		acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
    428		arg->common.value.name =
    429		    acpi_ps_get_next_namestring(parser_state);
    430		return_VOID;
    431
    432	default:
    433
    434		ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type));
    435		return_VOID;
    436	}
    437
    438	acpi_ps_init_op(arg, opcode);
    439	parser_state->aml += length;
    440	return_VOID;
    441}
    442
    443/*******************************************************************************
    444 *
    445 * FUNCTION:    acpi_ps_get_next_field
    446 *
    447 * PARAMETERS:  parser_state        - Current parser state object
    448 *
    449 * RETURN:      A newly allocated FIELD op
    450 *
    451 * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
    452 *
    453 ******************************************************************************/
    454
    455static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
    456						       *parser_state)
    457{
    458	u8 *aml;
    459	union acpi_parse_object *field;
    460	union acpi_parse_object *arg = NULL;
    461	u16 opcode;
    462	u32 name;
    463	u8 access_type;
    464	u8 access_attribute;
    465	u8 access_length;
    466	u32 pkg_length;
    467	u8 *pkg_end;
    468	u32 buffer_length;
    469
    470	ACPI_FUNCTION_TRACE(ps_get_next_field);
    471
    472	ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
    473	aml = parser_state->aml;
    474
    475	/* Determine field type */
    476
    477	switch (ACPI_GET8(parser_state->aml)) {
    478	case AML_FIELD_OFFSET_OP:
    479
    480		opcode = AML_INT_RESERVEDFIELD_OP;
    481		parser_state->aml++;
    482		break;
    483
    484	case AML_FIELD_ACCESS_OP:
    485
    486		opcode = AML_INT_ACCESSFIELD_OP;
    487		parser_state->aml++;
    488		break;
    489
    490	case AML_FIELD_CONNECTION_OP:
    491
    492		opcode = AML_INT_CONNECTION_OP;
    493		parser_state->aml++;
    494		break;
    495
    496	case AML_FIELD_EXT_ACCESS_OP:
    497
    498		opcode = AML_INT_EXTACCESSFIELD_OP;
    499		parser_state->aml++;
    500		break;
    501
    502	default:
    503
    504		opcode = AML_INT_NAMEDFIELD_OP;
    505		break;
    506	}
    507
    508	/* Allocate a new field op */
    509
    510	field = acpi_ps_alloc_op(opcode, aml);
    511	if (!field) {
    512		return_PTR(NULL);
    513	}
    514
    515	/* Decode the field type */
    516
    517	ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
    518	switch (opcode) {
    519	case AML_INT_NAMEDFIELD_OP:
    520
    521		/* Get the 4-character name */
    522
    523		ACPI_MOVE_32_TO_32(&name, parser_state->aml);
    524		acpi_ps_set_name(field, name);
    525		parser_state->aml += ACPI_NAMESEG_SIZE;
    526
    527		ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
    528
    529#ifdef ACPI_ASL_COMPILER
    530		/*
    531		 * Because the package length isn't represented as a parse tree object,
    532		 * take comments surrounding this and add to the previously created
    533		 * parse node.
    534		 */
    535		if (field->common.inline_comment) {
    536			field->common.name_comment =
    537			    field->common.inline_comment;
    538		}
    539		field->common.inline_comment = acpi_gbl_current_inline_comment;
    540		acpi_gbl_current_inline_comment = NULL;
    541#endif
    542
    543		/* Get the length which is encoded as a package length */
    544
    545		field->common.value.size =
    546		    acpi_ps_get_next_package_length(parser_state);
    547		break;
    548
    549	case AML_INT_RESERVEDFIELD_OP:
    550
    551		/* Get the length which is encoded as a package length */
    552
    553		field->common.value.size =
    554		    acpi_ps_get_next_package_length(parser_state);
    555		break;
    556
    557	case AML_INT_ACCESSFIELD_OP:
    558	case AML_INT_EXTACCESSFIELD_OP:
    559
    560		/*
    561		 * Get access_type and access_attrib and merge into the field Op
    562		 * access_type is first operand, access_attribute is second. stuff
    563		 * these bytes into the node integer value for convenience.
    564		 */
    565
    566		/* Get the two bytes (Type/Attribute) */
    567
    568		access_type = ACPI_GET8(parser_state->aml);
    569		parser_state->aml++;
    570		access_attribute = ACPI_GET8(parser_state->aml);
    571		parser_state->aml++;
    572
    573		field->common.value.integer = (u8)access_type;
    574		field->common.value.integer |= (u16)(access_attribute << 8);
    575
    576		/* This opcode has a third byte, access_length */
    577
    578		if (opcode == AML_INT_EXTACCESSFIELD_OP) {
    579			access_length = ACPI_GET8(parser_state->aml);
    580			parser_state->aml++;
    581
    582			field->common.value.integer |=
    583			    (u32)(access_length << 16);
    584		}
    585		break;
    586
    587	case AML_INT_CONNECTION_OP:
    588
    589		/*
    590		 * Argument for Connection operator can be either a Buffer
    591		 * (resource descriptor), or a name_string.
    592		 */
    593		aml = parser_state->aml;
    594		if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
    595			parser_state->aml++;
    596
    597			ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
    598			pkg_end = parser_state->aml;
    599			pkg_length =
    600			    acpi_ps_get_next_package_length(parser_state);
    601			pkg_end += pkg_length;
    602
    603			ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
    604			if (parser_state->aml < pkg_end) {
    605
    606				/* Non-empty list */
    607
    608				arg =
    609				    acpi_ps_alloc_op(AML_INT_BYTELIST_OP, aml);
    610				if (!arg) {
    611					acpi_ps_free_op(field);
    612					return_PTR(NULL);
    613				}
    614
    615				/* Get the actual buffer length argument */
    616
    617				opcode = ACPI_GET8(parser_state->aml);
    618				parser_state->aml++;
    619
    620				ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
    621				switch (opcode) {
    622				case AML_BYTE_OP:	/* AML_BYTEDATA_ARG */
    623
    624					buffer_length =
    625					    ACPI_GET8(parser_state->aml);
    626					parser_state->aml += 1;
    627					break;
    628
    629				case AML_WORD_OP:	/* AML_WORDDATA_ARG */
    630
    631					buffer_length =
    632					    ACPI_GET16(parser_state->aml);
    633					parser_state->aml += 2;
    634					break;
    635
    636				case AML_DWORD_OP:	/* AML_DWORDATA_ARG */
    637
    638					buffer_length =
    639					    ACPI_GET32(parser_state->aml);
    640					parser_state->aml += 4;
    641					break;
    642
    643				default:
    644
    645					buffer_length = 0;
    646					break;
    647				}
    648
    649				/* Fill in bytelist data */
    650
    651				ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
    652				arg->named.value.size = buffer_length;
    653				arg->named.data = parser_state->aml;
    654			}
    655
    656			/* Skip to End of byte data */
    657
    658			parser_state->aml = pkg_end;
    659		} else {
    660			arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, aml);
    661			if (!arg) {
    662				acpi_ps_free_op(field);
    663				return_PTR(NULL);
    664			}
    665
    666			/* Get the Namestring argument */
    667
    668			arg->common.value.name =
    669			    acpi_ps_get_next_namestring(parser_state);
    670		}
    671
    672		/* Link the buffer/namestring to parent (CONNECTION_OP) */
    673
    674		acpi_ps_append_arg(field, arg);
    675		break;
    676
    677	default:
    678
    679		/* Opcode was set in previous switch */
    680		break;
    681	}
    682
    683	return_PTR(field);
    684}
    685
    686/*******************************************************************************
    687 *
    688 * FUNCTION:    acpi_ps_get_next_arg
    689 *
    690 * PARAMETERS:  walk_state          - Current state
    691 *              parser_state        - Current parser state object
    692 *              arg_type            - The argument type (AML_*_ARG)
    693 *              return_arg          - Where the next arg is returned
    694 *
    695 * RETURN:      Status, and an op object containing the next argument.
    696 *
    697 * DESCRIPTION: Get next argument (including complex list arguments that require
    698 *              pushing the parser stack)
    699 *
    700 ******************************************************************************/
    701
    702acpi_status
    703acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
    704		     struct acpi_parse_state *parser_state,
    705		     u32 arg_type, union acpi_parse_object **return_arg)
    706{
    707	union acpi_parse_object *arg = NULL;
    708	union acpi_parse_object *prev = NULL;
    709	union acpi_parse_object *field;
    710	u32 subop;
    711	acpi_status status = AE_OK;
    712
    713	ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
    714
    715	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
    716			  "Expected argument type ARGP: %s (%2.2X)\n",
    717			  acpi_ut_get_argument_type_name(arg_type), arg_type));
    718
    719	switch (arg_type) {
    720	case ARGP_BYTEDATA:
    721	case ARGP_WORDDATA:
    722	case ARGP_DWORDDATA:
    723	case ARGP_CHARLIST:
    724	case ARGP_NAME:
    725	case ARGP_NAMESTRING:
    726
    727		/* Constants, strings, and namestrings are all the same size */
    728
    729		arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml);
    730		if (!arg) {
    731			return_ACPI_STATUS(AE_NO_MEMORY);
    732		}
    733
    734		acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
    735		break;
    736
    737	case ARGP_PKGLENGTH:
    738
    739		/* Package length, nothing returned */
    740
    741		parser_state->pkg_end =
    742		    acpi_ps_get_next_package_end(parser_state);
    743		break;
    744
    745	case ARGP_FIELDLIST:
    746
    747		if (parser_state->aml < parser_state->pkg_end) {
    748
    749			/* Non-empty list */
    750
    751			while (parser_state->aml < parser_state->pkg_end) {
    752				field = acpi_ps_get_next_field(parser_state);
    753				if (!field) {
    754					return_ACPI_STATUS(AE_NO_MEMORY);
    755				}
    756
    757				if (prev) {
    758					prev->common.next = field;
    759				} else {
    760					arg = field;
    761				}
    762				prev = field;
    763			}
    764
    765			/* Skip to End of byte data */
    766
    767			parser_state->aml = parser_state->pkg_end;
    768		}
    769		break;
    770
    771	case ARGP_BYTELIST:
    772
    773		if (parser_state->aml < parser_state->pkg_end) {
    774
    775			/* Non-empty list */
    776
    777			arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP,
    778					       parser_state->aml);
    779			if (!arg) {
    780				return_ACPI_STATUS(AE_NO_MEMORY);
    781			}
    782
    783			/* Fill in bytelist data */
    784
    785			arg->common.value.size = (u32)
    786			    ACPI_PTR_DIFF(parser_state->pkg_end,
    787					  parser_state->aml);
    788			arg->named.data = parser_state->aml;
    789
    790			/* Skip to End of byte data */
    791
    792			parser_state->aml = parser_state->pkg_end;
    793		}
    794		break;
    795
    796	case ARGP_SIMPLENAME:
    797	case ARGP_NAME_OR_REF:
    798
    799		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
    800				  "**** SimpleName/NameOrRef: %s (%2.2X)\n",
    801				  acpi_ut_get_argument_type_name(arg_type),
    802				  arg_type));
    803
    804		subop = acpi_ps_peek_opcode(parser_state);
    805		if (subop == 0 ||
    806		    acpi_ps_is_leading_char(subop) ||
    807		    ACPI_IS_ROOT_PREFIX(subop) ||
    808		    ACPI_IS_PARENT_PREFIX(subop)) {
    809
    810			/* null_name or name_string */
    811
    812			arg =
    813			    acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
    814					     parser_state->aml);
    815			if (!arg) {
    816				return_ACPI_STATUS(AE_NO_MEMORY);
    817			}
    818
    819			status =
    820			    acpi_ps_get_next_namepath(walk_state, parser_state,
    821						      arg,
    822						      ACPI_NOT_METHOD_CALL);
    823		} else {
    824			/* Single complex argument, nothing returned */
    825
    826			walk_state->arg_count = 1;
    827		}
    828		break;
    829
    830	case ARGP_TARGET:
    831	case ARGP_SUPERNAME:
    832
    833		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
    834				  "**** Target/Supername: %s (%2.2X)\n",
    835				  acpi_ut_get_argument_type_name(arg_type),
    836				  arg_type));
    837
    838		subop = acpi_ps_peek_opcode(parser_state);
    839		if (subop == 0 ||
    840		    acpi_ps_is_leading_char(subop) ||
    841		    ACPI_IS_ROOT_PREFIX(subop) ||
    842		    ACPI_IS_PARENT_PREFIX(subop)) {
    843
    844			/* NULL target (zero). Convert to a NULL namepath */
    845
    846			arg =
    847			    acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
    848					     parser_state->aml);
    849			if (!arg) {
    850				return_ACPI_STATUS(AE_NO_MEMORY);
    851			}
    852
    853			status =
    854			    acpi_ps_get_next_namepath(walk_state, parser_state,
    855						      arg,
    856						      ACPI_POSSIBLE_METHOD_CALL);
    857
    858			if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
    859
    860				/* Free method call op and corresponding namestring sub-ob */
    861
    862				acpi_ps_free_op(arg->common.value.arg);
    863				acpi_ps_free_op(arg);
    864				arg = NULL;
    865				walk_state->arg_count = 1;
    866			}
    867		} else {
    868			/* Single complex argument, nothing returned */
    869
    870			walk_state->arg_count = 1;
    871		}
    872		break;
    873
    874	case ARGP_DATAOBJ:
    875	case ARGP_TERMARG:
    876
    877		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
    878				  "**** TermArg/DataObj: %s (%2.2X)\n",
    879				  acpi_ut_get_argument_type_name(arg_type),
    880				  arg_type));
    881
    882		/* Single complex argument, nothing returned */
    883
    884		walk_state->arg_count = 1;
    885		break;
    886
    887	case ARGP_DATAOBJLIST:
    888	case ARGP_TERMLIST:
    889	case ARGP_OBJLIST:
    890
    891		if (parser_state->aml < parser_state->pkg_end) {
    892
    893			/* Non-empty list of variable arguments, nothing returned */
    894
    895			walk_state->arg_count = ACPI_VAR_ARGS;
    896		}
    897		break;
    898
    899	default:
    900
    901		ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type));
    902		status = AE_AML_OPERAND_TYPE;
    903		break;
    904	}
    905
    906	*return_arg = arg;
    907	return_ACPI_STATUS(status);
    908}