1 /******************************************************************************
3 * Module Name: psloop - Main AML parse loop
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2012, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
45 * Parse the AML and build an operation tree as most interpreters, (such as
46 * Perl) do. Parsing is done by hand rather than with a YACC generated parser
47 * to tightly constrain stack and dynamic memory usage. Parsing is kept
48 * flexible and the code fairly compact by parsing based on a list of AML
49 * opcode templates in aml_op_info[].
52 #include <acpi/acpi.h>
58 #define _COMPONENT ACPI_PARSER
59 ACPI_MODULE_NAME("psloop")
61 static u32 acpi_gbl_depth = 0;
63 /* Local prototypes */
65 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
68 acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
70 union acpi_parse_object *unnamed_op,
71 union acpi_parse_object **op);
74 acpi_ps_create_op(struct acpi_walk_state *walk_state,
75 u8 * aml_op_start, union acpi_parse_object **new_op);
78 acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
79 u8 * aml_op_start, union acpi_parse_object *op);
82 acpi_ps_complete_op(struct acpi_walk_state *walk_state,
83 union acpi_parse_object **op, acpi_status status);
86 acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
87 union acpi_parse_object *op, acpi_status status);
90 acpi_ps_link_module_code(union acpi_parse_object *parent_op,
91 u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
93 /*******************************************************************************
95 * FUNCTION: acpi_ps_get_aml_opcode
97 * PARAMETERS: walk_state - Current state
101 * DESCRIPTION: Extract the next AML opcode from the input stream.
103 ******************************************************************************/
105 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
108 ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
110 walk_state->aml_offset =
111 (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
112 walk_state->parser_state.aml_start);
113 walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
116 * First cut to determine what we have found:
117 * 1) A valid AML opcode
119 * 3) An unknown/invalid opcode
121 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
123 switch (walk_state->op_info->class) {
124 case AML_CLASS_ASCII:
125 case AML_CLASS_PREFIX:
127 * Starts with a valid prefix or ASCII char, this is a name
128 * string. Convert the bare name string to a namepath.
130 walk_state->opcode = AML_INT_NAMEPATH_OP;
131 walk_state->arg_types = ARGP_NAMESTRING;
134 case AML_CLASS_UNKNOWN:
136 /* The opcode is unrecognized. Complain and skip unknown opcodes */
138 if (walk_state->pass_number == 2) {
140 "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
142 (u32)(walk_state->aml_offset +
143 sizeof(struct acpi_table_header))));
145 ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
148 #ifdef ACPI_ASL_COMPILER
150 * This is executed for the disassembler only. Output goes
151 * to the disassembled ASL output file.
154 ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
156 (u32)(walk_state->aml_offset +
157 sizeof(struct acpi_table_header)));
159 /* Dump the context surrounding the invalid opcode */
161 acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
162 aml - 16), 48, DB_BYTE_DISPLAY,
163 (walk_state->aml_offset +
164 sizeof(struct acpi_table_header) -
166 acpi_os_printf(" */\n");
170 /* Increment past one-byte or two-byte opcode */
172 walk_state->parser_state.aml++;
173 if (walk_state->opcode > 0xFF) { /* Can only happen if first byte is 0x5B */
174 walk_state->parser_state.aml++;
177 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
181 /* Found opcode info, this is a normal opcode */
183 walk_state->parser_state.aml +=
184 acpi_ps_get_opcode_size(walk_state->opcode);
185 walk_state->arg_types = walk_state->op_info->parse_args;
189 return_ACPI_STATUS(AE_OK);
192 /*******************************************************************************
194 * FUNCTION: acpi_ps_build_named_op
196 * PARAMETERS: walk_state - Current state
197 * aml_op_start - Begin of named Op in AML
198 * unnamed_op - Early Op (not a named Op)
203 * DESCRIPTION: Parse a named Op
205 ******************************************************************************/
208 acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
210 union acpi_parse_object *unnamed_op,
211 union acpi_parse_object **op)
213 acpi_status status = AE_OK;
214 union acpi_parse_object *arg = NULL;
216 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
218 unnamed_op->common.value.arg = NULL;
219 unnamed_op->common.arg_list_length = 0;
220 unnamed_op->common.aml_opcode = walk_state->opcode;
223 * Get and append arguments until we find the node that contains
224 * the name (the type ARGP_NAME).
226 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
227 (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
229 acpi_ps_get_next_arg(walk_state,
230 &(walk_state->parser_state),
231 GET_CURRENT_ARG_TYPE(walk_state->
233 if (ACPI_FAILURE(status)) {
234 return_ACPI_STATUS(status);
237 acpi_ps_append_arg(unnamed_op, arg);
238 INCREMENT_ARG_LIST(walk_state->arg_types);
242 * Make sure that we found a NAME and didn't run out of arguments
244 if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
245 return_ACPI_STATUS(AE_AML_NO_OPERAND);
248 /* We know that this arg is a name, move to next arg */
250 INCREMENT_ARG_LIST(walk_state->arg_types);
253 * Find the object. This will either insert the object into
254 * the namespace or simply look it up
256 walk_state->op = NULL;
258 status = walk_state->descending_callback(walk_state, op);
259 if (ACPI_FAILURE(status)) {
260 ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
261 return_ACPI_STATUS(status);
265 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
268 status = acpi_ps_next_parse_state(walk_state, *op, status);
269 if (ACPI_FAILURE(status)) {
270 if (status == AE_CTRL_PENDING) {
271 return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
273 return_ACPI_STATUS(status);
276 acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
279 if ((*op)->common.aml_opcode == AML_REGION_OP ||
280 (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
282 * Defer final parsing of an operation_region body, because we don't
283 * have enough info in the first pass to parse it correctly (i.e.,
284 * there may be method calls within the term_arg elements of the body.)
286 * However, we must continue parsing because the opregion is not a
287 * standalone package -- we don't know where the end is at this point.
289 * (Length is unknown until parse of the body complete)
291 (*op)->named.data = aml_op_start;
292 (*op)->named.length = 0;
295 return_ACPI_STATUS(AE_OK);
298 /*******************************************************************************
300 * FUNCTION: acpi_ps_create_op
302 * PARAMETERS: walk_state - Current state
303 * aml_op_start - Op start in AML
304 * new_op - Returned Op
308 * DESCRIPTION: Get Op from AML
310 ******************************************************************************/
313 acpi_ps_create_op(struct acpi_walk_state *walk_state,
314 u8 * aml_op_start, union acpi_parse_object **new_op)
316 acpi_status status = AE_OK;
317 union acpi_parse_object *op;
318 union acpi_parse_object *named_op = NULL;
319 union acpi_parse_object *parent_scope;
321 const struct acpi_opcode_info *op_info;
323 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
325 status = acpi_ps_get_aml_opcode(walk_state);
326 if (status == AE_CTRL_PARSE_CONTINUE) {
327 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
330 /* Create Op structure and append to parent's argument list */
332 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
333 op = acpi_ps_alloc_op(walk_state->opcode);
335 return_ACPI_STATUS(AE_NO_MEMORY);
338 if (walk_state->op_info->flags & AML_NAMED) {
340 acpi_ps_build_named_op(walk_state, aml_op_start, op,
343 if (ACPI_FAILURE(status)) {
344 return_ACPI_STATUS(status);
348 return_ACPI_STATUS(AE_OK);
351 /* Not a named opcode, just allocate Op and append to parent */
353 if (walk_state->op_info->flags & AML_CREATE) {
355 * Backup to beginning of create_XXXfield declaration
356 * body_length is unknown until we parse the body
358 op->named.data = aml_op_start;
359 op->named.length = 0;
362 if (walk_state->opcode == AML_BANK_FIELD_OP) {
364 * Backup to beginning of bank_field declaration
365 * body_length is unknown until we parse the body
367 op->named.data = aml_op_start;
368 op->named.length = 0;
371 parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
372 acpi_ps_append_arg(parent_scope, op);
376 acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
377 if (op_info->flags & AML_HAS_TARGET) {
379 acpi_ps_get_argument_count(op_info->type);
380 if (parent_scope->common.arg_list_length >
382 op->common.flags |= ACPI_PARSEOP_TARGET;
384 } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
385 op->common.flags |= ACPI_PARSEOP_TARGET;
389 if (walk_state->descending_callback != NULL) {
391 * Find the object. This will either insert the object into
392 * the namespace or simply look it up
394 walk_state->op = *new_op = op;
396 status = walk_state->descending_callback(walk_state, &op);
397 status = acpi_ps_next_parse_state(walk_state, op, status);
398 if (status == AE_CTRL_PENDING) {
399 status = AE_CTRL_PARSE_PENDING;
403 return_ACPI_STATUS(status);
406 /*******************************************************************************
408 * FUNCTION: acpi_ps_get_arguments
410 * PARAMETERS: walk_state - Current state
411 * aml_op_start - Op start in AML
416 * DESCRIPTION: Get arguments for passed Op.
418 ******************************************************************************/
421 acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
422 u8 * aml_op_start, union acpi_parse_object *op)
424 acpi_status status = AE_OK;
425 union acpi_parse_object *arg = NULL;
426 const struct acpi_opcode_info *op_info;
428 ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
430 switch (op->common.aml_opcode) {
431 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
432 case AML_WORD_OP: /* AML_WORDDATA_ARG */
433 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
434 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
435 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
437 /* Fill in constant or string argument directly */
439 acpi_ps_get_next_simple_arg(&(walk_state->parser_state),
440 GET_CURRENT_ARG_TYPE(walk_state->
445 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
448 acpi_ps_get_next_namepath(walk_state,
449 &(walk_state->parser_state), op,
451 if (ACPI_FAILURE(status)) {
452 return_ACPI_STATUS(status);
455 walk_state->arg_types = 0;
460 * Op is not a constant or string, append each argument to the Op
462 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types)
463 && !walk_state->arg_count) {
464 walk_state->aml_offset =
465 (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
466 walk_state->parser_state.
470 acpi_ps_get_next_arg(walk_state,
471 &(walk_state->parser_state),
473 (walk_state->arg_types), &arg);
474 if (ACPI_FAILURE(status)) {
475 return_ACPI_STATUS(status);
479 arg->common.aml_offset = walk_state->aml_offset;
480 acpi_ps_append_arg(op, arg);
483 INCREMENT_ARG_LIST(walk_state->arg_types);
487 * Handle executable code at "module-level". This refers to
488 * executable opcodes that appear outside of any control method.
490 if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2) &&
491 ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
493 * We want to skip If/Else/While constructs during Pass1 because we
494 * want to actually conditionally execute the code during Pass2.
496 * Except for disassembly, where we always want to walk the
497 * If/Else/While packages
499 switch (op->common.aml_opcode) {
505 * Currently supported module-level opcodes are:
506 * IF/ELSE/WHILE. These appear to be the most common,
507 * and easiest to support since they open an AML
510 if (walk_state->pass_number ==
511 ACPI_IMODE_LOAD_PASS1) {
512 acpi_ps_link_module_code(op->common.
524 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
525 "Pass1: Skipping an If/Else/While body\n"));
527 /* Skip body of if/else/while in pass 1 */
529 walk_state->parser_state.aml =
530 walk_state->parser_state.pkg_end;
531 walk_state->arg_count = 0;
536 * Check for an unsupported executable opcode at module
537 * level. We must be in PASS1, the parent must be a SCOPE,
538 * The opcode class must be EXECUTE, and the opcode must
539 * not be an argument to another opcode.
541 if ((walk_state->pass_number ==
542 ACPI_IMODE_LOAD_PASS1)
543 && (op->common.parent->common.aml_opcode ==
546 acpi_ps_get_opcode_info(op->common.
548 if ((op_info->class ==
549 AML_CLASS_EXECUTE) && (!arg)) {
550 ACPI_WARNING((AE_INFO,
551 "Unsupported module-level executable opcode "
552 "0x%.2X at table offset 0x%.4X",
562 acpi_table_header))));
569 /* Special processing for certain opcodes */
571 switch (op->common.aml_opcode) {
574 * Skip parsing of control method because we don't have enough
575 * info in the first pass to parse it correctly.
577 * Save the length and address of the body
579 op->named.data = walk_state->parser_state.aml;
580 op->named.length = (u32)
581 (walk_state->parser_state.pkg_end -
582 walk_state->parser_state.aml);
584 /* Skip body of method */
586 walk_state->parser_state.aml =
587 walk_state->parser_state.pkg_end;
588 walk_state->arg_count = 0;
593 case AML_VAR_PACKAGE_OP:
595 if ((op->common.parent) &&
596 (op->common.parent->common.aml_opcode ==
598 && (walk_state->pass_number <=
599 ACPI_IMODE_LOAD_PASS2)) {
601 * Skip parsing of Buffers and Packages because we don't have
602 * enough info in the first pass to parse them correctly.
604 op->named.data = aml_op_start;
605 op->named.length = (u32)
606 (walk_state->parser_state.pkg_end -
611 walk_state->parser_state.aml =
612 walk_state->parser_state.pkg_end;
613 walk_state->arg_count = 0;
619 if (walk_state->control_state) {
620 walk_state->control_state->control.package_end =
621 walk_state->parser_state.pkg_end;
627 /* No action for all other opcodes */
634 return_ACPI_STATUS(AE_OK);
637 /*******************************************************************************
639 * FUNCTION: acpi_ps_link_module_code
641 * PARAMETERS: parent_op - Parent parser op
642 * aml_start - Pointer to the AML
643 * aml_length - Length of executable AML
644 * owner_id - owner_id of module level code
648 * DESCRIPTION: Wrap the module-level code with a method object and link the
649 * object to the global list. Note, the mutex field of the method
650 * object is used to link multiple module-level code objects.
652 ******************************************************************************/
655 acpi_ps_link_module_code(union acpi_parse_object *parent_op,
656 u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
658 union acpi_operand_object *prev;
659 union acpi_operand_object *next;
660 union acpi_operand_object *method_obj;
661 struct acpi_namespace_node *parent_node;
663 /* Get the tail of the list */
665 prev = next = acpi_gbl_module_code_list;
668 next = next->method.mutex;
672 * Insert the module level code into the list. Merge it if it is
673 * adjacent to the previous element.
676 ((prev->method.aml_start + prev->method.aml_length) != aml_start)) {
678 /* Create, initialize, and link a new temporary method object */
680 method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
685 if (parent_op->common.node) {
686 parent_node = parent_op->common.node;
688 parent_node = acpi_gbl_root_node;
691 method_obj->method.aml_start = aml_start;
692 method_obj->method.aml_length = aml_length;
693 method_obj->method.owner_id = owner_id;
694 method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
697 * Save the parent node in next_object. This is cheating, but we
698 * don't want to expand the method object.
700 method_obj->method.next_object =
701 ACPI_CAST_PTR(union acpi_operand_object, parent_node);
704 acpi_gbl_module_code_list = method_obj;
706 prev->method.mutex = method_obj;
709 prev->method.aml_length += aml_length;
713 /*******************************************************************************
715 * FUNCTION: acpi_ps_complete_op
717 * PARAMETERS: walk_state - Current state
719 * status - Parse status before complete Op
723 * DESCRIPTION: Complete Op
725 ******************************************************************************/
728 acpi_ps_complete_op(struct acpi_walk_state *walk_state,
729 union acpi_parse_object **op, acpi_status status)
733 ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
736 * Finished one argument of the containing scope
738 walk_state->parser_state.scope->parse_scope.arg_count--;
740 /* Close this Op (will result in parse subtree deletion) */
742 status2 = acpi_ps_complete_this_op(walk_state, *op);
743 if (ACPI_FAILURE(status2)) {
744 return_ACPI_STATUS(status2);
753 case AE_CTRL_TRANSFER:
755 /* We are about to transfer to a called method */
757 walk_state->prev_op = NULL;
758 walk_state->prev_arg_types = walk_state->arg_types;
759 return_ACPI_STATUS(status);
763 acpi_ps_pop_scope(&(walk_state->parser_state), op,
764 &walk_state->arg_types,
765 &walk_state->arg_count);
768 walk_state->op = *op;
769 walk_state->op_info =
770 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
771 walk_state->opcode = (*op)->common.aml_opcode;
773 status = walk_state->ascending_callback(walk_state);
775 acpi_ps_next_parse_state(walk_state, *op, status);
777 status2 = acpi_ps_complete_this_op(walk_state, *op);
778 if (ACPI_FAILURE(status2)) {
779 return_ACPI_STATUS(status2);
787 case AE_CTRL_CONTINUE:
789 /* Pop off scopes until we find the While */
791 while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
792 acpi_ps_pop_scope(&(walk_state->parser_state), op,
793 &walk_state->arg_types,
794 &walk_state->arg_count);
797 /* Close this iteration of the While loop */
799 walk_state->op = *op;
800 walk_state->op_info =
801 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
802 walk_state->opcode = (*op)->common.aml_opcode;
804 status = walk_state->ascending_callback(walk_state);
805 status = acpi_ps_next_parse_state(walk_state, *op, status);
807 status2 = acpi_ps_complete_this_op(walk_state, *op);
808 if (ACPI_FAILURE(status2)) {
809 return_ACPI_STATUS(status2);
815 case AE_CTRL_TERMINATE:
821 acpi_ps_complete_this_op(walk_state, *op);
822 if (ACPI_FAILURE(status2)) {
823 return_ACPI_STATUS(status2);
826 acpi_ut_delete_generic_state
827 (acpi_ut_pop_generic_state
828 (&walk_state->control_state));
831 acpi_ps_pop_scope(&(walk_state->parser_state), op,
832 &walk_state->arg_types,
833 &walk_state->arg_count);
837 return_ACPI_STATUS(AE_OK);
839 default: /* All other non-AE_OK status */
844 acpi_ps_complete_this_op(walk_state, *op);
845 if (ACPI_FAILURE(status2)) {
846 return_ACPI_STATUS(status2);
850 acpi_ps_pop_scope(&(walk_state->parser_state), op,
851 &walk_state->arg_types,
852 &walk_state->arg_count);
858 * TBD: Cleanup parse ops on error
861 acpi_ps_pop_scope(parser_state, op,
862 &walk_state->arg_types,
863 &walk_state->arg_count);
866 walk_state->prev_op = NULL;
867 walk_state->prev_arg_types = walk_state->arg_types;
868 return_ACPI_STATUS(status);
871 /* This scope complete? */
873 if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
874 acpi_ps_pop_scope(&(walk_state->parser_state), op,
875 &walk_state->arg_types,
876 &walk_state->arg_count);
877 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
882 return_ACPI_STATUS(AE_OK);
885 /*******************************************************************************
887 * FUNCTION: acpi_ps_complete_final_op
889 * PARAMETERS: walk_state - Current state
891 * status - Current parse status before complete last
896 * DESCRIPTION: Complete last Op.
898 ******************************************************************************/
901 acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
902 union acpi_parse_object *op, acpi_status status)
906 ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
909 * Complete the last Op (if not completed), and clear the scope stack.
910 * It is easily possible to end an AML "package" with an unbounded number
911 * of open scopes (such as when several ASL blocks are closed with
912 * sequential closing braces). We want to terminate each one cleanly.
914 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
918 if (walk_state->ascending_callback != NULL) {
920 walk_state->op_info =
921 acpi_ps_get_opcode_info(op->common.
923 walk_state->opcode = op->common.aml_opcode;
926 walk_state->ascending_callback(walk_state);
928 acpi_ps_next_parse_state(walk_state, op,
930 if (status == AE_CTRL_PENDING) {
932 acpi_ps_complete_op(walk_state, &op,
934 if (ACPI_FAILURE(status)) {
935 return_ACPI_STATUS(status);
939 if (status == AE_CTRL_TERMINATE) {
946 acpi_ps_complete_this_op
966 return_ACPI_STATUS(status);
969 else if (ACPI_FAILURE(status)) {
971 /* First error is most important */
974 acpi_ps_complete_this_op(walk_state,
976 return_ACPI_STATUS(status);
980 status2 = acpi_ps_complete_this_op(walk_state, op);
981 if (ACPI_FAILURE(status2)) {
982 return_ACPI_STATUS(status2);
986 acpi_ps_pop_scope(&(walk_state->parser_state), &op,
987 &walk_state->arg_types,
988 &walk_state->arg_count);
992 return_ACPI_STATUS(status);
995 /*******************************************************************************
997 * FUNCTION: acpi_ps_parse_loop
999 * PARAMETERS: walk_state - Current state
1003 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
1006 ******************************************************************************/
1008 acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
1010 acpi_status status = AE_OK;
1011 union acpi_parse_object *op = NULL; /* current op */
1012 struct acpi_parse_state *parser_state;
1013 u8 *aml_op_start = NULL;
1015 ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state);
1017 if (walk_state->descending_callback == NULL) {
1018 return_ACPI_STATUS(AE_BAD_PARAMETER);
1021 parser_state = &walk_state->parser_state;
1022 walk_state->arg_types = 0;
1024 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
1026 if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
1028 /* We are restarting a preempted control method */
1030 if (acpi_ps_has_completed_scope(parser_state)) {
1032 * We must check if a predicate to an IF or WHILE statement
1033 * was just completed
1035 if ((parser_state->scope->parse_scope.op) &&
1036 ((parser_state->scope->parse_scope.op->common.
1037 aml_opcode == AML_IF_OP)
1038 || (parser_state->scope->parse_scope.op->common.
1039 aml_opcode == AML_WHILE_OP))
1040 && (walk_state->control_state)
1041 && (walk_state->control_state->common.state ==
1042 ACPI_CONTROL_PREDICATE_EXECUTING)) {
1044 * A predicate was just completed, get the value of the
1045 * predicate and branch based on that value
1047 walk_state->op = NULL;
1049 acpi_ds_get_predicate_value(walk_state,
1052 if (ACPI_FAILURE(status)
1053 && ((status & AE_CODE_MASK) !=
1055 if (status == AE_AML_NO_RETURN_VALUE) {
1056 ACPI_EXCEPTION((AE_INFO, status,
1057 "Invoked method did not return a value"));
1060 ACPI_EXCEPTION((AE_INFO, status,
1061 "GetPredicate Failed"));
1062 return_ACPI_STATUS(status);
1066 acpi_ps_next_parse_state(walk_state, op,
1070 acpi_ps_pop_scope(parser_state, &op,
1071 &walk_state->arg_types,
1072 &walk_state->arg_count);
1073 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
1074 "Popped scope, Op=%p\n", op));
1075 } else if (walk_state->prev_op) {
1077 /* We were in the middle of an op */
1079 op = walk_state->prev_op;
1080 walk_state->arg_types = walk_state->prev_arg_types;
1085 /* Iterative parsing loop, while there is more AML to process: */
1087 while ((parser_state->aml < parser_state->aml_end) || (op)) {
1088 aml_op_start = parser_state->aml;
1091 acpi_ps_create_op(walk_state, aml_op_start, &op);
1092 if (ACPI_FAILURE(status)) {
1093 if (status == AE_CTRL_PARSE_CONTINUE) {
1097 if (status == AE_CTRL_PARSE_PENDING) {
1102 acpi_ps_complete_op(walk_state, &op,
1104 if (ACPI_FAILURE(status)) {
1105 return_ACPI_STATUS(status);
1111 op->common.aml_offset = walk_state->aml_offset;
1113 if (walk_state->op_info) {
1114 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
1115 "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
1116 (u32) op->common.aml_opcode,
1117 walk_state->op_info->name, op,
1119 op->common.aml_offset));
1124 * Start arg_count at zero because we don't know if there are
1127 walk_state->arg_count = 0;
1129 /* Are there any arguments that must be processed? */
1131 if (walk_state->arg_types) {
1136 acpi_ps_get_arguments(walk_state, aml_op_start, op);
1137 if (ACPI_FAILURE(status)) {
1139 acpi_ps_complete_op(walk_state, &op,
1141 if (ACPI_FAILURE(status)) {
1142 return_ACPI_STATUS(status);
1149 /* Check for arguments that need to be processed */
1151 if (walk_state->arg_count) {
1153 * There are arguments (complex ones), push Op and
1154 * prepare for argument
1156 status = acpi_ps_push_scope(parser_state, op,
1157 walk_state->arg_types,
1158 walk_state->arg_count);
1159 if (ACPI_FAILURE(status)) {
1161 acpi_ps_complete_op(walk_state, &op,
1163 if (ACPI_FAILURE(status)) {
1164 return_ACPI_STATUS(status);
1175 * All arguments have been processed -- Op is complete,
1178 walk_state->op_info =
1179 acpi_ps_get_opcode_info(op->common.aml_opcode);
1180 if (walk_state->op_info->flags & AML_NAMED) {
1181 if (acpi_gbl_depth) {
1185 if (op->common.aml_opcode == AML_REGION_OP ||
1186 op->common.aml_opcode == AML_DATA_REGION_OP) {
1188 * Skip parsing of control method or opregion body,
1189 * because we don't have enough info in the first pass
1190 * to parse them correctly.
1192 * Completed parsing an op_region declaration, we now
1196 (u32) (parser_state->aml - op->named.data);
1200 if (walk_state->op_info->flags & AML_CREATE) {
1202 * Backup to beginning of create_XXXfield declaration (1 for
1205 * body_length is unknown until we parse the body
1208 (u32) (parser_state->aml - op->named.data);
1211 if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
1213 * Backup to beginning of bank_field declaration
1215 * body_length is unknown until we parse the body
1218 (u32) (parser_state->aml - op->named.data);
1221 /* This op complete, notify the dispatcher */
1223 if (walk_state->ascending_callback != NULL) {
1224 walk_state->op = op;
1225 walk_state->opcode = op->common.aml_opcode;
1227 status = walk_state->ascending_callback(walk_state);
1229 acpi_ps_next_parse_state(walk_state, op, status);
1230 if (status == AE_CTRL_PENDING) {
1235 status = acpi_ps_complete_op(walk_state, &op, status);
1236 if (ACPI_FAILURE(status)) {
1237 return_ACPI_STATUS(status);
1240 } /* while parser_state->Aml */
1242 status = acpi_ps_complete_final_op(walk_state, op, status);
1243 return_ACPI_STATUS(status);