1 /*******************************************************************************
3 * Module Name: dsutils - Dispatcher utilities
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2004, 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 #ifndef ACPI_NO_METHOD_EXECUTION
59 /*******************************************************************************
61 * FUNCTION: acpi_ds_is_result_used
63 * PARAMETERS: Op - Current Op
64 * walk_state - Current State
66 * RETURN: TRUE if result is used, FALSE otherwise
68 * DESCRIPTION: Check if a result object will be used by the parent
70 ******************************************************************************/
73 acpi_ds_is_result_used (
74 union acpi_parse_object
*op
,
75 struct acpi_walk_state
*walk_state
)
77 const struct acpi_opcode_info
*parent_info
;
80 ACPI_FUNCTION_TRACE_PTR ("ds_is_result_used", op
);
83 /* Must have both an Op and a Result Object */
86 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
, "Null Op\n"));
91 * If there is no parent, we are executing at the method level.
92 * An executing method typically has no parent, since each method
93 * is parsed separately.
95 if (!op
->common
.parent
) {
97 * If this is the last statement in the method, we know it is not a
98 * Return() operator (would not come here.) The following code is the
99 * optional support for a so-called "implicit return". Some AML code
100 * assumes that the last value of the method is "implicitly" returned
101 * to the caller. Just save the last result as the return value.
102 * NOTE: this is optional because the ASL language does not actually
103 * support this behavior.
105 if ((acpi_gbl_enable_interpreter_slack
) &&
106 (walk_state
->parser_state
.aml
>= walk_state
->parser_state
.aml_end
)) {
107 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
,
108 "Result of [%s] will be implicitly returned\n",
109 acpi_ps_get_opcode_name (op
->common
.aml_opcode
)));
111 /* Use the top of the result stack as the implicit return value */
113 walk_state
->return_desc
= walk_state
->results
->results
.obj_desc
[0];
117 /* No parent, the return value cannot possibly be used */
119 return_VALUE (FALSE
);
122 /* Get info on the parent. The root_op is AML_SCOPE */
124 parent_info
= acpi_ps_get_opcode_info (op
->common
.parent
->common
.aml_opcode
);
125 if (parent_info
->class == AML_CLASS_UNKNOWN
) {
126 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
, "Unknown parent opcode. Op=%p\n", op
));
127 return_VALUE (FALSE
);
131 * Decide what to do with the result based on the parent. If
132 * the parent opcode will not use the result, delete the object.
133 * Otherwise leave it as is, it will be deleted when it is used
134 * as an operand later.
136 switch (parent_info
->class) {
137 case AML_CLASS_CONTROL
:
139 switch (op
->common
.parent
->common
.aml_opcode
) {
142 /* Never delete the return value associated with a return opcode */
150 * If we are executing the predicate AND this is the predicate op,
151 * we will use the return value
153 if ((walk_state
->control_state
->common
.state
== ACPI_CONTROL_PREDICATE_EXECUTING
) &&
154 (walk_state
->control_state
->control
.predicate_op
== op
)) {
160 /* Ignore other control opcodes */
164 /* The general control opcode returns no result */
166 goto result_not_used
;
169 case AML_CLASS_CREATE
:
172 * These opcodes allow term_arg(s) as operands and therefore
173 * the operands can be method calls. The result is used.
178 case AML_CLASS_NAMED_OBJECT
:
180 if ((op
->common
.parent
->common
.aml_opcode
== AML_REGION_OP
) ||
181 (op
->common
.parent
->common
.aml_opcode
== AML_DATA_REGION_OP
) ||
182 (op
->common
.parent
->common
.aml_opcode
== AML_PACKAGE_OP
) ||
183 (op
->common
.parent
->common
.aml_opcode
== AML_VAR_PACKAGE_OP
) ||
184 (op
->common
.parent
->common
.aml_opcode
== AML_BUFFER_OP
) ||
185 (op
->common
.parent
->common
.aml_opcode
== AML_INT_EVAL_SUBTREE_OP
)) {
187 * These opcodes allow term_arg(s) as operands and therefore
188 * the operands can be method calls. The result is used.
193 goto result_not_used
;
199 * In all other cases. the parent will actually use the return
200 * object, so keep it.
207 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
, "Result of [%s] used by Parent [%s] Op=%p\n",
208 acpi_ps_get_opcode_name (op
->common
.aml_opcode
),
209 acpi_ps_get_opcode_name (op
->common
.parent
->common
.aml_opcode
), op
));
215 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
, "Result of [%s] not used by Parent [%s] Op=%p\n",
216 acpi_ps_get_opcode_name (op
->common
.aml_opcode
),
217 acpi_ps_get_opcode_name (op
->common
.parent
->common
.aml_opcode
), op
));
219 return_VALUE (FALSE
);
223 /*******************************************************************************
225 * FUNCTION: acpi_ds_delete_result_if_not_used
227 * PARAMETERS: Op - Current parse Op
228 * result_obj - Result of the operation
229 * walk_state - Current state
233 * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
234 * result descriptor, check if the parent opcode will actually use
235 * this result. If not, delete the result now so that it will
236 * not become orphaned.
238 ******************************************************************************/
241 acpi_ds_delete_result_if_not_used (
242 union acpi_parse_object
*op
,
243 union acpi_operand_object
*result_obj
,
244 struct acpi_walk_state
*walk_state
)
246 union acpi_operand_object
*obj_desc
;
250 ACPI_FUNCTION_TRACE_PTR ("ds_delete_result_if_not_used", result_obj
);
254 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
, "Null Op\n"));
262 if (!acpi_ds_is_result_used (op
, walk_state
)) {
264 * Must pop the result stack (obj_desc should be equal to result_obj)
266 status
= acpi_ds_result_pop (&obj_desc
, walk_state
);
267 if (ACPI_SUCCESS (status
)) {
268 acpi_ut_remove_reference (result_obj
);
276 /*******************************************************************************
278 * FUNCTION: acpi_ds_resolve_operands
280 * PARAMETERS: walk_state - Current walk state with operands on stack
284 * DESCRIPTION: Resolve all operands to their values. Used to prepare
285 * arguments to a control method invocation (a call from one
286 * method to another.)
288 ******************************************************************************/
291 acpi_ds_resolve_operands (
292 struct acpi_walk_state
*walk_state
)
295 acpi_status status
= AE_OK
;
298 ACPI_FUNCTION_TRACE_PTR ("ds_resolve_operands", walk_state
);
302 * Attempt to resolve each of the valid operands
303 * Method arguments are passed by reference, not by value. This means
304 * that the actual objects are passed, not copies of the objects.
306 for (i
= 0; i
< walk_state
->num_operands
; i
++) {
307 status
= acpi_ex_resolve_to_value (&walk_state
->operands
[i
], walk_state
);
308 if (ACPI_FAILURE (status
)) {
313 return_ACPI_STATUS (status
);
317 /*******************************************************************************
319 * FUNCTION: acpi_ds_clear_operands
321 * PARAMETERS: walk_state - Current walk state with operands on stack
325 * DESCRIPTION: Clear all operands on the current walk state operand stack.
327 ******************************************************************************/
330 acpi_ds_clear_operands (
331 struct acpi_walk_state
*walk_state
)
336 ACPI_FUNCTION_TRACE_PTR ("acpi_ds_clear_operands", walk_state
);
340 * Remove a reference on each operand on the stack
342 for (i
= 0; i
< walk_state
->num_operands
; i
++) {
344 * Remove a reference to all operands, including both
345 * "Arguments" and "Targets".
347 acpi_ut_remove_reference (walk_state
->operands
[i
]);
348 walk_state
->operands
[i
] = NULL
;
351 walk_state
->num_operands
= 0;
357 /*******************************************************************************
359 * FUNCTION: acpi_ds_create_operand
361 * PARAMETERS: walk_state - Current walk state
362 * Arg - Parse object for the argument
363 * arg_index - Which argument (zero based)
367 * DESCRIPTION: Translate a parse tree object that is an argument to an AML
368 * opcode to the equivalent interpreter object. This may include
369 * looking up a name or entering a new name into the internal
372 ******************************************************************************/
375 acpi_ds_create_operand (
376 struct acpi_walk_state
*walk_state
,
377 union acpi_parse_object
*arg
,
380 acpi_status status
= AE_OK
;
383 union acpi_operand_object
*obj_desc
;
384 union acpi_parse_object
*parent_op
;
386 acpi_interpreter_mode interpreter_mode
;
387 const struct acpi_opcode_info
*op_info
;
390 ACPI_FUNCTION_TRACE_PTR ("ds_create_operand", arg
);
393 /* A valid name must be looked up in the namespace */
395 if ((arg
->common
.aml_opcode
== AML_INT_NAMEPATH_OP
) &&
396 (arg
->common
.value
.string
)) {
397 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
, "Getting a name: Arg=%p\n", arg
));
399 /* Get the entire name string from the AML stream */
401 status
= acpi_ex_get_name_string (ACPI_TYPE_ANY
, arg
->common
.value
.buffer
,
402 &name_string
, &name_length
);
404 if (ACPI_FAILURE (status
)) {
405 return_ACPI_STATUS (status
);
409 * All prefixes have been handled, and the name is
415 * Special handling for buffer_field declarations. This is a deferred
416 * opcode that unfortunately defines the field name as the last
417 * parameter instead of the first. We get here when we are performing
418 * the deferred execution, so the actual name of the field is already
419 * in the namespace. We don't want to attempt to look it up again
420 * because we may be executing in a different scope than where the
421 * actual opcode exists.
423 if ((walk_state
->deferred_node
) &&
424 (walk_state
->deferred_node
->type
== ACPI_TYPE_BUFFER_FIELD
) &&
426 obj_desc
= ACPI_CAST_PTR (union acpi_operand_object
, walk_state
->deferred_node
);
429 else /* All other opcodes */ {
431 * Differentiate between a namespace "create" operation
432 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
433 * IMODE_EXECUTE) in order to support the creation of
434 * namespace objects during the execution of control methods.
436 parent_op
= arg
->common
.parent
;
437 op_info
= acpi_ps_get_opcode_info (parent_op
->common
.aml_opcode
);
438 if ((op_info
->flags
& AML_NSNODE
) &&
439 (parent_op
->common
.aml_opcode
!= AML_INT_METHODCALL_OP
) &&
440 (parent_op
->common
.aml_opcode
!= AML_REGION_OP
) &&
441 (parent_op
->common
.aml_opcode
!= AML_INT_NAMEPATH_OP
)) {
442 /* Enter name into namespace if not found */
444 interpreter_mode
= ACPI_IMODE_LOAD_PASS2
;
447 /* Return a failure if name not found */
449 interpreter_mode
= ACPI_IMODE_EXECUTE
;
452 status
= acpi_ns_lookup (walk_state
->scope_info
, name_string
,
453 ACPI_TYPE_ANY
, interpreter_mode
,
454 ACPI_NS_SEARCH_PARENT
| ACPI_NS_DONT_OPEN_SCOPE
,
456 ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node
, &obj_desc
));
458 * The only case where we pass through (ignore) a NOT_FOUND
459 * error is for the cond_ref_of opcode.
461 if (status
== AE_NOT_FOUND
) {
462 if (parent_op
->common
.aml_opcode
== AML_COND_REF_OF_OP
) {
464 * For the Conditional Reference op, it's OK if
465 * the name is not found; We just need a way to
466 * indicate this to the interpreter, set the
469 obj_desc
= ACPI_CAST_PTR (union acpi_operand_object
, acpi_gbl_root_node
);
474 * We just plain didn't find it -- which is a
475 * very serious error at this point
477 status
= AE_AML_NAME_NOT_FOUND
;
481 if (ACPI_FAILURE (status
)) {
482 ACPI_REPORT_NSERROR (name_string
, status
);
486 /* Free the namestring created above */
488 ACPI_MEM_FREE (name_string
);
490 /* Check status from the lookup */
492 if (ACPI_FAILURE (status
)) {
493 return_ACPI_STATUS (status
);
496 /* Put the resulting object onto the current object stack */
498 status
= acpi_ds_obj_stack_push (obj_desc
, walk_state
);
499 if (ACPI_FAILURE (status
)) {
500 return_ACPI_STATUS (status
);
502 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc
, walk_state
));
505 /* Check for null name case */
507 if (arg
->common
.aml_opcode
== AML_INT_NAMEPATH_OP
) {
509 * If the name is null, this means that this is an
510 * optional result parameter that was not specified
511 * in the original ASL. Create a Zero Constant for a
512 * placeholder. (Store to a constant is a Noop.)
514 opcode
= AML_ZERO_OP
; /* Has no arguments! */
516 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
, "Null namepath: Arg=%p\n", arg
));
519 opcode
= arg
->common
.aml_opcode
;
522 /* Get the object type of the argument */
524 op_info
= acpi_ps_get_opcode_info (opcode
);
525 if (op_info
->object_type
== ACPI_TYPE_INVALID
) {
526 return_ACPI_STATUS (AE_NOT_IMPLEMENTED
);
529 if (op_info
->flags
& AML_HAS_RETVAL
) {
530 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
,
531 "Argument previously created, already stacked \n"));
533 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (
534 walk_state
->operands
[walk_state
->num_operands
- 1], walk_state
));
537 * Use value that was already previously returned
538 * by the evaluation of this argument
540 status
= acpi_ds_result_pop_from_bottom (&obj_desc
, walk_state
);
541 if (ACPI_FAILURE (status
)) {
543 * Only error is underflow, and this indicates
544 * a missing or null operand!
546 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
, "Missing or null operand, %s\n",
547 acpi_format_exception (status
)));
548 return_ACPI_STATUS (status
);
552 /* Create an ACPI_INTERNAL_OBJECT for the argument */
554 obj_desc
= acpi_ut_create_internal_object (op_info
->object_type
);
556 return_ACPI_STATUS (AE_NO_MEMORY
);
559 /* Initialize the new object */
561 status
= acpi_ds_init_object_from_op (walk_state
, arg
,
563 if (ACPI_FAILURE (status
)) {
564 acpi_ut_delete_object_desc (obj_desc
);
565 return_ACPI_STATUS (status
);
569 /* Put the operand object on the object stack */
571 status
= acpi_ds_obj_stack_push (obj_desc
, walk_state
);
572 if (ACPI_FAILURE (status
)) {
573 return_ACPI_STATUS (status
);
576 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc
, walk_state
));
579 return_ACPI_STATUS (AE_OK
);
583 /*******************************************************************************
585 * FUNCTION: acpi_ds_create_operands
587 * PARAMETERS: first_arg - First argument of a parser argument tree
591 * DESCRIPTION: Convert an operator's arguments from a parse tree format to
592 * namespace objects and place those argument object on the object
593 * stack in preparation for evaluation by the interpreter.
595 ******************************************************************************/
598 acpi_ds_create_operands (
599 struct acpi_walk_state
*walk_state
,
600 union acpi_parse_object
*first_arg
)
602 acpi_status status
= AE_OK
;
603 union acpi_parse_object
*arg
;
607 ACPI_FUNCTION_TRACE_PTR ("ds_create_operands", first_arg
);
610 /* For all arguments in the list... */
614 status
= acpi_ds_create_operand (walk_state
, arg
, arg_count
);
615 if (ACPI_FAILURE (status
)) {
619 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
, "Arg #%d (%p) done, Arg1=%p\n",
620 arg_count
, arg
, first_arg
));
622 /* Move on to next argument, if any */
624 arg
= arg
->common
.next
;
628 return_ACPI_STATUS (status
);
633 * We must undo everything done above; meaning that we must
634 * pop everything off of the operand stack and delete those
637 (void) acpi_ds_obj_stack_pop_and_delete (arg_count
, walk_state
);
639 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
, "While creating Arg %d - %s\n",
640 (arg_count
+ 1), acpi_format_exception (status
)));
641 return_ACPI_STATUS (status
);