Blame view

drivers/acpi/acpica/psloop.c 17.1 KB
73459f73e   Robert Moore   ACPICA 20050617-0...
1
2
3
4
5
6
7
  /******************************************************************************
   *
   * Module Name: psloop - Main AML parse loop
   *
   *****************************************************************************/
  
  /*
c8100dc46   Bob Moore   ACPICA: Additiona...
8
   * Copyright (C) 2000 - 2016, Intel Corp.
73459f73e   Robert Moore   ACPICA 20050617-0...
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions, and the following disclaimer,
   *    without modification.
   * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   *    substantially similar to the "NO WARRANTY" disclaimer below
   *    ("Disclaimer") and any redistribution must be conditioned upon
   *    including a substantially similar Disclaimer requirement for further
   *    binary redistribution.
   * 3. Neither the names of the above-listed copyright holders nor the names
   *    of any contributors may be used to endorse or promote products derived
   *    from this software without specific prior written permission.
   *
   * Alternatively, this software may be distributed under the terms of the
   * GNU General Public License ("GPL") version 2 as published by the Free
   * Software Foundation.
   *
   * NO WARRANTY
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGES.
   */
73459f73e   Robert Moore   ACPICA 20050617-0...
43
  /*
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
44
45
46
47
48
   * Parse the AML and build an operation tree as most interpreters, (such as
   * Perl) do. Parsing is done by hand rather than with a YACC generated parser
   * to tightly constrain stack and dynamic memory usage. Parsing is kept
   * flexible and the code fairly compact by parsing based on a list of AML
   * opcode templates in aml_op_info[].
73459f73e   Robert Moore   ACPICA 20050617-0...
49
50
51
   */
  
  #include <acpi/acpi.h>
e2f7a7772   Len Brown   ACPICA: hide priv...
52
  #include "accommon.h"
ab6c57332   Lv Zheng   ACPICA: Executer:...
53
  #include "acinterp.h"
e2f7a7772   Len Brown   ACPICA: hide priv...
54
55
56
  #include "acparser.h"
  #include "acdispat.h"
  #include "amlcode.h"
73459f73e   Robert Moore   ACPICA 20050617-0...
57
58
  
  #define _COMPONENT          ACPI_PARSER
4be44fcd3   Len Brown   [ACPI] Lindent al...
59
  ACPI_MODULE_NAME("psloop")
73459f73e   Robert Moore   ACPICA 20050617-0...
60

4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
61
  /* Local prototypes */
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
62
63
64
  static acpi_status
  acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
  		      u8 * aml_op_start, union acpi_parse_object *op);
7f0c826a4   Lin Ming   ACPICA: Add suppo...
65
  static void
9a884ab64   Lin Ming   ACPICA: Add addit...
66
67
  acpi_ps_link_module_code(union acpi_parse_object *parent_op,
  			 u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
7f0c826a4   Lin Ming   ACPICA: Add suppo...
68

4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
69
70
  /*******************************************************************************
   *
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
71
72
73
74
   * FUNCTION:    acpi_ps_get_arguments
   *
   * PARAMETERS:  walk_state          - Current state
   *              aml_op_start        - Op start in AML
ba494beea   Bob Moore   ACPICA: AcpiSrc: ...
75
   *              op                  - Current Op
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
76
77
78
79
80
81
82
83
84
85
86
87
88
   *
   * RETURN:      Status
   *
   * DESCRIPTION: Get arguments for passed Op.
   *
   ******************************************************************************/
  
  static acpi_status
  acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
  		      u8 * aml_op_start, union acpi_parse_object *op)
  {
  	acpi_status status = AE_OK;
  	union acpi_parse_object *arg = NULL;
7f0c826a4   Lin Ming   ACPICA: Add suppo...
89
  	const struct acpi_opcode_info *op_info;
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  
  	ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
  
  	switch (op->common.aml_opcode) {
  	case AML_BYTE_OP:	/* AML_BYTEDATA_ARG */
  	case AML_WORD_OP:	/* AML_WORDDATA_ARG */
  	case AML_DWORD_OP:	/* AML_DWORDATA_ARG */
  	case AML_QWORD_OP:	/* AML_QWORDATA_ARG */
  	case AML_STRING_OP:	/* AML_ASCIICHARLIST_ARG */
  
  		/* Fill in constant or string argument directly */
  
  		acpi_ps_get_next_simple_arg(&(walk_state->parser_state),
  					    GET_CURRENT_ARG_TYPE(walk_state->
  								 arg_types),
  					    op);
  		break;
  
  	case AML_INT_NAMEPATH_OP:	/* AML_NAMESTRING_ARG */
89438f96f   Bob Moore   ACPICA: Parser: A...
109
110
111
112
  		status = acpi_ps_get_next_namepath(walk_state,
  						   &(walk_state->parser_state),
  						   op,
  						   ACPI_POSSIBLE_METHOD_CALL);
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
113
114
115
116
117
118
119
120
121
122
123
  		if (ACPI_FAILURE(status)) {
  			return_ACPI_STATUS(status);
  		}
  
  		walk_state->arg_types = 0;
  		break;
  
  	default:
  		/*
  		 * Op is not a constant or string, append each argument to the Op
  		 */
1fad87385   Bob Moore   ACPICA: Core: Maj...
124
125
  		while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
  		       !walk_state->arg_count) {
83482f758   Lv Zheng   ACPICA: Parser: C...
126
  			walk_state->aml = walk_state->parser_state.aml;
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
127
128
129
130
131
132
133
134
135
136
137
  
  			status =
  			    acpi_ps_get_next_arg(walk_state,
  						 &(walk_state->parser_state),
  						 GET_CURRENT_ARG_TYPE
  						 (walk_state->arg_types), &arg);
  			if (ACPI_FAILURE(status)) {
  				return_ACPI_STATUS(status);
  			}
  
  			if (arg) {
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
138
139
140
141
142
  				acpi_ps_append_arg(op, arg);
  			}
  
  			INCREMENT_ARG_LIST(walk_state->arg_types);
  		}
7f0c826a4   Lin Ming   ACPICA: Add suppo...
143
144
145
146
147
  		/*
  		 * Handle executable code at "module-level". This refers to
  		 * executable opcodes that appear outside of any control method.
  		 */
  		if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2) &&
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
148
149
150
151
152
153
154
155
156
157
158
159
  		    ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
  			/*
  			 * We want to skip If/Else/While constructs during Pass1 because we
  			 * want to actually conditionally execute the code during Pass2.
  			 *
  			 * Except for disassembly, where we always want to walk the
  			 * If/Else/While packages
  			 */
  			switch (op->common.aml_opcode) {
  			case AML_IF_OP:
  			case AML_ELSE_OP:
  			case AML_WHILE_OP:
7f0c826a4   Lin Ming   ACPICA: Add suppo...
160
161
162
163
164
165
166
167
  				/*
  				 * Currently supported module-level opcodes are:
  				 * IF/ELSE/WHILE. These appear to be the most common,
  				 * and easiest to support since they open an AML
  				 * package.
  				 */
  				if (walk_state->pass_number ==
  				    ACPI_IMODE_LOAD_PASS1) {
9a884ab64   Lin Ming   ACPICA: Add addit...
168
169
170
171
172
  					acpi_ps_link_module_code(op->common.
  								 parent,
  								 aml_op_start,
  								 (u32)
  								 (walk_state->
7f0c826a4   Lin Ming   ACPICA: Add suppo...
173
174
  								 parser_state.
  								 pkg_end -
9a884ab64   Lin Ming   ACPICA: Add addit...
175
  								 aml_op_start),
7f0c826a4   Lin Ming   ACPICA: Add suppo...
176
177
178
  								 walk_state->
  								 owner_id);
  				}
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
179
180
181
182
183
184
185
186
187
188
189
190
  				ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
  						  "Pass1: Skipping an If/Else/While body
  "));
  
  				/* Skip body of if/else/while in pass 1 */
  
  				walk_state->parser_state.aml =
  				    walk_state->parser_state.pkg_end;
  				walk_state->arg_count = 0;
  				break;
  
  			default:
7f0c826a4   Lin Ming   ACPICA: Add suppo...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
  				/*
  				 * Check for an unsupported executable opcode at module
  				 * level. We must be in PASS1, the parent must be a SCOPE,
  				 * The opcode class must be EXECUTE, and the opcode must
  				 * not be an argument to another opcode.
  				 */
  				if ((walk_state->pass_number ==
  				     ACPI_IMODE_LOAD_PASS1)
  				    && (op->common.parent->common.aml_opcode ==
  					AML_SCOPE_OP)) {
  					op_info =
  					    acpi_ps_get_opcode_info(op->common.
  								    aml_opcode);
  					if ((op_info->class ==
  					     AML_CLASS_EXECUTE) && (!arg)) {
  						ACPI_WARNING((AE_INFO,
00eb32550   Bob Moore   ACPICA: Enhance e...
207
208
209
210
211
212
213
214
215
216
217
218
  							      "Unsupported module-level executable opcode "
  							      "0x%.2X at table offset 0x%.4X",
  							      op->common.
  							      aml_opcode,
  							      (u32)
  							      (ACPI_PTR_DIFF
  							       (aml_op_start,
  								walk_state->
  								parser_state.
  								aml_start) +
  							       sizeof(struct
  								      acpi_table_header))));
7f0c826a4   Lin Ming   ACPICA: Add suppo...
219
220
  					}
  				}
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
221
222
223
  				break;
  			}
  		}
7f0c826a4   Lin Ming   ACPICA: Add suppo...
224
225
  
  		/* Special processing for certain opcodes */
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  
  		switch (op->common.aml_opcode) {
  		case AML_METHOD_OP:
  			/*
  			 * Skip parsing of control method because we don't have enough
  			 * info in the first pass to parse it correctly.
  			 *
  			 * Save the length and address of the body
  			 */
  			op->named.data = walk_state->parser_state.aml;
  			op->named.length = (u32)
  			    (walk_state->parser_state.pkg_end -
  			     walk_state->parser_state.aml);
  
  			/* Skip body of method */
  
  			walk_state->parser_state.aml =
  			    walk_state->parser_state.pkg_end;
  			walk_state->arg_count = 0;
  			break;
  
  		case AML_BUFFER_OP:
  		case AML_PACKAGE_OP:
  		case AML_VAR_PACKAGE_OP:
  
  			if ((op->common.parent) &&
  			    (op->common.parent->common.aml_opcode ==
  			     AML_NAME_OP)
  			    && (walk_state->pass_number <=
  				ACPI_IMODE_LOAD_PASS2)) {
  				/*
  				 * Skip parsing of Buffers and Packages because we don't have
  				 * enough info in the first pass to parse them correctly.
  				 */
  				op->named.data = aml_op_start;
  				op->named.length = (u32)
  				    (walk_state->parser_state.pkg_end -
  				     aml_op_start);
  
  				/* Skip body */
  
  				walk_state->parser_state.aml =
  				    walk_state->parser_state.pkg_end;
  				walk_state->arg_count = 0;
  			}
  			break;
  
  		case AML_WHILE_OP:
  
  			if (walk_state->control_state) {
  				walk_state->control_state->control.package_end =
  				    walk_state->parser_state.pkg_end;
  			}
  			break;
  
  		default:
  
  			/* No action for all other opcodes */
1d1ea1b72   Chao Guan   ACPICA: Standardi...
284

4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
285
286
287
288
289
290
291
292
293
294
295
  			break;
  		}
  
  		break;
  	}
  
  	return_ACPI_STATUS(AE_OK);
  }
  
  /*******************************************************************************
   *
7f0c826a4   Lin Ming   ACPICA: Add suppo...
296
297
   * FUNCTION:    acpi_ps_link_module_code
   *
9a884ab64   Lin Ming   ACPICA: Add addit...
298
299
   * PARAMETERS:  parent_op           - Parent parser op
   *              aml_start           - Pointer to the AML
7f0c826a4   Lin Ming   ACPICA: Add suppo...
300
301
302
303
304
305
306
307
308
309
310
311
   *              aml_length          - Length of executable AML
   *              owner_id            - owner_id of module level code
   *
   * RETURN:      None.
   *
   * DESCRIPTION: Wrap the module-level code with a method object and link the
   *              object to the global list. Note, the mutex field of the method
   *              object is used to link multiple module-level code objects.
   *
   ******************************************************************************/
  
  static void
9a884ab64   Lin Ming   ACPICA: Add addit...
312
313
  acpi_ps_link_module_code(union acpi_parse_object *parent_op,
  			 u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
7f0c826a4   Lin Ming   ACPICA: Add suppo...
314
315
316
317
  {
  	union acpi_operand_object *prev;
  	union acpi_operand_object *next;
  	union acpi_operand_object *method_obj;
9a884ab64   Lin Ming   ACPICA: Add addit...
318
  	struct acpi_namespace_node *parent_node;
7f0c826a4   Lin Ming   ACPICA: Add suppo...
319

25823e784   Bob Moore   ACPICA: Add addit...
320
  	ACPI_FUNCTION_TRACE(ps_link_module_code);
7f0c826a4   Lin Ming   ACPICA: Add suppo...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
  	/* Get the tail of the list */
  
  	prev = next = acpi_gbl_module_code_list;
  	while (next) {
  		prev = next;
  		next = next->method.mutex;
  	}
  
  	/*
  	 * Insert the module level code into the list. Merge it if it is
  	 * adjacent to the previous element.
  	 */
  	if (!prev ||
  	    ((prev->method.aml_start + prev->method.aml_length) != aml_start)) {
  
  		/* Create, initialize, and link a new temporary method object */
  
  		method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
  		if (!method_obj) {
25823e784   Bob Moore   ACPICA: Add addit...
340
  			return_VOID;
7f0c826a4   Lin Ming   ACPICA: Add suppo...
341
  		}
25823e784   Bob Moore   ACPICA: Add addit...
342
343
344
345
  		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
  				  "Create/Link new code block: %p
  ",
  				  method_obj));
9a884ab64   Lin Ming   ACPICA: Add addit...
346
347
348
349
350
  		if (parent_op->common.node) {
  			parent_node = parent_op->common.node;
  		} else {
  			parent_node = acpi_gbl_root_node;
  		}
7f0c826a4   Lin Ming   ACPICA: Add suppo...
351
352
353
  		method_obj->method.aml_start = aml_start;
  		method_obj->method.aml_length = aml_length;
  		method_obj->method.owner_id = owner_id;
262948428   Lin Ming   ACPICA: Fix issue...
354
  		method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
7f0c826a4   Lin Ming   ACPICA: Add suppo...
355

9a884ab64   Lin Ming   ACPICA: Add addit...
356
357
358
359
360
361
  		/*
  		 * Save the parent node in next_object. This is cheating, but we
  		 * don't want to expand the method object.
  		 */
  		method_obj->method.next_object =
  		    ACPI_CAST_PTR(union acpi_operand_object, parent_node);
7f0c826a4   Lin Ming   ACPICA: Add suppo...
362
363
364
365
366
367
  		if (!prev) {
  			acpi_gbl_module_code_list = method_obj;
  		} else {
  			prev->method.mutex = method_obj;
  		}
  	} else {
25823e784   Bob Moore   ACPICA: Add addit...
368
369
370
371
  		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
  				  "Appending to existing code block: %p
  ",
  				  prev));
7f0c826a4   Lin Ming   ACPICA: Add suppo...
372
373
  		prev->method.aml_length += aml_length;
  	}
25823e784   Bob Moore   ACPICA: Add addit...
374
375
  
  	return_VOID;
7f0c826a4   Lin Ming   ACPICA: Add suppo...
376
377
378
379
  }
  
  /*******************************************************************************
   *
73459f73e   Robert Moore   ACPICA 20050617-0...
380
381
382
383
384
385
386
387
388
389
   * FUNCTION:    acpi_ps_parse_loop
   *
   * PARAMETERS:  walk_state          - Current state
   *
   * RETURN:      Status
   *
   * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
   *              a tree of ops.
   *
   ******************************************************************************/
4be44fcd3   Len Brown   [ACPI] Lindent al...
390
  acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
73459f73e   Robert Moore   ACPICA 20050617-0...
391
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
392
  	acpi_status status = AE_OK;
4be44fcd3   Len Brown   [ACPI] Lindent al...
393
  	union acpi_parse_object *op = NULL;	/* current op */
4be44fcd3   Len Brown   [ACPI] Lindent al...
394
395
  	struct acpi_parse_state *parser_state;
  	u8 *aml_op_start = NULL;
73459f73e   Robert Moore   ACPICA 20050617-0...
396

b229cf92e   Bob Moore   ACPI: ACPICA 2006...
397
  	ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state);
73459f73e   Robert Moore   ACPICA 20050617-0...
398
399
  
  	if (walk_state->descending_callback == NULL) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
400
  		return_ACPI_STATUS(AE_BAD_PARAMETER);
73459f73e   Robert Moore   ACPICA 20050617-0...
401
402
403
404
405
406
407
408
  	}
  
  	parser_state = &walk_state->parser_state;
  	walk_state->arg_types = 0;
  
  #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
  
  	if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
409

73459f73e   Robert Moore   ACPICA 20050617-0...
410
  		/* We are restarting a preempted control method */
4be44fcd3   Len Brown   [ACPI] Lindent al...
411
  		if (acpi_ps_has_completed_scope(parser_state)) {
73459f73e   Robert Moore   ACPICA 20050617-0...
412
413
414
415
416
  			/*
  			 * We must check if a predicate to an IF or WHILE statement
  			 * was just completed
  			 */
  			if ((parser_state->scope->parse_scope.op) &&
4be44fcd3   Len Brown   [ACPI] Lindent al...
417
418
419
420
421
422
423
  			    ((parser_state->scope->parse_scope.op->common.
  			      aml_opcode == AML_IF_OP)
  			     || (parser_state->scope->parse_scope.op->common.
  				 aml_opcode == AML_WHILE_OP))
  			    && (walk_state->control_state)
  			    && (walk_state->control_state->common.state ==
  				ACPI_CONTROL_PREDICATE_EXECUTING)) {
73459f73e   Robert Moore   ACPICA 20050617-0...
424
425
426
427
428
  				/*
  				 * A predicate was just completed, get the value of the
  				 * predicate and branch based on that value
  				 */
  				walk_state->op = NULL;
4be44fcd3   Len Brown   [ACPI] Lindent al...
429
430
431
432
433
434
435
  				status =
  				    acpi_ds_get_predicate_value(walk_state,
  								ACPI_TO_POINTER
  								(TRUE));
  				if (ACPI_FAILURE(status)
  				    && ((status & AE_CODE_MASK) !=
  					AE_CODE_CONTROL)) {
73459f73e   Robert Moore   ACPICA 20050617-0...
436
  					if (status == AE_AML_NO_RETURN_VALUE) {
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
437
438
  						ACPI_EXCEPTION((AE_INFO, status,
  								"Invoked method did not return a value"));
73459f73e   Robert Moore   ACPICA 20050617-0...
439
  					}
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
440

b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
441
  					ACPI_EXCEPTION((AE_INFO, status,
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
442
  							"GetPredicate Failed"));
4be44fcd3   Len Brown   [ACPI] Lindent al...
443
  					return_ACPI_STATUS(status);
73459f73e   Robert Moore   ACPICA 20050617-0...
444
  				}
4be44fcd3   Len Brown   [ACPI] Lindent al...
445
446
447
  				status =
  				    acpi_ps_next_parse_state(walk_state, op,
  							     status);
73459f73e   Robert Moore   ACPICA 20050617-0...
448
  			}
4be44fcd3   Len Brown   [ACPI] Lindent al...
449
450
451
452
453
454
455
  			acpi_ps_pop_scope(parser_state, &op,
  					  &walk_state->arg_types,
  					  &walk_state->arg_count);
  			ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
  					  "Popped scope, Op=%p
  ", op));
  		} else if (walk_state->prev_op) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
456

73459f73e   Robert Moore   ACPICA 20050617-0...
457
  			/* We were in the middle of an op */
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
458
459
460
461
462
  			op = walk_state->prev_op;
  			walk_state->arg_types = walk_state->prev_arg_types;
  		}
  	}
  #endif
73459f73e   Robert Moore   ACPICA 20050617-0...
463

4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
464
  	/* Iterative parsing loop, while there is more AML to process: */
73459f73e   Robert Moore   ACPICA 20050617-0...
465

4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
466
467
468
469
470
471
472
  	while ((parser_state->aml < parser_state->aml_end) || (op)) {
  		aml_op_start = parser_state->aml;
  		if (!op) {
  			status =
  			    acpi_ps_create_op(walk_state, aml_op_start, &op);
  			if (ACPI_FAILURE(status)) {
  				if (status == AE_CTRL_PARSE_CONTINUE) {
73459f73e   Robert Moore   ACPICA 20050617-0...
473
474
  					continue;
  				}
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
475
  				if (status == AE_CTRL_PARSE_PENDING) {
73459f73e   Robert Moore   ACPICA 20050617-0...
476
  					status = AE_OK;
73459f73e   Robert Moore   ACPICA 20050617-0...
477
  				}
22b5afce6   Bob Moore   ACPICA: Add auto-...
478
479
480
  				if (status == AE_CTRL_TERMINATE) {
  					return_ACPI_STATUS(status);
  				}
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
481
482
483
  				status =
  				    acpi_ps_complete_op(walk_state, &op,
  							status);
4be44fcd3   Len Brown   [ACPI] Lindent al...
484
  				if (ACPI_FAILURE(status)) {
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
485
  					return_ACPI_STATUS(status);
73459f73e   Robert Moore   ACPICA 20050617-0...
486
  				}
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
487
  				continue;
73459f73e   Robert Moore   ACPICA 20050617-0...
488
  			}
ab6c57332   Lv Zheng   ACPICA: Executer:...
489
  			acpi_ex_start_trace_opcode(op, walk_state);
73459f73e   Robert Moore   ACPICA 20050617-0...
490
  		}
73459f73e   Robert Moore   ACPICA 20050617-0...
491
492
493
494
495
496
497
498
499
  		/*
  		 * Start arg_count at zero because we don't know if there are
  		 * any args yet
  		 */
  		walk_state->arg_count = 0;
  
  		/* Are there any arguments that must be processed? */
  
  		if (walk_state->arg_types) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
500

73459f73e   Robert Moore   ACPICA 20050617-0...
501
  			/* Get arguments */
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
502
503
504
  			status =
  			    acpi_ps_get_arguments(walk_state, aml_op_start, op);
  			if (ACPI_FAILURE(status)) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
505
  				status =
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
506
507
  				    acpi_ps_complete_op(walk_state, &op,
  							status);
4be44fcd3   Len Brown   [ACPI] Lindent al...
508
  				if (ACPI_FAILURE(status)) {
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
509
  					return_ACPI_STATUS(status);
73459f73e   Robert Moore   ACPICA 20050617-0...
510
  				}
73459f73e   Robert Moore   ACPICA 20050617-0...
511

4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
512
  				continue;
73459f73e   Robert Moore   ACPICA 20050617-0...
513
514
515
516
517
518
519
520
521
522
  			}
  		}
  
  		/* Check for arguments that need to be processed */
  
  		if (walk_state->arg_count) {
  			/*
  			 * There are arguments (complex ones), push Op and
  			 * prepare for argument
  			 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
523
524
525
526
  			status = acpi_ps_push_scope(parser_state, op,
  						    walk_state->arg_types,
  						    walk_state->arg_count);
  			if (ACPI_FAILURE(status)) {
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
527
528
529
530
531
532
533
534
  				status =
  				    acpi_ps_complete_op(walk_state, &op,
  							status);
  				if (ACPI_FAILURE(status)) {
  					return_ACPI_STATUS(status);
  				}
  
  				continue;
73459f73e   Robert Moore   ACPICA 20050617-0...
535
  			}
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
536

73459f73e   Robert Moore   ACPICA 20050617-0...
537
538
539
540
541
542
543
544
  			op = NULL;
  			continue;
  		}
  
  		/*
  		 * All arguments have been processed -- Op is complete,
  		 * prepare for next
  		 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
545
546
  		walk_state->op_info =
  		    acpi_ps_get_opcode_info(op->common.aml_opcode);
73459f73e   Robert Moore   ACPICA 20050617-0...
547
  		if (walk_state->op_info->flags & AML_NAMED) {
941f48bb4   Lin Ming   ACPICA: Implement...
548
549
  			if (op->common.aml_opcode == AML_REGION_OP ||
  			    op->common.aml_opcode == AML_DATA_REGION_OP) {
73459f73e   Robert Moore   ACPICA 20050617-0...
550
551
552
553
554
555
556
557
  				/*
  				 * Skip parsing of control method or opregion body,
  				 * because we don't have enough info in the first pass
  				 * to parse them correctly.
  				 *
  				 * Completed parsing an op_region declaration, we now
  				 * know the length.
  				 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
558
559
  				op->named.length =
  				    (u32) (parser_state->aml - op->named.data);
73459f73e   Robert Moore   ACPICA 20050617-0...
560
561
562
563
564
  			}
  		}
  
  		if (walk_state->op_info->flags & AML_CREATE) {
  			/*
ba494beea   Bob Moore   ACPICA: AcpiSrc: ...
565
  			 * Backup to beginning of create_XXXfield declaration (1 for
73459f73e   Robert Moore   ACPICA 20050617-0...
566
567
568
569
  			 * Opcode)
  			 *
  			 * body_length is unknown until we parse the body
  			 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
570
571
  			op->named.length =
  			    (u32) (parser_state->aml - op->named.data);
73459f73e   Robert Moore   ACPICA 20050617-0...
572
  		}
ef805d956   Lin Ming   ACPICA: Implement...
573
574
575
576
577
578
579
580
581
  		if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
  			/*
  			 * Backup to beginning of bank_field declaration
  			 *
  			 * body_length is unknown until we parse the body
  			 */
  			op->named.length =
  			    (u32) (parser_state->aml - op->named.data);
  		}
73459f73e   Robert Moore   ACPICA 20050617-0...
582
583
584
  		/* This op complete, notify the dispatcher */
  
  		if (walk_state->ascending_callback != NULL) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
585
  			walk_state->op = op;
73459f73e   Robert Moore   ACPICA 20050617-0...
586
  			walk_state->opcode = op->common.aml_opcode;
4be44fcd3   Len Brown   [ACPI] Lindent al...
587
588
589
  			status = walk_state->ascending_callback(walk_state);
  			status =
  			    acpi_ps_next_parse_state(walk_state, op, status);
73459f73e   Robert Moore   ACPICA 20050617-0...
590
591
  			if (status == AE_CTRL_PENDING) {
  				status = AE_OK;
73459f73e   Robert Moore   ACPICA 20050617-0...
592
593
  			}
  		}
4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
594
595
  		status = acpi_ps_complete_op(walk_state, &op, status);
  		if (ACPI_FAILURE(status)) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
596
  			return_ACPI_STATUS(status);
73459f73e   Robert Moore   ACPICA 20050617-0...
597
  		}
4be44fcd3   Len Brown   [ACPI] Lindent al...
598
  	}			/* while parser_state->Aml */
73459f73e   Robert Moore   ACPICA 20050617-0...
599

4d0b4af95   Mikhail Kouzmich   ACPICA: Restructu...
600
  	status = acpi_ps_complete_final_op(walk_state, op, status);
4be44fcd3   Len Brown   [ACPI] Lindent al...
601
  	return_ACPI_STATUS(status);
73459f73e   Robert Moore   ACPICA 20050617-0...
602
  }