File: /usr/src/linux/drivers/acpi/parser/psparse.c

1     /******************************************************************************
2      *
3      * Module Name: psparse - Parser top level AML parse routines
4      *              $Revision: 96 $
5      *
6      *****************************************************************************/
7     
8     /*
9      *  Copyright (C) 2000, 2001 R. Byron Moore
10      *
11      *  This program is free software; you can redistribute it and/or modify
12      *  it under the terms of the GNU General Public License as published by
13      *  the Free Software Foundation; either version 2 of the License, or
14      *  (at your option) any later version.
15      *
16      *  This program is distributed in the hope that it will be useful,
17      *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18      *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19      *  GNU General Public License for more details.
20      *
21      *  You should have received a copy of the GNU General Public License
22      *  along with this program; if not, write to the Free Software
23      *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24      */
25     
26     
27     /*
28      * Parse the AML and build an operation tree as most interpreters,
29      * like Perl, do.  Parsing is done by hand rather than with a YACC
30      * generated parser to tightly constrain stack and dynamic memory
31      * usage.  At the same time, parsing is kept flexible and the code
32      * fairly compact by parsing based on a list of AML opcode
33      * templates in Aml_op_info[]
34      */
35     
36     #include "acpi.h"
37     #include "acparser.h"
38     #include "acdispat.h"
39     #include "amlcode.h"
40     #include "acnamesp.h"
41     #include "acdebug.h"
42     #include "acinterp.h"
43     
44     #define _COMPONENT          ACPI_PARSER
45     	 MODULE_NAME         ("psparse")
46     
47     
48     u32                         acpi_gbl_depth = 0;
49     extern u32                  acpi_gbl_scope_depth;
50     
51     
52     /*******************************************************************************
53      *
54      * FUNCTION:    Acpi_ps_get_opcode_size
55      *
56      * PARAMETERS:  Opcode          - An AML opcode
57      *
58      * RETURN:      Size of the opcode, in bytes (1 or 2)
59      *
60      * DESCRIPTION: Get the size of the current opcode.
61      *
62      ******************************************************************************/
63     
64     static u32
65     acpi_ps_get_opcode_size (
66     	u32                     opcode)
67     {
68     
69     	/* Extended (2-byte) opcode if > 255 */
70     
71     	if (opcode > 0x00FF) {
72     		return (2);
73     	}
74     
75     	/* Otherwise, just a single byte opcode */
76     
77     	return (1);
78     }
79     
80     
81     /*******************************************************************************
82      *
83      * FUNCTION:    Acpi_ps_peek_opcode
84      *
85      * PARAMETERS:  Parser_state        - A parser state object
86      *
87      * RETURN:      Status
88      *
89      * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
90      *
91      ******************************************************************************/
92     
93     u16
94     acpi_ps_peek_opcode (
95     	acpi_parse_state        *parser_state)
96     {
97     	u8                      *aml;
98     	u16                     opcode;
99     
100     
101     	aml = parser_state->aml;
102     	opcode = (u16) GET8 (aml);
103     
104     	aml++;
105     
106     
107     	/*
108     	 * Original code special cased LNOTEQUAL, LLESSEQUAL, LGREATEREQUAL.
109     	 * These opcodes are no longer recognized. Instead, they are broken into
110     	 * two opcodes.
111     	 *
112     	 *
113     	 *    if (Opcode == AML_EXTOP
114     	 *       || (Opcode == AML_LNOT
115     	 *          && (GET8 (Aml) == AML_LEQUAL
116     	 *               || GET8 (Aml) == AML_LGREATER
117     	 *               || GET8 (Aml) == AML_LLESS)))
118     	 *
119     	 *     extended Opcode, !=, <=, or >=
120     	 */
121     	if (opcode == AML_EXTOP) {
122     		/* Extended opcode */
123     
124     		opcode = (u16) ((opcode << 8) | GET8 (aml));
125     		aml++;
126     	}
127     
128     	/* don't convert bare name to a namepath */
129     
130     	return (opcode);
131     }
132     
133     
134     /*******************************************************************************
135      *
136      * FUNCTION:    Acpi_ps_create_state
137      *
138      * PARAMETERS:  Aml             - Aml code pointer
139      *              Aml_size        - Length of AML code
140      *
141      * RETURN:      A new parser state object
142      *
143      * DESCRIPTION: Create and initialize a new parser state object
144      *
145      ******************************************************************************/
146     
147     acpi_parse_state *
148     acpi_ps_create_state (
149     	u8                      *aml,
150     	u32                     aml_size)
151     {
152     	acpi_parse_state        *parser_state;
153     
154     
155     	FUNCTION_TRACE ("Ps_create_state");
156     
157     
158     	parser_state = ACPI_MEM_CALLOCATE (sizeof (acpi_parse_state));
159     	if (!parser_state) {
160     		return_PTR (NULL);
161     	}
162     
163     	parser_state->aml      = aml;
164     	parser_state->aml_end  = aml + aml_size;
165     	parser_state->pkg_end  = parser_state->aml_end;
166     	parser_state->aml_start = aml;
167     
168     
169     	return_PTR (parser_state);
170     }
171     
172     
173     /*******************************************************************************
174      *
175      * FUNCTION:    Acpi_ps_find_object
176      *
177      * PARAMETERS:  Opcode          - Current opcode
178      *              Parser_state    - Current state
179      *              Walk_state      - Current state
180      *              *Op             - Where found/new op is returned
181      *
182      * RETURN:      Status
183      *
184      * DESCRIPTION: Find a named object.  Two versions - one to search the parse
185      *              tree (for parser-only applications such as acpidump), another
186      *              to search the ACPI internal namespace (the parse tree may no
187      *              longer exist)
188      *
189      ******************************************************************************/
190     
191     #ifdef PARSER_ONLY
192     
193     acpi_status
194     acpi_ps_find_object (
195     	u16                     opcode,
196     	acpi_parse_object       *op,
197     	acpi_walk_state         *walk_state,
198     	acpi_parse_object       **out_op)
199     {
200     	NATIVE_CHAR             *path;
201     	const acpi_opcode_info  *op_info;
202     
203     
204     	/* We are only interested in opcodes that have an associated name */
205     
206     	op_info = acpi_ps_get_opcode_info (opcode);
207     	if (!(op_info->flags & AML_NAMED)) {
208     		*out_op = op;
209     		return (AE_OK);
210     	}
211     
212     	/* Find the name in the parse tree */
213     
214     	path = acpi_ps_get_next_namestring (walk_state->parser_state);
215     
216     	*out_op = acpi_ps_find (acpi_ps_get_parent_scope (walk_state->parser_state),
217     			  path, opcode, 1);
218     
219     	if (!(*out_op)) {
220     		return (AE_NOT_FOUND);
221     	}
222     
223     	return (AE_OK);
224     }
225     
226     #endif
227     
228     
229     /*******************************************************************************
230      *
231      * FUNCTION:    Acpi_ps_complete_this_op
232      *
233      * PARAMETERS:  Walk_state      - Current State
234      *              Op              - Op to complete
235      *
236      * RETURN:      TRUE if Op and subtree was deleted
237      *
238      * DESCRIPTION: Perform any cleanup at the completion of an Op.
239      *
240      ******************************************************************************/
241     
242     static u8
243     acpi_ps_complete_this_op (
244     	acpi_walk_state         *walk_state,
245     	acpi_parse_object       *op)
246     {
247     #ifndef PARSER_ONLY
248     	acpi_parse_object       *prev;
249     	acpi_parse_object       *next;
250     	const acpi_opcode_info  *op_info;
251     	const acpi_opcode_info  *parent_info;
252     	u32                     opcode_class;
253     	acpi_parse_object       *replacement_op = NULL;
254     
255     
256     	FUNCTION_TRACE_PTR ("Ps_complete_this_op", op);
257     
258     
259     	op_info     = acpi_ps_get_opcode_info (op->opcode);
260     	opcode_class = ACPI_GET_OP_CLASS (op_info);
261     
262     
263     	/* Delete this op and the subtree below it if asked to */
264     
265     	if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) &&
266     		(opcode_class != OPTYPE_CONSTANT)       &&
267     		(opcode_class != OPTYPE_LITERAL)        &&
268     		(opcode_class != OPTYPE_LOCAL_VARIABLE) &&
269     		(opcode_class != OPTYPE_METHOD_ARGUMENT) &&
270     		(opcode_class != OPTYPE_DATA_TERM)      &&
271     		(op->opcode  != AML_INT_NAMEPATH_OP)) {
272     		/* Make sure that we only delete this subtree */
273     
274     		if (op->parent) {
275     			/*
276     			 * Check if we need to replace the operator and its subtree
277     			 * with a return value op (placeholder op)
278     			 */
279     			parent_info = acpi_ps_get_opcode_info (op->parent->opcode);
280     
281     			switch (ACPI_GET_OP_CLASS (parent_info)) {
282     			case OPTYPE_CONTROL:        /* IF, ELSE, WHILE only */
283     				break;
284     
285     			case OPTYPE_NAMED_OBJECT:   /* Scope, method, etc. */
286     
287     				/*
288     				 * These opcodes contain Term_arg operands. The current
289     				 * op must be replace by a placeholder return op
290     				 */
291     				if ((op->parent->opcode == AML_REGION_OP)               ||
292     					(op->parent->opcode == AML_CREATE_FIELD_OP)         ||
293     					(op->parent->opcode == AML_CREATE_BIT_FIELD_OP)     ||
294     					(op->parent->opcode == AML_CREATE_BYTE_FIELD_OP)    ||
295     					(op->parent->opcode == AML_CREATE_WORD_FIELD_OP)    ||
296     					(op->parent->opcode == AML_CREATE_DWORD_FIELD_OP)   ||
297     					(op->parent->opcode == AML_CREATE_QWORD_FIELD_OP)) {
298     					replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
299     					if (!replacement_op) {
300     						return_VALUE (FALSE);
301     					}
302     				}
303     
304     				break;
305     
306     			default:
307     				replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
308     				if (!replacement_op) {
309     					return_VALUE (FALSE);
310     				}
311     			}
312     
313     			/* We must unlink this op from the parent tree */
314     
315     			prev = op->parent->value.arg;
316     			if (prev == op) {
317     				/* This op is the first in the list */
318     
319     				if (replacement_op) {
320     					replacement_op->parent   = op->parent;
321     					replacement_op->value.arg = NULL;
322     					op->parent->value.arg    = replacement_op;
323     					replacement_op->next     = op->next;
324     				}
325     				else {
326     					op->parent->value.arg    = op->next;
327     				}
328     			}
329     
330     			/* Search the parent list */
331     
332     			else while (prev) {
333     				/* Traverse all siblings in the parent's argument list */
334     
335     				next = prev->next;
336     				if (next == op) {
337     					if (replacement_op) {
338     						replacement_op->parent = op->parent;
339     						replacement_op->value.arg = NULL;
340     						prev->next = replacement_op;
341     						replacement_op->next = op->next;
342     						next = NULL;
343     					}
344     					else {
345     						prev->next = op->next;
346     						next = NULL;
347     					}
348     				}
349     
350     				prev = next;
351     			}
352     
353     		}
354     
355     		/* Now we can actually delete the subtree rooted at op */
356     
357     		acpi_ps_delete_parse_tree (op);
358     
359     		return_VALUE (TRUE);
360     	}
361     
362     	return_VALUE (FALSE);
363     
364     #else
365     	return (FALSE);
366     #endif
367     }
368     
369     
370     /*******************************************************************************
371      *
372      * FUNCTION:    Acpi_ps_next_parse_state
373      *
374      * PARAMETERS:  Parser_state        - Current parser state object
375      *
376      * RETURN:
377      *
378      * DESCRIPTION:
379      *
380      ******************************************************************************/
381     
382     static acpi_status
383     acpi_ps_next_parse_state (
384     	acpi_walk_state         *walk_state,
385     	acpi_parse_object       *op,
386     	acpi_status             callback_status)
387     {
388     	acpi_parse_state        *parser_state = walk_state->parser_state;
389     	acpi_status             status = AE_CTRL_PENDING;
390     	u8                      *start;
391     	u32                     package_length;
392     
393     
394     	FUNCTION_TRACE_PTR ("Ps_next_parse_state", op);
395     
396     
397     	switch (callback_status) {
398     	case AE_CTRL_TERMINATE:
399     
400     		/*
401     		 * A control method was terminated via a RETURN statement.
402     		 * The walk of this method is complete.
403     		 */
404     		parser_state->aml = parser_state->aml_end;
405     		status = AE_CTRL_TERMINATE;
406     		break;
407     
408     
409     	case AE_CTRL_PENDING:
410     
411     		/*
412     		 * Predicate of a WHILE was true and the loop just completed an
413     		 * execution.  Go back to the start of the loop and reevaluate the
414     		 * predicate.
415     		 */
416     
417     		/* TBD: How to handle a break within a while. */
418     		/* This code attempts it */
419     
420     		parser_state->aml = walk_state->aml_last_while;
421     		break;
422     
423     
424     	case AE_CTRL_TRUE:
425     		/*
426     		 * Predicate of an IF was true, and we are at the matching ELSE.
427     		 * Just close out this package
428     		 *
429     		 * Note: Parser_state->Aml is modified by the package length procedure
430     		 * TBD: [Investigate] perhaps it shouldn't, too much trouble
431     		 */
432     		start = parser_state->aml;
433     		package_length = acpi_ps_get_next_package_length (parser_state);
434     		parser_state->aml = start + package_length;
435     		break;
436     
437     
438     	case AE_CTRL_FALSE:
439     
440     		/*
441     		 * Either an IF/WHILE Predicate was false or we encountered a BREAK
442     		 * opcode.  In both cases, we do not execute the rest of the
443     		 * package;  We simply close out the parent (finishing the walk of
444     		 * this branch of the tree) and continue execution at the parent
445     		 * level.
446     		 */
447     		parser_state->aml = parser_state->scope->parse_scope.pkg_end;
448     
449     		/* In the case of a BREAK, just force a predicate (if any) to FALSE */
450     
451     		walk_state->control_state->common.value = FALSE;
452     		status = AE_CTRL_END;
453     		break;
454     
455     
456     	case AE_CTRL_TRANSFER:
457     
458     		/*
459     		 * A method call (invocation) -- transfer control
460     		 */
461     		status = AE_CTRL_TRANSFER;
462     		walk_state->prev_op = op;
463     		walk_state->method_call_op = op;
464     		walk_state->method_call_node = (op->value.arg)->node;
465     
466     		/* Will return value (if any) be used by the caller? */
467     
468     		walk_state->return_used = acpi_ds_is_result_used (op, walk_state);
469     		break;
470     
471     
472     	default:
473     		status = callback_status;
474     		if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
475     			status = AE_OK;
476     		}
477     		break;
478     	}
479     
480     	return_ACPI_STATUS (status);
481     }
482     
483     
484     /*******************************************************************************
485      *
486      * FUNCTION:    Acpi_ps_parse_loop
487      *
488      * PARAMETERS:  Parser_state        - Current parser state object
489      *
490      * RETURN:      Status
491      *
492      * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
493      *              a tree of ops.
494      *
495      ******************************************************************************/
496     
497     acpi_status
498     acpi_ps_parse_loop (
499     	acpi_walk_state         *walk_state)
500     {
501     	acpi_status             status = AE_OK;
502     	acpi_parse_object       *op = NULL;     /* current op */
503     	const acpi_opcode_info  *op_info;
504     	acpi_parse_object       *arg = NULL;
505     	acpi_parse2_object      *deferred_op;
506     	u32                     arg_count;      /* push for fixed or var args */
507     	u32                     arg_types = 0;
508     	u32                     aml_offset;
509     	u16                     opcode;
510     	acpi_parse_object       pre_op;
511     	acpi_parse_state        *parser_state;
512     	u8                      *aml_op_start;
513     
514     
515     	FUNCTION_TRACE_PTR ("Ps_parse_loop", walk_state);
516     
517     
518     	parser_state = walk_state->parser_state;
519     
520     #ifndef PARSER_ONLY
521     	if (walk_state->walk_type & WALK_METHOD_RESTART) {
522     		/* We are restarting a preempted control method */
523     
524     		if (acpi_ps_has_completed_scope (parser_state)) {
525     			/*
526     			 * We must check if a predicate to an IF or WHILE statement
527     			 * was just completed
528     			 */
529     			if ((parser_state->scope->parse_scope.op) &&
530     				((parser_state->scope->parse_scope.op->opcode == AML_IF_OP) ||
531     				(parser_state->scope->parse_scope.op->opcode == AML_WHILE_OP)) &&
532     				(walk_state->control_state) &&
533     				(walk_state->control_state->common.state ==
534     					CONTROL_PREDICATE_EXECUTING)) {
535     
536     				/*
537     				 * A predicate was just completed, get the value of the
538     				 * predicate and branch based on that value
539     				 */
540     				status = acpi_ds_get_predicate_value (walk_state, NULL, TRUE);
541     				if (ACPI_FAILURE (status) &&
542     					((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
543     					if (status == AE_AML_NO_RETURN_VALUE) {
544     						ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
545     							"Invoked method did not return a value, %s\n",
546     							acpi_format_exception (status)));
547     
548     					}
549     					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Get_predicate Failed, %s\n",
550     						acpi_format_exception (status)));
551     					return_ACPI_STATUS (status);
552     				}
553     
554     				status = acpi_ps_next_parse_state (walk_state, op, status);
555     			}
556     
557     			acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
558     			ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
559     		}
560     
561     		else if (walk_state->prev_op) {
562     			/* We were in the middle of an op */
563     
564     			op = walk_state->prev_op;
565     			arg_types = walk_state->prev_arg_types;
566     		}
567     	}
568     #endif
569     
570     	/*
571     	 * Iterative parsing loop, while there is more aml to process:
572     	 */
573     	while ((parser_state->aml < parser_state->aml_end) || (op)) {
574     		if (!op) {
575     			/* Get the next opcode from the AML stream */
576     
577     			aml_op_start = parser_state->aml;
578     			aml_offset = parser_state->aml - parser_state->aml_start;
579     			opcode     = acpi_ps_peek_opcode (parser_state);
580     
581     			/*
582     			 * First cut to determine what we have found:
583     			 * 1) A valid AML opcode
584     			 * 2) A name string
585     			 * 3) An unknown/invalid opcode
586     			 */
587     			op_info = acpi_ps_get_opcode_info (opcode);
588     			switch (ACPI_GET_OP_TYPE (op_info)) {
589     			case ACPI_OP_TYPE_OPCODE:
590     
591     				/* Found opcode info, this is a normal opcode */
592     
593     				parser_state->aml += acpi_ps_get_opcode_size (opcode);
594     				arg_types = op_info->parse_args;
595     				break;
596     
597     			case ACPI_OP_TYPE_ASCII:
598     			case ACPI_OP_TYPE_PREFIX:
599     				/*
600     				 * Starts with a valid prefix or ASCII char, this is a name
601     				 * string.  Convert the bare name string to a namepath.
602     				 */
603     				opcode = AML_INT_NAMEPATH_OP;
604     				arg_types = ARGP_NAMESTRING;
605     				break;
606     
607     			case ACPI_OP_TYPE_UNKNOWN:
608     
609     				/* The opcode is unrecognized.  Just skip unknown opcodes */
610     
611     				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
612     					"Found unknown opcode %lX at AML offset %X, ignoring\n",
613     					opcode, aml_offset));
614     
615     				DUMP_BUFFER (parser_state->aml, 128);
616     
617     				/* Assume one-byte bad opcode */
618     
619     				parser_state->aml++;
620     				continue;
621     			}
622     
623     
624     			/* Create Op structure and append to parent's argument list */
625     
626     			if (op_info->flags & AML_NAMED) {
627     				pre_op.value.arg = NULL;
628     				pre_op.opcode = opcode;
629     
630     				while (GET_CURRENT_ARG_TYPE (arg_types) != ARGP_NAME) {
631     					arg = acpi_ps_get_next_arg (parser_state,
632     							 GET_CURRENT_ARG_TYPE (arg_types),
633     							 &arg_count);
634     					acpi_ps_append_arg (&pre_op, arg);
635     					INCREMENT_ARG_LIST (arg_types);
636     				}
637     
638     
639     				/* We know that this arg is a name, move to next arg */
640     
641     				INCREMENT_ARG_LIST (arg_types);
642     
643     				if (walk_state->descending_callback != NULL) {
644     					/*
645     					 * Find the object.  This will either insert the object into
646     					 * the namespace or simply look it up
647     					 */
648     					status = walk_state->descending_callback (opcode, NULL, walk_state, &op);
649     					if (op == NULL) {
650     						continue;
651     					}
652     					status = acpi_ps_next_parse_state (walk_state, op, status);
653     					if (status == AE_CTRL_PENDING) {
654     						status = AE_OK;
655     						goto close_this_op;
656     					}
657     
658     					if (ACPI_FAILURE (status)) {
659     						goto close_this_op;
660     					}
661     				}
662     
663     				acpi_ps_append_arg (op, pre_op.value.arg);
664     				acpi_gbl_depth++;
665     
666     
667     				if (op->opcode == AML_REGION_OP) {
668     					deferred_op = (acpi_parse2_object *) op;
669     
670     					/*
671     					 * Defer final parsing of an Operation_region body,
672     					 * because we don't have enough info in the first pass
673     					 * to parse it correctly (i.e., there may be method
674     					 * calls within the Term_arg elements of the body.
675     					 *
676     					 * However, we must continue parsing because
677     					 * the opregion is not a standalone package --
678     					 * we don't know where the end is at this point.
679     					 *
680     					 * (Length is unknown until parse of the body complete)
681     					 */
682     					deferred_op->data   = aml_op_start;
683     					deferred_op->length = 0;
684     				}
685     			}
686     
687     
688     			else {
689     				/* Not a named opcode, just allocate Op and append to parent */
690     
691     				op_info = acpi_ps_get_opcode_info (opcode);
692     				op = acpi_ps_alloc_op (opcode);
693     				if (!op) {
694     					return_ACPI_STATUS (AE_NO_MEMORY);
695     				}
696     
697     
698     				if (op_info->flags & AML_CREATE) {
699     					/*
700     					 * Backup to beginning of Create_xXXfield declaration
701     					 * Body_length is unknown until we parse the body
702     					 */
703     					deferred_op = (acpi_parse2_object *) op;
704     
705     					deferred_op->data   = aml_op_start;
706     					deferred_op->length = 0;
707     				}
708     
709     				acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
710     
711     				if ((walk_state->descending_callback != NULL)) {
712     					/*
713     					 * Find the object.  This will either insert the object into
714     					 * the namespace or simply look it up
715     					 */
716     					status = walk_state->descending_callback (opcode, op, walk_state, &op);
717     					status = acpi_ps_next_parse_state (walk_state, op, status);
718     					if (status == AE_CTRL_PENDING) {
719     						status = AE_OK;
720     						goto close_this_op;
721     					}
722     
723     					if (ACPI_FAILURE (status)) {
724     						goto close_this_op;
725     					}
726     				}
727     			}
728     
729     			op->aml_offset = aml_offset;
730     
731     			if (op_info) {
732     				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
733     					"Op=%p Opcode=%4.4lX Aml %p Oft=%5.5lX\n",
734     					 op, op->opcode, parser_state->aml, op->aml_offset));
735     			}
736     		}
737     
738     
739     		/* Start Arg_count at zero because we don't know if there are any args yet */
740     
741     		arg_count = 0;
742     
743     
744     		if (arg_types)  /* Are there any arguments that must be processed? */ {
745     			/* get arguments */
746     
747     			switch (op->opcode) {
748     			case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
749     			case AML_WORD_OP:       /* AML_WORDDATA_ARG */
750     			case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
751     			case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
752     			case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
753     
754     				/* fill in constant or string argument directly */
755     
756     				acpi_ps_get_next_simple_arg (parser_state,
757     						 GET_CURRENT_ARG_TYPE (arg_types), op);
758     				break;
759     
760     			case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
761     
762     				acpi_ps_get_next_namepath (parser_state, op, &arg_count, 1);
763     				arg_types = 0;
764     				break;
765     
766     
767     			default:
768     
769     				/* Op is not a constant or string, append each argument */
770     
771     				while (GET_CURRENT_ARG_TYPE (arg_types) && !arg_count) {
772     					aml_offset = parser_state->aml - parser_state->aml_start;
773     					arg = acpi_ps_get_next_arg (parser_state,
774     							 GET_CURRENT_ARG_TYPE (arg_types),
775     							 &arg_count);
776     					if (arg) {
777     						arg->aml_offset = aml_offset;
778     						acpi_ps_append_arg (op, arg);
779     					}
780     
781     					INCREMENT_ARG_LIST (arg_types);
782     				}
783     
784     
785     				/* For a method, save the length and address of the body */
786     
787     				if (op->opcode == AML_METHOD_OP) {
788     					deferred_op = (acpi_parse2_object *) op;
789     
790     					/*
791     					 * Skip parsing of control method or opregion body,
792     					 * because we don't have enough info in the first pass
793     					 * to parse them correctly.
794     					 */
795     					deferred_op->data   = parser_state->aml;
796     					deferred_op->length = (u32) (parser_state->pkg_end -
797     							   parser_state->aml);
798     
799     					/*
800     					 * Skip body of method.  For Op_regions, we must continue
801     					 * parsing because the opregion is not a standalone
802     					 * package (We don't know where the end is).
803     					 */
804     					parser_state->aml   = parser_state->pkg_end;
805     					arg_count           = 0;
806     				}
807     
808     				break;
809     			}
810     		}
811     
812     
813     		/*
814     		 * Zero Arg_count means that all arguments for this op have been processed
815     		 */
816     		if (!arg_count) {
817     			/* completed Op, prepare for next */
818     
819     			op_info = acpi_ps_get_opcode_info (op->opcode);
820     			if (op_info->flags & AML_NAMED) {
821     				if (acpi_gbl_depth) {
822     					acpi_gbl_depth--;
823     				}
824     
825     				if (op->opcode == AML_REGION_OP) {
826     					deferred_op = (acpi_parse2_object *) op;
827     
828     					/*
829     					 * Skip parsing of control method or opregion body,
830     					 * because we don't have enough info in the first pass
831     					 * to parse them correctly.
832     					 *
833     					 * Completed parsing an Op_region declaration, we now
834     					 * know the length.
835     					 */
836     					deferred_op->length = (u32) (parser_state->aml -
837     							   deferred_op->data);
838     				}
839     			}
840     
841     			if (op_info->flags & AML_CREATE) {
842     				/*
843     				 * Backup to beginning of Create_xXXfield declaration (1 for
844     				 * Opcode)
845     				 *
846     				 * Body_length is unknown until we parse the body
847     				 */
848     				deferred_op = (acpi_parse2_object *) op;
849     				deferred_op->length = (u32) (parser_state->aml -
850     						  deferred_op->data);
851     			}
852     
853     			/* This op complete, notify the dispatcher */
854     
855     			if (walk_state->ascending_callback != NULL) {
856     				status = walk_state->ascending_callback (walk_state, op);
857     				status = acpi_ps_next_parse_state (walk_state, op, status);
858     				if (status == AE_CTRL_PENDING) {
859     					status = AE_OK;
860     					goto close_this_op;
861     				}
862     			}
863     
864     
865     close_this_op:
866     
867     			/*
868     			 * Finished one argument of the containing scope
869     			 */
870     			parser_state->scope->parse_scope.arg_count--;
871     
872     			/* Close this Op (may result in parse subtree deletion) */
873     
874     			if (acpi_ps_complete_this_op (walk_state, op)) {
875     				op = NULL;
876     			}
877     
878     
879     			switch (status) {
880     			case AE_OK:
881     				break;
882     
883     
884     			case AE_CTRL_TRANSFER:
885     
886     				/*
887     				 * We are about to transfer to a called method.
888     				 */
889     				walk_state->prev_op = op;
890     				walk_state->prev_arg_types = arg_types;
891     				return_ACPI_STATUS (status);
892     				break;
893     
894     
895     			case AE_CTRL_END:
896     
897     				acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
898     
899     				status = walk_state->ascending_callback (walk_state, op);
900     				status = acpi_ps_next_parse_state (walk_state, op, status);
901     
902     				acpi_ps_complete_this_op (walk_state, op);
903     				op = NULL;
904     				status = AE_OK;
905     				break;
906     
907     
908     			case AE_CTRL_TERMINATE:
909     
910     				status = AE_OK;
911     
912     				/* Clean up */
913     				do {
914     					if (op) {
915     						acpi_ps_complete_this_op (walk_state, op);
916     					}
917     
918     					acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
919     				} while (op);
920     
921     				return_ACPI_STATUS (status);
922     				break;
923     
924     
925     			default:  /* All other non-AE_OK status */
926     
927     				if (op == NULL) {
928     					acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
929     				}
930     				walk_state->prev_op = op;
931     				walk_state->prev_arg_types = arg_types;
932     
933     				/*
934     				 * TEMP:
935     				 */
936     
937     				return_ACPI_STATUS (status);
938     				break;
939     			}
940     
941     			/* This scope complete? */
942     
943     			if (acpi_ps_has_completed_scope (parser_state)) {
944     				acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
945     				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
946     			}
947     
948     			else {
949     				op = NULL;
950     			}
951     
952     		}
953     
954     
955     		/* Arg_count is non-zero */
956     
957     		else {
958     			/* complex argument, push Op and prepare for argument */
959     
960     			acpi_ps_push_scope (parser_state, op, arg_types, arg_count);
961     			op = NULL;
962     		}
963     
964     	} /* while Parser_state->Aml */
965     
966     
967     	/*
968     	 * Complete the last Op (if not completed), and clear the scope stack.
969     	 * It is easily possible to end an AML "package" with an unbounded number
970     	 * of open scopes (such as when several AML blocks are closed with
971     	 * sequential closing braces).  We want to terminate each one cleanly.
972     	 */
973     	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Package complete at Op %p\n", op));
974     	do {
975     		if (op) {
976     			if (walk_state->ascending_callback != NULL) {
977     				status = walk_state->ascending_callback (walk_state, op);
978     				status = acpi_ps_next_parse_state (walk_state, op, status);
979     				if (status == AE_CTRL_PENDING) {
980     					status = AE_OK;
981     					goto close_this_op;
982     				}
983     
984     				if (status == AE_CTRL_TERMINATE) {
985     					status = AE_OK;
986     
987     					/* Clean up */
988     					do {
989     						if (op) {
990     							acpi_ps_complete_this_op (walk_state, op);
991     						}
992     
993     						acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
994     
995     					} while (op);
996     
997     					return_ACPI_STATUS (status);
998     				}
999     
1000     				else if (ACPI_FAILURE (status)) {
1001     					acpi_ps_complete_this_op (walk_state, op);
1002     					return_ACPI_STATUS (status);
1003     				}
1004     			}
1005     
1006     			acpi_ps_complete_this_op (walk_state, op);
1007     		}
1008     
1009     		acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
1010     
1011     	} while (op);
1012     
1013     	return_ACPI_STATUS (status);
1014     }
1015     
1016     
1017     /*******************************************************************************
1018      *
1019      * FUNCTION:    Acpi_ps_parse_aml
1020      *
1021      * PARAMETERS:  Start_scope     - The starting point of the parse.  Becomes the
1022      *                                root of the parsed op tree.
1023      *              Aml             - Pointer to the raw AML code to parse
1024      *              Aml_size        - Length of the AML to parse
1025      *
1026      *
1027      * RETURN:      Status
1028      *
1029      * DESCRIPTION: Parse raw AML and return a tree of ops
1030      *
1031      ******************************************************************************/
1032     
1033     acpi_status
1034     acpi_ps_parse_aml (
1035     	acpi_parse_object       *start_scope,
1036     	u8                      *aml,
1037     	u32                     aml_size,
1038     	u32                     parse_flags,
1039     	acpi_namespace_node     *method_node,
1040     	acpi_operand_object     **params,
1041     	acpi_operand_object     **caller_return_desc,
1042     	acpi_parse_downwards    descending_callback,
1043     	acpi_parse_upwards      ascending_callback)
1044     {
1045     	acpi_status             status;
1046     	acpi_parse_state        *parser_state;
1047     	acpi_walk_state         *walk_state;
1048     	acpi_walk_list          walk_list;
1049     	acpi_walk_list          *prev_walk_list = acpi_gbl_current_walk_list;
1050     	acpi_operand_object     *return_desc;
1051     	acpi_operand_object     *mth_desc = NULL;
1052     
1053     
1054     	FUNCTION_TRACE ("Ps_parse_aml");
1055     
1056     	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with Scope=%p Aml=%p size=%lX\n",
1057     		start_scope, aml, aml_size));
1058     
1059     
1060     	/* Create and initialize a new parser state */
1061     
1062     	parser_state = acpi_ps_create_state (aml, aml_size);
1063     	if (!parser_state) {
1064     		return_ACPI_STATUS (AE_NO_MEMORY);
1065     	}
1066     
1067     	acpi_ps_init_scope (parser_state, start_scope);
1068     
1069     	if (method_node) {
1070     		mth_desc = acpi_ns_get_attached_object (method_node);
1071     	}
1072     
1073     	/* Create and initialize a new walk list */
1074     
1075     	walk_list.walk_state = NULL;
1076     	walk_list.acquired_mutex_list.prev = NULL;
1077     	walk_list.acquired_mutex_list.next = NULL;
1078     
1079     	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, parser_state->start_op,
1080     			   mth_desc, &walk_list);
1081     	if (!walk_state) {
1082     		status = AE_NO_MEMORY;
1083     		goto cleanup;
1084     	}
1085     
1086     	walk_state->method_node         = method_node;
1087     	walk_state->parser_state        = parser_state;
1088     	walk_state->parse_flags         = parse_flags;
1089     	walk_state->descending_callback = descending_callback;
1090     	walk_state->ascending_callback  = ascending_callback;
1091     
1092     	/* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter
1093     	 */
1094     	acpi_gbl_current_walk_list = &walk_list;
1095     
1096     
1097     	if (method_node) {
1098     		parser_state->start_node = method_node;
1099     		walk_state->walk_type   = WALK_METHOD;
1100     
1101     		/* Push start scope on scope stack and make it current  */
1102     
1103     		status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state);
1104     		if (ACPI_FAILURE (status)) {
1105     			return_ACPI_STATUS (status);
1106     		}
1107     
1108     		/* Init arguments if this is a control method */
1109     		/* TBD: [Restructure] add walkstate as a param */
1110     
1111     		acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state);
1112     	}
1113     
1114     	else {
1115     		/* Setup the current scope */
1116     
1117     		parser_state->start_node = parser_state->start_op->node;
1118     		if (parser_state->start_node) {
1119     			/* Push start scope on scope stack and make it current  */
1120     
1121     			status = acpi_ds_scope_stack_push (parser_state->start_node,
1122     					  parser_state->start_node->type, walk_state);
1123     			if (ACPI_FAILURE (status)) {
1124     				goto cleanup;
1125     			}
1126     
1127     		}
1128     	}
1129     
1130     	/*
1131     	 * Execute the walk loop as long as there is a valid Walk State.  This
1132     	 * handles nested control method invocations without recursion.
1133     	 */
1134     	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", walk_state));
1135     
1136     	status = AE_OK;
1137     	while (walk_state) {
1138     		if (ACPI_SUCCESS (status)) {
1139     			status = acpi_ps_parse_loop (walk_state);
1140     		}
1141     
1142     		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1143     			"Completed one call to walk loop, State=%p\n", walk_state));
1144     
1145     		if (status == AE_CTRL_TRANSFER) {
1146     			/*
1147     			 * A method call was detected.
1148     			 * Transfer control to the called control method
1149     			 */
1150     			status = acpi_ds_call_control_method (&walk_list, walk_state, NULL);
1151     
1152     			/*
1153     			 * If the transfer to the new method method call worked, a new walk
1154     			 * state was created -- get it
1155     			 */
1156     			walk_state = acpi_ds_get_current_walk_state (&walk_list);
1157     			continue;
1158     		}
1159     
1160     		else if (status == AE_CTRL_TERMINATE) {
1161     			status = AE_OK;
1162     		}
1163     
1164     		/* We are done with this walk, move on to the parent if any */
1165     
1166     		walk_state = acpi_ds_pop_walk_state (&walk_list);
1167     
1168     		/* Extract return value before we delete Walk_state */
1169     
1170     		return_desc = walk_state->return_desc;
1171     
1172     		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Return_value=%p, State=%p\n",
1173     			walk_state->return_desc, walk_state));
1174     
1175     		/* Reset the current scope to the beginning of scope stack */
1176     
1177     		acpi_ds_scope_stack_clear (walk_state);
1178     
1179     		/*
1180     		 * If we just returned from the execution of a control method,
1181     		 * there's lots of cleanup to do
1182     		 */
1183     		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) {
1184     			acpi_ds_terminate_control_method (walk_state);
1185     		}
1186     
1187     		/* Delete this walk state and all linked control states */
1188     
1189     		acpi_ps_cleanup_scope (walk_state->parser_state);
1190     		ACPI_MEM_FREE (walk_state->parser_state);
1191     		acpi_ds_delete_walk_state (walk_state);
1192     
1193     		/* Check if we have restarted a preempted walk */
1194     
1195     		walk_state = acpi_ds_get_current_walk_state (&walk_list);
1196     		if (walk_state &&
1197     			ACPI_SUCCESS (status)) {
1198     			/* There is another walk state, restart it */
1199     
1200     			/*
1201     			 * If the method returned value is not used by the parent,
1202     			 * The object is deleted
1203     			 */
1204     			acpi_ds_restart_control_method (walk_state, return_desc);
1205     			walk_state->walk_type |= WALK_METHOD_RESTART;
1206     		}
1207     
1208     		/*
1209     		 * Just completed a 1st-level method, save the final internal return
1210     		 * value (if any)
1211     		 */
1212     		else if (caller_return_desc) {
1213     			*caller_return_desc = return_desc; /* NULL if no return value */
1214     		}
1215     
1216     		else if (return_desc) {
1217     			/* Caller doesn't want it, must delete it */
1218     
1219     			acpi_ut_remove_reference (return_desc);
1220     		}
1221     	}
1222     
1223     
1224     	/* Normal exit */
1225     
1226     	acpi_ex_release_all_mutexes ((acpi_operand_object *) &walk_list.acquired_mutex_list);
1227     	acpi_gbl_current_walk_list = prev_walk_list;
1228     	return_ACPI_STATUS (status);
1229     
1230     
1231     cleanup:
1232     
1233     	/* Cleanup */
1234     
1235     	acpi_ds_delete_walk_state (walk_state);
1236     	acpi_ps_cleanup_scope (parser_state);
1237     	ACPI_MEM_FREE (parser_state);
1238     
1239     	acpi_ex_release_all_mutexes ((acpi_operand_object *)&walk_list.acquired_mutex_list);
1240     	acpi_gbl_current_walk_list = prev_walk_list;
1241     
1242     	return_ACPI_STATUS (status);
1243     }
1244     
1245     
1246