Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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