1 /******************************************************************************
3 * Module Name: dswexec - Dispatcher method execution callbacks;
4 * dispatch to interpreter.
7 *****************************************************************************/
10 * Copyright (C) 2000, 2001 R. Byron Moore
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #define _COMPONENT ACPI_DISPATCHER
31 MODULE_NAME ("dswexec")
34 /*****************************************************************************
36 * FUNCTION: Acpi_ds_get_predicate_value
38 * PARAMETERS: Walk_state - Current state of the parse tree walk
42 * DESCRIPTION: Get the result of a predicate evaluation
44 ****************************************************************************/
47 acpi_ds_get_predicate_value (
48 ACPI_WALK_STATE
*walk_state
,
49 ACPI_PARSE_OBJECT
*op
,
52 ACPI_STATUS status
= AE_OK
;
53 ACPI_OPERAND_OBJECT
*obj_desc
;
56 walk_state
->control_state
->common
.state
= 0;
59 status
= acpi_ds_result_pop (&obj_desc
, walk_state
);
60 if (ACPI_FAILURE (status
)) {
66 status
= acpi_ds_create_operand (walk_state
, op
, 0);
67 if (ACPI_FAILURE (status
)) {
71 status
= acpi_aml_resolve_to_value (&walk_state
->operands
[0], walk_state
);
72 if (ACPI_FAILURE (status
)) {
76 obj_desc
= walk_state
->operands
[0];
80 return (AE_AML_NO_OPERAND
);
85 * Result of predicate evaluation currently must
89 if (obj_desc
->common
.type
!= ACPI_TYPE_INTEGER
) {
90 status
= AE_AML_OPERAND_TYPE
;
95 /* Truncate the predicate to 32-bits if necessary */
97 acpi_aml_truncate_for32bit_table (obj_desc
, walk_state
);
100 * Save the result of the predicate evaluation on
104 if (obj_desc
->integer
.value
) {
105 walk_state
->control_state
->common
.value
= TRUE
;
110 * Predicate is FALSE, we will just toss the
111 * rest of the package
114 walk_state
->control_state
->common
.value
= FALSE
;
115 status
= AE_CTRL_FALSE
;
121 /* Break to debugger to display result */
123 DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc
, walk_state
));
126 * Delete the predicate result object (we know that
127 * we don't need it anymore)
130 acpi_cm_remove_reference (obj_desc
);
132 walk_state
->control_state
->common
.state
= CONTROL_NORMAL
;
138 /*****************************************************************************
140 * FUNCTION: Acpi_ds_exec_begin_op
142 * PARAMETERS: Walk_state - Current state of the parse tree walk
143 * Op - Op that has been just been reached in the
144 * walk; Arguments have not been evaluated yet.
148 * DESCRIPTION: Descending callback used during the execution of control
149 * methods. This is where most operators and operands are
150 * dispatched to the interpreter.
152 ****************************************************************************/
155 acpi_ds_exec_begin_op (
157 ACPI_PARSE_OBJECT
*op
,
158 ACPI_WALK_STATE
*walk_state
,
159 ACPI_PARSE_OBJECT
**out_op
)
161 ACPI_OPCODE_INFO
*op_info
;
162 ACPI_STATUS status
= AE_OK
;
166 status
= acpi_ds_load2_begin_op (opcode
, NULL
, walk_state
, out_op
);
167 if (ACPI_FAILURE (status
)) {
174 if (op
== walk_state
->origin
) {
183 * If the previous opcode was a conditional, this opcode
184 * must be the beginning of the associated predicate.
185 * Save this knowledge in the current scope descriptor
188 if ((walk_state
->control_state
) &&
189 (walk_state
->control_state
->common
.state
==
190 CONTROL_CONDITIONAL_EXECUTING
)) {
191 walk_state
->control_state
->common
.state
= CONTROL_PREDICATE_EXECUTING
;
193 /* Save start of predicate */
195 walk_state
->control_state
->control
.predicate_op
= op
;
199 op_info
= acpi_ps_get_opcode_info (op
->opcode
);
201 /* We want to send namepaths to the load code */
203 if (op
->opcode
== AML_NAMEPATH_OP
) {
204 op_info
->flags
= OPTYPE_NAMED_OBJECT
;
209 * Handle the opcode based upon the opcode type
212 switch (ACPI_GET_OP_CLASS (op_info
)) {
215 status
= acpi_ds_result_stack_push (walk_state
);
216 if (ACPI_FAILURE (status
)) {
220 status
= acpi_ds_exec_begin_control_op (walk_state
, op
);
224 case OPTYPE_NAMED_OBJECT
:
226 if (walk_state
->walk_type
== WALK_METHOD
) {
228 * Found a named object declaration during method
229 * execution; we must enter this object into the
230 * namespace. The created object is temporary and
231 * will be deleted upon completion of the execution
235 status
= acpi_ds_load2_begin_op (op
->opcode
, op
, walk_state
, NULL
);
239 if (op
->opcode
== AML_REGION_OP
) {
240 status
= acpi_ds_result_stack_push (walk_state
);
246 /* most operators with arguments */
248 case OPTYPE_MONADIC1
:
250 case OPTYPE_MONADIC2
:
251 case OPTYPE_MONADIC2_r
:
253 case OPTYPE_DYADIC2_r
:
254 case OPTYPE_DYADIC2_s
:
255 case OPTYPE_RECONFIGURATION
:
259 case OPTYPE_CREATE_FIELD
:
261 /* Start a new result/operand state */
263 status
= acpi_ds_result_stack_push (walk_state
);
271 /* Nothing to do here during method execution */
277 /*****************************************************************************
279 * FUNCTION: Acpi_ds_exec_end_op
281 * PARAMETERS: Walk_state - Current state of the parse tree walk
282 * Op - Op that has been just been completed in the
283 * walk; Arguments have now been evaluated.
287 * DESCRIPTION: Ascending callback used during the execution of control
288 * methods. The only thing we really need to do here is to
289 * notice the beginning of IF, ELSE, and WHILE blocks.
291 ****************************************************************************/
294 acpi_ds_exec_end_op (
295 ACPI_WALK_STATE
*walk_state
,
296 ACPI_PARSE_OBJECT
*op
)
298 ACPI_STATUS status
= AE_OK
;
301 ACPI_PARSE_OBJECT
*next_op
;
302 ACPI_NAMESPACE_NODE
*node
;
303 ACPI_PARSE_OBJECT
*first_arg
;
304 ACPI_OPERAND_OBJECT
*result_obj
= NULL
;
305 ACPI_OPCODE_INFO
*op_info
;
309 opcode
= (u16
) op
->opcode
;
312 op_info
= acpi_ps_get_opcode_info (op
->opcode
);
313 if (ACPI_GET_OP_TYPE (op_info
) != ACPI_OP_TYPE_OPCODE
) {
314 return (AE_NOT_IMPLEMENTED
);
317 optype
= (u8
) ACPI_GET_OP_CLASS (op_info
);
318 first_arg
= op
->value
.arg
;
320 /* Init the walk state */
322 walk_state
->num_operands
= 0;
323 walk_state
->return_desc
= NULL
;
324 walk_state
->op_info
= op_info
;
325 walk_state
->opcode
= opcode
;
328 /* Call debugger for single step support (DEBUG build only) */
330 DEBUGGER_EXEC (status
= acpi_db_single_step (walk_state
, op
, optype
));
331 DEBUGGER_EXEC (if (ACPI_FAILURE (status
)) {return (status
);});
334 /* Decode the opcode */
337 case OPTYPE_UNDEFINED
:
339 return (AE_NOT_IMPLEMENTED
);
346 case OPTYPE_CONSTANT
: /* argument type only */
347 case OPTYPE_LITERAL
: /* argument type only */
348 case OPTYPE_DATA_TERM
: /* argument type only */
349 case OPTYPE_LOCAL_VARIABLE
: /* argument type only */
350 case OPTYPE_METHOD_ARGUMENT
: /* argument type only */
354 /* most operators with arguments */
356 case OPTYPE_MONADIC1
:
358 case OPTYPE_MONADIC2
:
359 case OPTYPE_MONADIC2_r
:
361 case OPTYPE_DYADIC2_r
:
362 case OPTYPE_DYADIC2_s
:
363 case OPTYPE_RECONFIGURATION
:
369 /* Build resolved operand stack */
371 status
= acpi_ds_create_operands (walk_state
, first_arg
);
372 if (ACPI_FAILURE (status
)) {
376 operand_index
= walk_state
->num_operands
- 1;
379 /* Done with this result state (Now that operand stack is built) */
381 status
= acpi_ds_result_stack_pop (walk_state
);
382 if (ACPI_FAILURE (status
)) {
387 case OPTYPE_MONADIC1
:
389 /* 1 Operand, 0 External_result, 0 Internal_result */
391 status
= acpi_aml_exec_monadic1 (opcode
, walk_state
);
395 case OPTYPE_MONADIC2
:
397 /* 1 Operand, 0 External_result, 1 Internal_result */
399 status
= acpi_aml_exec_monadic2 (opcode
, walk_state
, &result_obj
);
403 case OPTYPE_MONADIC2_r
:
405 /* 1 Operand, 1 External_result, 1 Internal_result */
407 status
= acpi_aml_exec_monadic2_r (opcode
, walk_state
, &result_obj
);
413 /* 2 Operands, 0 External_result, 0 Internal_result */
415 status
= acpi_aml_exec_dyadic1 (opcode
, walk_state
);
421 /* 2 Operands, 0 External_result, 1 Internal_result */
423 status
= acpi_aml_exec_dyadic2 (opcode
, walk_state
, &result_obj
);
427 case OPTYPE_DYADIC2_r
:
429 /* 2 Operands, 1 or 2 External_results, 1 Internal_result */
431 status
= acpi_aml_exec_dyadic2_r (opcode
, walk_state
, &result_obj
);
435 case OPTYPE_DYADIC2_s
: /* Synchronization Operator */
437 /* 2 Operands, 0 External_result, 1 Internal_result */
439 status
= acpi_aml_exec_dyadic2_s (opcode
, walk_state
, &result_obj
);
443 case OPTYPE_INDEX
: /* Type 2 opcode with 3 operands */
445 /* 3 Operands, 1 External_result, 1 Internal_result */
447 status
= acpi_aml_exec_index (walk_state
, &result_obj
);
451 case OPTYPE_MATCH
: /* Type 2 opcode with 6 operands */
453 /* 6 Operands, 0 External_result, 1 Internal_result */
455 status
= acpi_aml_exec_match (walk_state
, &result_obj
);
459 case OPTYPE_RECONFIGURATION
:
461 /* 1 or 2 operands, 0 Internal Result */
463 status
= acpi_aml_exec_reconfiguration (opcode
, walk_state
);
469 /* 3 Operands, 0 External_result, 0 Internal_result */
471 status
= acpi_aml_exec_fatal (walk_state
);
476 * If a result object was returned from above, push it on the
477 * current result stack
479 if (ACPI_SUCCESS (status
) &&
481 status
= acpi_ds_result_push (result_obj
, walk_state
);
487 case OPTYPE_CONTROL
: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
489 /* 1 Operand, 0 External_result, 0 Internal_result */
491 status
= acpi_ds_exec_end_control_op (walk_state
, op
);
493 acpi_ds_result_stack_pop (walk_state
);
497 case OPTYPE_METHOD_CALL
:
500 * (AML_METHODCALL) Op->Value->Arg->Node contains
501 * the method Node pointer
503 /* Next_op points to the op that holds the method name */
506 node
= next_op
->node
;
508 /* Next_op points to first argument op */
510 next_op
= next_op
->next
;
513 * Get the method's arguments and put them on the operand stack
515 status
= acpi_ds_create_operands (walk_state
, next_op
);
516 if (ACPI_FAILURE (status
)) {
521 * Since the operands will be passed to another
522 * control method, we must resolve all local
523 * references here (Local variables, arguments
524 * to *this* method, etc.)
527 status
= acpi_ds_resolve_operands (walk_state
);
528 if (ACPI_FAILURE (status
)) {
533 * Tell the walk loop to preempt this running method and
534 * execute the new method
536 status
= AE_CTRL_TRANSFER
;
539 * Return now; we don't want to disturb anything,
540 * especially the operand count!
546 case OPTYPE_CREATE_FIELD
:
548 status
= acpi_ds_load2_end_op (walk_state
, op
);
549 if (ACPI_FAILURE (status
)) {
553 status
= acpi_ds_eval_field_unit_operands (walk_state
, op
);
557 case OPTYPE_NAMED_OBJECT
:
559 status
= acpi_ds_load2_end_op (walk_state
, op
);
560 if (ACPI_FAILURE (status
)) {
564 switch (op
->opcode
) {
567 status
= acpi_ds_eval_region_operands (walk_state
, op
);
568 if (ACPI_FAILURE (status
)) {
572 status
= acpi_ds_result_stack_pop (walk_state
);
582 /* Alias creation was already handled by call
588 /* Nothing needs to be done */
598 status
= AE_NOT_IMPLEMENTED
;
604 * ACPI 2.0 support for 64-bit integers:
605 * Truncate numeric result value if we are executing from a 32-bit ACPI table
607 acpi_aml_truncate_for32bit_table (result_obj
, walk_state
);
610 * Check if we just completed the evaluation of a
611 * conditional predicate
614 if ((walk_state
->control_state
) &&
615 (walk_state
->control_state
->common
.state
==
616 CONTROL_PREDICATE_EXECUTING
) &&
617 (walk_state
->control_state
->control
.predicate_op
== op
)) {
618 status
= acpi_ds_get_predicate_value (walk_state
, op
, (u32
) result_obj
);
625 /* Break to debugger to display result */
627 DEBUGGER_EXEC (acpi_db_display_result_object (result_obj
, walk_state
));
630 * Delete the result op if and only if:
631 * Parent will not use the result -- such as any
632 * non-nested type2 op in a method (parent will be method)
634 acpi_ds_delete_result_if_not_used (op
, result_obj
, walk_state
);
637 /* Always clear the object stack */
639 /* TBD: [Investigate] Clear stack of return value,
640 but don't delete it */
641 walk_state
->num_operands
= 0;