1 /*******************************************************************************
3 * Module Name: dsutils - Dispatcher utilities
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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 #include <acpi/acpi.h>
46 #include <acpi/acparser.h>
47 #include <acpi/amlcode.h>
48 #include <acpi/acdispat.h>
49 #include <acpi/acinterp.h>
50 #include <acpi/acnamesp.h>
51 #include <acpi/acdebug.h>
53 #define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME ("dsutils")
57 /*******************************************************************************
59 * FUNCTION: acpi_ds_clear_implicit_return
61 * PARAMETERS: walk_state - Current State
65 * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
66 * to delete "stale" return values (if enabled, the return value
67 * from every operator is saved at least momentarily, in case the
68 * parent method exits.)
70 ******************************************************************************/
73 acpi_ds_clear_implicit_return (
74 struct acpi_walk_state *walk_state)
76 ACPI_FUNCTION_NAME ("ds_clear_implicit_return");
80 * Slack must be enabled for this feature
82 if (!acpi_gbl_enable_interpreter_slack) {
86 if (walk_state->implicit_return_obj) {
88 * Delete any "stale" implicit return. However, in
89 * complex statements, the implicit return value can be
90 * bubbled up several levels.
92 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
93 "Removing reference on stale implicit return obj %p\n",
94 walk_state->implicit_return_obj));
96 acpi_ut_remove_reference (walk_state->implicit_return_obj);
97 walk_state->implicit_return_obj = NULL;
102 #ifndef ACPI_NO_METHOD_EXECUTION
103 /*******************************************************************************
105 * FUNCTION: acpi_ds_do_implicit_return
107 * PARAMETERS: return_desc - The return value
108 * walk_state - Current State
109 * add_reference - True if a reference should be added to the
112 * RETURN: TRUE if implicit return enabled, FALSE otherwise
114 * DESCRIPTION: Implements the optional "implicit return". We save the result
115 * of every ASL operator and control method invocation in case the
116 * parent method exit. Before storing a new return value, we
117 * delete the previous return value.
119 ******************************************************************************/
122 acpi_ds_do_implicit_return (
123 union acpi_operand_object *return_desc,
124 struct acpi_walk_state *walk_state,
127 ACPI_FUNCTION_NAME ("ds_do_implicit_return");
131 * Slack must be enabled for this feature, and we must
132 * have a valid return object
134 if ((!acpi_gbl_enable_interpreter_slack) ||
139 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
140 "Result %p will be implicitly returned; Prev=%p\n",
142 walk_state->implicit_return_obj));
145 * Delete any "stale" implicit return value first. However, in
146 * complex statements, the implicit return value can be
147 * bubbled up several levels, so we don't clear the value if it
148 * is the same as the return_desc.
150 if (walk_state->implicit_return_obj) {
151 if (walk_state->implicit_return_obj == return_desc) {
154 acpi_ds_clear_implicit_return (walk_state);
157 /* Save the implicit return value, add a reference if requested */
159 walk_state->implicit_return_obj = return_desc;
161 acpi_ut_add_reference (return_desc);
168 /*******************************************************************************
170 * FUNCTION: acpi_ds_is_result_used
172 * PARAMETERS: Op - Current Op
173 * walk_state - Current State
175 * RETURN: TRUE if result is used, FALSE otherwise
177 * DESCRIPTION: Check if a result object will be used by the parent
179 ******************************************************************************/
182 acpi_ds_is_result_used (
183 union acpi_parse_object *op,
184 struct acpi_walk_state *walk_state)
186 const struct acpi_opcode_info *parent_info;
188 ACPI_FUNCTION_TRACE_PTR ("ds_is_result_used", op);
191 /* Must have both an Op and a Result Object */
194 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
199 * We know that this operator is not a
200 * Return() operator (would not come here.) The following code is the
201 * optional support for a so-called "implicit return". Some AML code
202 * assumes that the last value of the method is "implicitly" returned
203 * to the caller. Just save the last result as the return value.
204 * NOTE: this is optional because the ASL language does not actually
205 * support this behavior.
207 (void) acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
210 * Now determine if the parent will use the result
212 * If there is no parent, or the parent is a scope_op, we are executing
213 * at the method level. An executing method typically has no parent,
214 * since each method is parsed separately. A method invoked externally
215 * via execute_control_method has a scope_op as the parent.
217 if ((!op->common.parent) ||
218 (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
219 /* No parent, the return value cannot possibly be used */
221 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
222 "At Method level, result of [%s] not used\n",
223 acpi_ps_get_opcode_name (op->common.aml_opcode)));
224 return_VALUE (FALSE);
227 /* Get info on the parent. The root_op is AML_SCOPE */
229 parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
230 if (parent_info->class == AML_CLASS_UNKNOWN) {
231 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
232 "Unknown parent opcode. Op=%p\n", op));
233 return_VALUE (FALSE);
237 * Decide what to do with the result based on the parent. If
238 * the parent opcode will not use the result, delete the object.
239 * Otherwise leave it as is, it will be deleted when it is used
240 * as an operand later.
242 switch (parent_info->class) {
243 case AML_CLASS_CONTROL:
245 switch (op->common.parent->common.aml_opcode) {
248 /* Never delete the return value associated with a return opcode */
256 * If we are executing the predicate AND this is the predicate op,
257 * we will use the return value
259 if ((walk_state->control_state->common.state == ACPI_CONTROL_PREDICATE_EXECUTING) &&
260 (walk_state->control_state->control.predicate_op == op)) {
266 /* Ignore other control opcodes */
270 /* The general control opcode returns no result */
272 goto result_not_used;
275 case AML_CLASS_CREATE:
278 * These opcodes allow term_arg(s) as operands and therefore
279 * the operands can be method calls. The result is used.
284 case AML_CLASS_NAMED_OBJECT:
286 if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
287 (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) ||
288 (op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
289 (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
290 (op->common.parent->common.aml_opcode == AML_BUFFER_OP) ||
291 (op->common.parent->common.aml_opcode == AML_INT_EVAL_SUBTREE_OP)) {
293 * These opcodes allow term_arg(s) as operands and therefore
294 * the operands can be method calls. The result is used.
299 goto result_not_used;
305 * In all other cases. the parent will actually use the return
306 * object, so keep it.
313 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
314 "Result of [%s] used by Parent [%s] Op=%p\n",
315 acpi_ps_get_opcode_name (op->common.aml_opcode),
316 acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
322 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
323 "Result of [%s] not used by Parent [%s] Op=%p\n",
324 acpi_ps_get_opcode_name (op->common.aml_opcode),
325 acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
327 return_VALUE (FALSE);
331 /*******************************************************************************
333 * FUNCTION: acpi_ds_delete_result_if_not_used
335 * PARAMETERS: Op - Current parse Op
336 * result_obj - Result of the operation
337 * walk_state - Current state
341 * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
342 * result descriptor, check if the parent opcode will actually use
343 * this result. If not, delete the result now so that it will
344 * not become orphaned.
346 ******************************************************************************/
349 acpi_ds_delete_result_if_not_used (
350 union acpi_parse_object *op,
351 union acpi_operand_object *result_obj,
352 struct acpi_walk_state *walk_state)
354 union acpi_operand_object *obj_desc;
358 ACPI_FUNCTION_TRACE_PTR ("ds_delete_result_if_not_used", result_obj);
362 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
370 if (!acpi_ds_is_result_used (op, walk_state)) {
371 /* Must pop the result stack (obj_desc should be equal to result_obj) */
373 status = acpi_ds_result_pop (&obj_desc, walk_state);
374 if (ACPI_SUCCESS (status)) {
375 acpi_ut_remove_reference (result_obj);
383 /*******************************************************************************
385 * FUNCTION: acpi_ds_resolve_operands
387 * PARAMETERS: walk_state - Current walk state with operands on stack
391 * DESCRIPTION: Resolve all operands to their values. Used to prepare
392 * arguments to a control method invocation (a call from one
393 * method to another.)
395 ******************************************************************************/
398 acpi_ds_resolve_operands (
399 struct acpi_walk_state *walk_state)
402 acpi_status status = AE_OK;
405 ACPI_FUNCTION_TRACE_PTR ("ds_resolve_operands", walk_state);
409 * Attempt to resolve each of the valid operands
410 * Method arguments are passed by reference, not by value. This means
411 * that the actual objects are passed, not copies of the objects.
413 for (i = 0; i < walk_state->num_operands; i++) {
414 status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state);
415 if (ACPI_FAILURE (status)) {
420 return_ACPI_STATUS (status);
424 /*******************************************************************************
426 * FUNCTION: acpi_ds_clear_operands
428 * PARAMETERS: walk_state - Current walk state with operands on stack
432 * DESCRIPTION: Clear all operands on the current walk state operand stack.
434 ******************************************************************************/
437 acpi_ds_clear_operands (
438 struct acpi_walk_state *walk_state)
443 ACPI_FUNCTION_TRACE_PTR ("ds_clear_operands", walk_state);
446 /* Remove a reference on each operand on the stack */
448 for (i = 0; i < walk_state->num_operands; i++) {
450 * Remove a reference to all operands, including both
451 * "Arguments" and "Targets".
453 acpi_ut_remove_reference (walk_state->operands[i]);
454 walk_state->operands[i] = NULL;
457 walk_state->num_operands = 0;
463 /*******************************************************************************
465 * FUNCTION: acpi_ds_create_operand
467 * PARAMETERS: walk_state - Current walk state
468 * Arg - Parse object for the argument
469 * arg_index - Which argument (zero based)
473 * DESCRIPTION: Translate a parse tree object that is an argument to an AML
474 * opcode to the equivalent interpreter object. This may include
475 * looking up a name or entering a new name into the internal
478 ******************************************************************************/
481 acpi_ds_create_operand (
482 struct acpi_walk_state *walk_state,
483 union acpi_parse_object *arg,
486 acpi_status status = AE_OK;
489 union acpi_operand_object *obj_desc;
490 union acpi_parse_object *parent_op;
492 acpi_interpreter_mode interpreter_mode;
493 const struct acpi_opcode_info *op_info;
496 ACPI_FUNCTION_TRACE_PTR ("ds_create_operand", arg);
499 /* A valid name must be looked up in the namespace */
501 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
502 (arg->common.value.string)) {
503 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", arg));
505 /* Get the entire name string from the AML stream */
507 status = acpi_ex_get_name_string (ACPI_TYPE_ANY, arg->common.value.buffer,
508 &name_string, &name_length);
510 if (ACPI_FAILURE (status)) {
511 return_ACPI_STATUS (status);
514 /* All prefixes have been handled, and the name is in name_string */
517 * Special handling for buffer_field declarations. This is a deferred
518 * opcode that unfortunately defines the field name as the last
519 * parameter instead of the first. We get here when we are performing
520 * the deferred execution, so the actual name of the field is already
521 * in the namespace. We don't want to attempt to look it up again
522 * because we may be executing in a different scope than where the
523 * actual opcode exists.
525 if ((walk_state->deferred_node) &&
526 (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) &&
528 obj_desc = ACPI_CAST_PTR (
529 union acpi_operand_object, walk_state->deferred_node);
532 else /* All other opcodes */ {
534 * Differentiate between a namespace "create" operation
535 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
536 * IMODE_EXECUTE) in order to support the creation of
537 * namespace objects during the execution of control methods.
539 parent_op = arg->common.parent;
540 op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode);
541 if ((op_info->flags & AML_NSNODE) &&
542 (parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) &&
543 (parent_op->common.aml_opcode != AML_REGION_OP) &&
544 (parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) {
545 /* Enter name into namespace if not found */
547 interpreter_mode = ACPI_IMODE_LOAD_PASS2;
550 /* Return a failure if name not found */
552 interpreter_mode = ACPI_IMODE_EXECUTE;
555 status = acpi_ns_lookup (walk_state->scope_info, name_string,
556 ACPI_TYPE_ANY, interpreter_mode,
557 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
559 ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc));
561 * The only case where we pass through (ignore) a NOT_FOUND
562 * error is for the cond_ref_of opcode.
564 if (status == AE_NOT_FOUND) {
565 if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) {
567 * For the Conditional Reference op, it's OK if
568 * the name is not found; We just need a way to
569 * indicate this to the interpreter, set the
572 obj_desc = ACPI_CAST_PTR (
573 union acpi_operand_object, acpi_gbl_root_node);
578 * We just plain didn't find it -- which is a
579 * very serious error at this point
581 status = AE_AML_NAME_NOT_FOUND;
585 if (ACPI_FAILURE (status)) {
586 ACPI_REPORT_NSERROR (name_string, status);
590 /* Free the namestring created above */
592 ACPI_MEM_FREE (name_string);
594 /* Check status from the lookup */
596 if (ACPI_FAILURE (status)) {
597 return_ACPI_STATUS (status);
600 /* Put the resulting object onto the current object stack */
602 status = acpi_ds_obj_stack_push (obj_desc, walk_state);
603 if (ACPI_FAILURE (status)) {
604 return_ACPI_STATUS (status);
606 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
609 /* Check for null name case */
611 if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) {
613 * If the name is null, this means that this is an
614 * optional result parameter that was not specified
615 * in the original ASL. Create a Zero Constant for a
616 * placeholder. (Store to a constant is a Noop.)
618 opcode = AML_ZERO_OP; /* Has no arguments! */
620 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
621 "Null namepath: Arg=%p\n", arg));
624 opcode = arg->common.aml_opcode;
627 /* Get the object type of the argument */
629 op_info = acpi_ps_get_opcode_info (opcode);
630 if (op_info->object_type == ACPI_TYPE_INVALID) {
631 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
634 if (op_info->flags & AML_HAS_RETVAL) {
635 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
636 "Argument previously created, already stacked \n"));
638 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (
639 walk_state->operands [walk_state->num_operands - 1], walk_state));
642 * Use value that was already previously returned
643 * by the evaluation of this argument
645 status = acpi_ds_result_pop_from_bottom (&obj_desc, walk_state);
646 if (ACPI_FAILURE (status)) {
648 * Only error is underflow, and this indicates
649 * a missing or null operand!
651 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
652 "Missing or null operand, %s\n",
653 acpi_format_exception (status)));
654 return_ACPI_STATUS (status);
658 /* Create an ACPI_INTERNAL_OBJECT for the argument */
660 obj_desc = acpi_ut_create_internal_object (op_info->object_type);
662 return_ACPI_STATUS (AE_NO_MEMORY);
665 /* Initialize the new object */
667 status = acpi_ds_init_object_from_op (
668 walk_state, arg, opcode, &obj_desc);
669 if (ACPI_FAILURE (status)) {
670 acpi_ut_delete_object_desc (obj_desc);
671 return_ACPI_STATUS (status);
675 /* Put the operand object on the object stack */
677 status = acpi_ds_obj_stack_push (obj_desc, walk_state);
678 if (ACPI_FAILURE (status)) {
679 return_ACPI_STATUS (status);
682 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
685 return_ACPI_STATUS (AE_OK);
689 /*******************************************************************************
691 * FUNCTION: acpi_ds_create_operands
693 * PARAMETERS: walk_state - Current state
694 * first_arg - First argument of a parser argument tree
698 * DESCRIPTION: Convert an operator's arguments from a parse tree format to
699 * namespace objects and place those argument object on the object
700 * stack in preparation for evaluation by the interpreter.
702 ******************************************************************************/
705 acpi_ds_create_operands (
706 struct acpi_walk_state *walk_state,
707 union acpi_parse_object *first_arg)
709 acpi_status status = AE_OK;
710 union acpi_parse_object *arg;
714 ACPI_FUNCTION_TRACE_PTR ("ds_create_operands", first_arg);
717 /* For all arguments in the list... */
721 status = acpi_ds_create_operand (walk_state, arg, arg_count);
722 if (ACPI_FAILURE (status)) {
726 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%d (%p) done, Arg1=%p\n",
727 arg_count, arg, first_arg));
729 /* Move on to next argument, if any */
731 arg = arg->common.next;
735 return_ACPI_STATUS (status);
740 * We must undo everything done above; meaning that we must
741 * pop everything off of the operand stack and delete those
744 (void) acpi_ds_obj_stack_pop_and_delete (arg_count, walk_state);
746 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While creating Arg %d - %s\n",
747 (arg_count + 1), acpi_format_exception (status)));
748 return_ACPI_STATUS (status);