1 /******************************************************************************
3 * Module Name: psparse - Parser top level AML parse routines
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
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.
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.
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
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[]
44 #define _COMPONENT ACPI_PARSER
45 MODULE_NAME ("psparse")
48 u32 acpi_gbl_depth = 0;
49 extern u32 acpi_gbl_scope_depth;
52 /*******************************************************************************
54 * FUNCTION: Acpi_ps_get_opcode_size
56 * PARAMETERS: Opcode - An AML opcode
58 * RETURN: Size of the opcode, in bytes (1 or 2)
60 * DESCRIPTION: Get the size of the current opcode.
62 ******************************************************************************/
65 acpi_ps_get_opcode_size (
69 /* Extended (2-byte) opcode if > 255 */
71 if (opcode > 0x00FF) {
75 /* Otherwise, just a single byte opcode */
81 /*******************************************************************************
83 * FUNCTION: Acpi_ps_peek_opcode
85 * PARAMETERS: Parser_state - A parser state object
89 * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
91 ******************************************************************************/
95 acpi_parse_state *parser_state)
101 aml = parser_state->aml;
102 opcode = (u16) GET8 (aml);
108 * Original code special cased LNOTEQUAL, LLESSEQUAL, LGREATEREQUAL.
109 * These opcodes are no longer recognized. Instead, they are broken into
113 * if (Opcode == AML_EXTOP
114 * || (Opcode == AML_LNOT
115 * && (GET8 (Aml) == AML_LEQUAL
116 * || GET8 (Aml) == AML_LGREATER
117 * || GET8 (Aml) == AML_LLESS)))
119 * extended Opcode, !=, <=, or >=
121 if (opcode == AML_EXTOP) {
122 /* Extended opcode */
124 opcode = (u16) ((opcode << 8) | GET8 (aml));
132 /*******************************************************************************
134 * FUNCTION: Acpi_ps_find_object
136 * PARAMETERS: Opcode - Current opcode
137 * Parser_state - Current state
138 * Walk_state - Current state
139 * *Op - Where found/new op is returned
143 * DESCRIPTION: Find a named object. Two versions - one to search the parse
144 * tree (for parser-only applications such as acpidump), another
145 * to search the ACPI internal namespace (the parse tree may no
148 ******************************************************************************/
153 acpi_ps_find_object (
154 acpi_walk_state *walk_state,
155 acpi_parse_object **out_op)
160 /* We are only interested in opcodes that have an associated name */
162 if (!(walk_state->op_info->flags & AML_NAMED)) {
163 *out_op = walk_state->op;
167 /* Find the name in the parse tree */
169 path = acpi_ps_get_next_namestring (&walk_state->parser_state);
171 *out_op = acpi_ps_find (acpi_ps_get_parent_scope (&walk_state->parser_state),
172 path, walk_state->opcode, 1);
175 return (AE_NOT_FOUND);
184 /*******************************************************************************
186 * FUNCTION: Acpi_ps_complete_this_op
188 * PARAMETERS: Walk_state - Current State
189 * Op - Op to complete
191 * RETURN: TRUE if Op and subtree was deleted
193 * DESCRIPTION: Perform any cleanup at the completion of an Op.
195 ******************************************************************************/
198 acpi_ps_complete_this_op (
199 acpi_walk_state *walk_state,
200 acpi_parse_object *op)
203 acpi_parse_object *prev;
204 acpi_parse_object *next;
205 const acpi_opcode_info *parent_info;
206 acpi_parse_object *replacement_op = NULL;
209 FUNCTION_TRACE_PTR ("Ps_complete_this_op", op);
212 /* Delete this op and the subtree below it if asked to */
214 if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) &&
215 (walk_state->op_info->class != AML_CLASS_ARGUMENT)) {
216 /* Make sure that we only delete this subtree */
220 * Check if we need to replace the operator and its subtree
221 * with a return value op (placeholder op)
223 parent_info = acpi_ps_get_opcode_info (op->parent->opcode);
225 switch (parent_info->class) {
226 case AML_CLASS_CONTROL: /* IF, ELSE, WHILE only */
229 case AML_CLASS_NAMED_OBJECT: /* Scope, method, etc. */
230 case AML_CLASS_CREATE:
233 * These opcodes contain Term_arg operands. The current
234 * op must be replace by a placeholder return op
236 if ((op->parent->opcode == AML_REGION_OP) ||
237 (op->parent->opcode == AML_CREATE_FIELD_OP) ||
238 (op->parent->opcode == AML_CREATE_BIT_FIELD_OP) ||
239 (op->parent->opcode == AML_CREATE_BYTE_FIELD_OP) ||
240 (op->parent->opcode == AML_CREATE_WORD_FIELD_OP) ||
241 (op->parent->opcode == AML_CREATE_DWORD_FIELD_OP) ||
242 (op->parent->opcode == AML_CREATE_QWORD_FIELD_OP)) {
243 replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
244 if (!replacement_op) {
245 return_VALUE (FALSE);
252 replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
253 if (!replacement_op) {
254 return_VALUE (FALSE);
258 /* We must unlink this op from the parent tree */
260 prev = op->parent->value.arg;
262 /* This op is the first in the list */
264 if (replacement_op) {
265 replacement_op->parent = op->parent;
266 replacement_op->value.arg = NULL;
267 op->parent->value.arg = replacement_op;
268 replacement_op->next = op->next;
271 op->parent->value.arg = op->next;
275 /* Search the parent list */
278 /* Traverse all siblings in the parent's argument list */
282 if (replacement_op) {
283 replacement_op->parent = op->parent;
284 replacement_op->value.arg = NULL;
285 prev->next = replacement_op;
286 replacement_op->next = op->next;
290 prev->next = op->next;
300 /* Now we can actually delete the subtree rooted at op */
302 acpi_ps_delete_parse_tree (op);
307 return_VALUE (FALSE);
315 /*******************************************************************************
317 * FUNCTION: Acpi_ps_next_parse_state
319 * PARAMETERS: Parser_state - Current parser state object
325 ******************************************************************************/
328 acpi_ps_next_parse_state (
329 acpi_walk_state *walk_state,
330 acpi_parse_object *op,
331 acpi_status callback_status)
333 acpi_parse_state *parser_state = &walk_state->parser_state;
334 acpi_status status = AE_CTRL_PENDING;
339 FUNCTION_TRACE_PTR ("Ps_next_parse_state", op);
342 switch (callback_status) {
343 case AE_CTRL_TERMINATE:
346 * A control method was terminated via a RETURN statement.
347 * The walk of this method is complete.
349 parser_state->aml = parser_state->aml_end;
350 status = AE_CTRL_TERMINATE;
354 case AE_CTRL_PENDING:
357 * Predicate of a WHILE was true and the loop just completed an
358 * execution. Go back to the start of the loop and reevaluate the
362 /* TBD: How to handle a break within a while. */
363 /* This code attempts it */
365 parser_state->aml = walk_state->aml_last_while;
371 * Predicate of an IF was true, and we are at the matching ELSE.
372 * Just close out this package
374 * Note: Parser_state->Aml is modified by the package length procedure
375 * TBD: [Investigate] perhaps it shouldn't, too much trouble
377 start = parser_state->aml;
378 package_length = acpi_ps_get_next_package_length (parser_state);
379 parser_state->aml = start + package_length;
386 * Either an IF/WHILE Predicate was false or we encountered a BREAK
387 * opcode. In both cases, we do not execute the rest of the
388 * package; We simply close out the parent (finishing the walk of
389 * this branch of the tree) and continue execution at the parent
392 parser_state->aml = parser_state->scope->parse_scope.pkg_end;
394 /* In the case of a BREAK, just force a predicate (if any) to FALSE */
396 walk_state->control_state->common.value = FALSE;
397 status = AE_CTRL_END;
401 case AE_CTRL_TRANSFER:
404 * A method call (invocation) -- transfer control
406 status = AE_CTRL_TRANSFER;
407 walk_state->prev_op = op;
408 walk_state->method_call_op = op;
409 walk_state->method_call_node = (op->value.arg)->node;
411 /* Will return value (if any) be used by the caller? */
413 walk_state->return_used = acpi_ds_is_result_used (op, walk_state);
418 status = callback_status;
419 if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
425 return_ACPI_STATUS (status);
429 /*******************************************************************************
431 * FUNCTION: Acpi_ps_parse_loop
433 * PARAMETERS: Parser_state - Current parser state object
437 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
440 ******************************************************************************/
444 acpi_walk_state *walk_state)
446 acpi_status status = AE_OK;
447 acpi_parse_object *op = NULL; /* current op */
448 acpi_parse_object *arg = NULL;
449 acpi_parse_object pre_op;
450 acpi_parse_state *parser_state;
454 FUNCTION_TRACE_PTR ("Ps_parse_loop", walk_state);
457 parser_state = &walk_state->parser_state;
458 walk_state->arg_types = 0;
461 if (walk_state->walk_type & WALK_METHOD_RESTART) {
462 /* We are restarting a preempted control method */
464 if (acpi_ps_has_completed_scope (parser_state)) {
466 * We must check if a predicate to an IF or WHILE statement
469 if ((parser_state->scope->parse_scope.op) &&
470 ((parser_state->scope->parse_scope.op->opcode == AML_IF_OP) ||
471 (parser_state->scope->parse_scope.op->opcode == AML_WHILE_OP)) &&
472 (walk_state->control_state) &&
473 (walk_state->control_state->common.state ==
474 CONTROL_PREDICATE_EXECUTING)) {
477 * A predicate was just completed, get the value of the
478 * predicate and branch based on that value
480 walk_state->op = NULL;
481 status = acpi_ds_get_predicate_value (walk_state, TRUE);
482 if (ACPI_FAILURE (status) &&
483 ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
484 if (status == AE_AML_NO_RETURN_VALUE) {
485 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
486 "Invoked method did not return a value, %s\n",
487 acpi_format_exception (status)));
490 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Get_predicate Failed, %s\n",
491 acpi_format_exception (status)));
492 return_ACPI_STATUS (status);
495 status = acpi_ps_next_parse_state (walk_state, op, status);
498 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
499 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
502 else if (walk_state->prev_op) {
503 /* We were in the middle of an op */
505 op = walk_state->prev_op;
506 walk_state->arg_types = walk_state->prev_arg_types;
512 * Iterative parsing loop, while there is more aml to process:
514 while ((parser_state->aml < parser_state->aml_end) || (op)) {
516 /* Get the next opcode from the AML stream */
518 aml_op_start = parser_state->aml;
519 walk_state->aml_offset = parser_state->aml - parser_state->aml_start;
520 walk_state->opcode = acpi_ps_peek_opcode (parser_state);
523 * First cut to determine what we have found:
524 * 1) A valid AML opcode
526 * 3) An unknown/invalid opcode
528 walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
529 switch (walk_state->op_info->class) {
530 case AML_CLASS_ASCII:
531 case AML_CLASS_PREFIX:
533 * Starts with a valid prefix or ASCII char, this is a name
534 * string. Convert the bare name string to a namepath.
536 walk_state->opcode = AML_INT_NAMEPATH_OP;
537 walk_state->arg_types = ARGP_NAMESTRING;
540 case AML_CLASS_UNKNOWN:
542 /* The opcode is unrecognized. Just skip unknown opcodes */
544 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
545 "Found unknown opcode %X at AML offset %X, ignoring\n",
546 walk_state->opcode, walk_state->aml_offset));
548 DUMP_BUFFER (parser_state->aml, 128);
550 /* Assume one-byte bad opcode */
557 /* Found opcode info, this is a normal opcode */
559 parser_state->aml += acpi_ps_get_opcode_size (walk_state->opcode);
560 walk_state->arg_types = walk_state->op_info->parse_args;
566 /* Create Op structure and append to parent's argument list */
568 if (walk_state->op_info->flags & AML_NAMED) {
569 pre_op.value.arg = NULL;
570 pre_op.opcode = walk_state->opcode;
572 while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME) {
573 arg = acpi_ps_get_next_arg (parser_state,
574 GET_CURRENT_ARG_TYPE (walk_state->arg_types),
575 &walk_state->arg_count);
576 acpi_ps_append_arg (&pre_op, arg);
577 INCREMENT_ARG_LIST (walk_state->arg_types);
581 /* We know that this arg is a name, move to next arg */
583 INCREMENT_ARG_LIST (walk_state->arg_types);
585 if (walk_state->descending_callback != NULL) {
587 * Find the object. This will either insert the object into
588 * the namespace or simply look it up
590 walk_state->op = NULL;
592 status = walk_state->descending_callback (walk_state, &op);
594 /* TBD: check status here? */
596 if (ACPI_FAILURE (status)) {
597 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n",
598 acpi_format_exception (status)));
605 status = acpi_ps_next_parse_state (walk_state, op, status);
606 if (status == AE_CTRL_PENDING) {
611 if (ACPI_FAILURE (status)) {
616 acpi_ps_append_arg (op, pre_op.value.arg);
620 if (op->opcode == AML_REGION_OP) {
622 * Defer final parsing of an Operation_region body,
623 * because we don't have enough info in the first pass
624 * to parse it correctly (i.e., there may be method
625 * calls within the Term_arg elements of the body.
627 * However, we must continue parsing because
628 * the opregion is not a standalone package --
629 * we don't know where the end is at this point.
631 * (Length is unknown until parse of the body complete)
633 ((acpi_parse2_object * ) op)->data = aml_op_start;
634 ((acpi_parse2_object * ) op)->length = 0;
640 /* Not a named opcode, just allocate Op and append to parent */
642 walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
643 op = acpi_ps_alloc_op (walk_state->opcode);
645 return_ACPI_STATUS (AE_NO_MEMORY);
649 if (walk_state->op_info->flags & AML_CREATE) {
651 * Backup to beginning of Create_xXXfield declaration
652 * Body_length is unknown until we parse the body
654 ((acpi_parse2_object * ) op)->data = aml_op_start;
655 ((acpi_parse2_object * ) op)->length = 0;
658 acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
660 if ((walk_state->descending_callback != NULL)) {
662 * Find the object. This will either insert the object into
663 * the namespace or simply look it up
667 status = walk_state->descending_callback (walk_state, &op);
668 status = acpi_ps_next_parse_state (walk_state, op, status);
669 if (status == AE_CTRL_PENDING) {
674 if (ACPI_FAILURE (status)) {
680 op->aml_offset = walk_state->aml_offset;
682 if (walk_state->op_info) {
683 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
684 "Op=%p Opcode=%4.4X Aml %p Oft=%5.5X\n",
685 op, op->opcode, parser_state->aml, op->aml_offset));
690 /* Start Arg_count at zero because we don't know if there are any args yet */
692 walk_state->arg_count = 0;
695 if (walk_state->arg_types) /* Are there any arguments that must be processed? */ {
698 switch (op->opcode) {
699 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
700 case AML_WORD_OP: /* AML_WORDDATA_ARG */
701 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
702 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
703 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
705 /* fill in constant or string argument directly */
707 acpi_ps_get_next_simple_arg (parser_state,
708 GET_CURRENT_ARG_TYPE (walk_state->arg_types), op);
711 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
713 acpi_ps_get_next_namepath (parser_state, op, &walk_state->arg_count, 1);
714 walk_state->arg_types = 0;
720 /* Op is not a constant or string, append each argument */
722 while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && !walk_state->arg_count) {
723 walk_state->aml_offset = parser_state->aml - parser_state->aml_start;
724 arg = acpi_ps_get_next_arg (parser_state,
725 GET_CURRENT_ARG_TYPE (walk_state->arg_types),
726 &walk_state->arg_count);
728 arg->aml_offset = walk_state->aml_offset;
729 acpi_ps_append_arg (op, arg);
732 INCREMENT_ARG_LIST (walk_state->arg_types);
736 /* For a method, save the length and address of the body */
738 if (op->opcode == AML_METHOD_OP) {
740 * Skip parsing of control method or opregion body,
741 * because we don't have enough info in the first pass
742 * to parse them correctly.
744 ((acpi_parse2_object * ) op)->data = parser_state->aml;
745 ((acpi_parse2_object * ) op)->length = (u32) (parser_state->pkg_end -
749 * Skip body of method. For Op_regions, we must continue
750 * parsing because the opregion is not a standalone
751 * package (We don't know where the end is).
753 parser_state->aml = parser_state->pkg_end;
754 walk_state->arg_count = 0;
763 * Zero Arg_count means that all arguments for this op have been processed
765 if (!walk_state->arg_count) {
766 /* completed Op, prepare for next */
768 walk_state->op_info = acpi_ps_get_opcode_info (op->opcode);
769 if (walk_state->op_info->flags & AML_NAMED) {
770 if (acpi_gbl_depth) {
774 if (op->opcode == AML_REGION_OP) {
776 * Skip parsing of control method or opregion body,
777 * because we don't have enough info in the first pass
778 * to parse them correctly.
780 * Completed parsing an Op_region declaration, we now
783 ((acpi_parse2_object * ) op)->length = (u32) (parser_state->aml -
784 ((acpi_parse2_object * ) op)->data);
788 if (walk_state->op_info->flags & AML_CREATE) {
790 * Backup to beginning of Create_xXXfield declaration (1 for
793 * Body_length is unknown until we parse the body
795 ((acpi_parse2_object * ) op)->length = (u32) (parser_state->aml -
796 ((acpi_parse2_object * ) op)->data);
799 /* This op complete, notify the dispatcher */
801 if (walk_state->ascending_callback != NULL) {
803 walk_state->opcode = op->opcode;
805 status = walk_state->ascending_callback (walk_state);
806 status = acpi_ps_next_parse_state (walk_state, op, status);
807 if (status == AE_CTRL_PENDING) {
817 * Finished one argument of the containing scope
819 parser_state->scope->parse_scope.arg_count--;
821 /* Close this Op (may result in parse subtree deletion) */
823 if (acpi_ps_complete_this_op (walk_state, op)) {
833 case AE_CTRL_TRANSFER:
836 * We are about to transfer to a called method.
838 walk_state->prev_op = op;
839 walk_state->prev_arg_types = walk_state->arg_types;
840 return_ACPI_STATUS (status);
846 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
849 walk_state->op_info = acpi_ps_get_opcode_info (op->opcode);
850 walk_state->opcode = op->opcode;
852 status = walk_state->ascending_callback (walk_state);
853 status = acpi_ps_next_parse_state (walk_state, op, status);
855 acpi_ps_complete_this_op (walk_state, op);
861 case AE_CTRL_TERMINATE:
868 acpi_ps_complete_this_op (walk_state, op);
871 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
874 return_ACPI_STATUS (status);
878 default: /* All other non-AE_OK status */
881 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
883 walk_state->prev_op = op;
884 walk_state->prev_arg_types = walk_state->arg_types;
890 return_ACPI_STATUS (status);
894 /* This scope complete? */
896 if (acpi_ps_has_completed_scope (parser_state)) {
897 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
898 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
908 /* Arg_count is non-zero */
911 /* complex argument, push Op and prepare for argument */
913 acpi_ps_push_scope (parser_state, op, walk_state->arg_types, walk_state->arg_count);
917 } /* while Parser_state->Aml */
921 * Complete the last Op (if not completed), and clear the scope stack.
922 * It is easily possible to end an AML "package" with an unbounded number
923 * of open scopes (such as when several ASL blocks are closed with
924 * sequential closing braces). We want to terminate each one cleanly.
926 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", op));
929 if (walk_state->ascending_callback != NULL) {
931 walk_state->op_info = acpi_ps_get_opcode_info (op->opcode);
932 walk_state->opcode = op->opcode;
934 status = walk_state->ascending_callback (walk_state);
935 status = acpi_ps_next_parse_state (walk_state, op, status);
936 if (status == AE_CTRL_PENDING) {
941 if (status == AE_CTRL_TERMINATE) {
947 acpi_ps_complete_this_op (walk_state, op);
950 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
954 return_ACPI_STATUS (status);
957 else if (ACPI_FAILURE (status)) {
958 acpi_ps_complete_this_op (walk_state, op);
959 return_ACPI_STATUS (status);
963 acpi_ps_complete_this_op (walk_state, op);
966 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
970 return_ACPI_STATUS (status);
974 /*******************************************************************************
976 * FUNCTION: Acpi_ps_parse_aml
978 * PARAMETERS: Start_scope - The starting point of the parse. Becomes the
979 * root of the parsed op tree.
980 * Aml - Pointer to the raw AML code to parse
981 * Aml_size - Length of the AML to parse
986 * DESCRIPTION: Parse raw AML and return a tree of ops
988 ******************************************************************************/
992 acpi_walk_state *walk_state)
995 acpi_walk_list walk_list;
996 acpi_walk_list *prev_walk_list = acpi_gbl_current_walk_list;
997 acpi_walk_state *previous_walk_state;
1000 FUNCTION_TRACE ("Ps_parse_aml");
1002 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with Walk_state=%p Aml=%p size=%X\n",
1003 walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size));
1006 /* Create and initialize a new walk list */
1008 walk_list.walk_state = NULL;
1009 walk_list.acquired_mutex_list.prev = NULL;
1010 walk_list.acquired_mutex_list.next = NULL;
1012 walk_state->walk_list = &walk_list;
1013 acpi_ds_push_walk_state (walk_state, &walk_list);
1016 /* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter
1018 acpi_gbl_current_walk_list = &walk_list;
1021 * Execute the walk loop as long as there is a valid Walk State. This
1022 * handles nested control method invocations without recursion.
1024 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", walk_state));
1027 while (walk_state) {
1028 if (ACPI_SUCCESS (status)) {
1030 * The Parse_loop executes AML until the method terminates
1031 * or calls another method.
1033 status = acpi_ps_parse_loop (walk_state);
1036 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1037 "Completed one call to walk loop, State=%p\n", walk_state));
1039 if (status == AE_CTRL_TRANSFER) {
1041 * A method call was detected.
1042 * Transfer control to the called control method
1044 status = acpi_ds_call_control_method (&walk_list, walk_state, NULL);
1047 * If the transfer to the new method method call worked, a new walk
1048 * state was created -- get it
1050 walk_state = acpi_ds_get_current_walk_state (&walk_list);
1054 else if (status == AE_CTRL_TERMINATE) {
1058 /* We are done with this walk, move on to the parent if any */
1060 walk_state = acpi_ds_pop_walk_state (&walk_list);
1062 /* Reset the current scope to the beginning of scope stack */
1064 acpi_ds_scope_stack_clear (walk_state);
1067 * If we just returned from the execution of a control method,
1068 * there's lots of cleanup to do
1070 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) {
1071 acpi_ds_terminate_control_method (walk_state);
1074 /* Delete this walk state and all linked control states */
1076 acpi_ps_cleanup_scope (&walk_state->parser_state);
1078 previous_walk_state = walk_state;
1080 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Return_value=%p, State=%p\n",
1081 walk_state->return_desc, walk_state));
1083 /* Check if we have restarted a preempted walk */
1085 walk_state = acpi_ds_get_current_walk_state (&walk_list);
1087 if (ACPI_SUCCESS (status)) {
1088 /* There is another walk state, restart it */
1091 * If the method returned value is not used by the parent,
1092 * The object is deleted
1094 acpi_ds_restart_control_method (walk_state, previous_walk_state->return_desc);
1095 walk_state->walk_type |= WALK_METHOD_RESTART;
1100 * Just completed a 1st-level method, save the final internal return
1103 else if (previous_walk_state->caller_return_desc) {
1104 *(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc; /* NULL if no return value */
1107 else if (previous_walk_state->return_desc) {
1108 /* Caller doesn't want it, must delete it */
1110 acpi_ut_remove_reference (previous_walk_state->return_desc);
1113 acpi_ds_delete_walk_state (previous_walk_state);
1119 acpi_ex_release_all_mutexes ((acpi_operand_object *) &walk_list.acquired_mutex_list);
1120 acpi_gbl_current_walk_list = prev_walk_list;
1121 return_ACPI_STATUS (status);