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
37 #define _COMPONENT ACPI_DISPATCHER
38 MODULE_NAME ("dswexec")
41 /*****************************************************************************
43 * FUNCTION: Acpi_ds_get_predicate_value
45 * PARAMETERS: Walk_state - Current state of the parse tree walk
49 * DESCRIPTION: Get the result of a predicate evaluation
51 ****************************************************************************/
54 acpi_ds_get_predicate_value (
55 ACPI_WALK_STATE
*walk_state
,
56 ACPI_PARSE_OBJECT
*op
,
59 ACPI_STATUS status
= AE_OK
;
60 ACPI_OPERAND_OBJECT
*obj_desc
;
63 walk_state
->control_state
->common
.state
= 0;
66 status
= acpi_ds_result_pop (&obj_desc
, walk_state
);
67 if (ACPI_FAILURE (status
)) {
73 status
= acpi_ds_create_operand (walk_state
, op
, 0);
74 if (ACPI_FAILURE (status
)) {
78 status
= acpi_aml_resolve_to_value (&walk_state
->operands
[0], walk_state
);
79 if (ACPI_FAILURE (status
)) {
83 obj_desc
= walk_state
->operands
[0];
87 return (AE_AML_NO_OPERAND
);
92 * Result of predicate evaluation currently must
96 if (obj_desc
->common
.type
!= ACPI_TYPE_INTEGER
) {
97 status
= AE_AML_OPERAND_TYPE
;
102 /* Truncate the predicate to 32-bits if necessary */
104 acpi_aml_truncate_for32bit_table (obj_desc
, walk_state
);
107 * Save the result of the predicate evaluation on
111 if (obj_desc
->integer
.value
) {
112 walk_state
->control_state
->common
.value
= TRUE
;
117 * Predicate is FALSE, we will just toss the
118 * rest of the package
121 walk_state
->control_state
->common
.value
= FALSE
;
122 status
= AE_CTRL_FALSE
;
128 /* Break to debugger to display result */
130 DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc
, walk_state
));
133 * Delete the predicate result object (we know that
134 * we don't need it anymore)
137 acpi_cm_remove_reference (obj_desc
);
139 walk_state
->control_state
->common
.state
= CONTROL_NORMAL
;
145 /*****************************************************************************
147 * FUNCTION: Acpi_ds_exec_begin_op
149 * PARAMETERS: Walk_state - Current state of the parse tree walk
150 * Op - Op that has been just been reached in the
151 * walk; Arguments have not been evaluated yet.
155 * DESCRIPTION: Descending callback used during the execution of control
156 * methods. This is where most operators and operands are
157 * dispatched to the interpreter.
159 ****************************************************************************/
162 acpi_ds_exec_begin_op (
164 ACPI_PARSE_OBJECT
*op
,
165 ACPI_WALK_STATE
*walk_state
,
166 ACPI_PARSE_OBJECT
**out_op
)
168 ACPI_OPCODE_INFO
*op_info
;
169 ACPI_STATUS status
= AE_OK
;
173 status
= acpi_ds_load2_begin_op (opcode
, NULL
, walk_state
, out_op
);
174 if (ACPI_FAILURE (status
)) {
181 if (op
== walk_state
->origin
) {
190 * If the previous opcode was a conditional, this opcode
191 * must be the beginning of the associated predicate.
192 * Save this knowledge in the current scope descriptor
195 if ((walk_state
->control_state
) &&
196 (walk_state
->control_state
->common
.state
==
197 CONTROL_CONDITIONAL_EXECUTING
)) {
198 walk_state
->control_state
->common
.state
= CONTROL_PREDICATE_EXECUTING
;
200 /* Save start of predicate */
202 walk_state
->control_state
->control
.predicate_op
= op
;
206 op_info
= acpi_ps_get_opcode_info (op
->opcode
);
208 /* We want to send namepaths to the load code */
210 if (op
->opcode
== AML_NAMEPATH_OP
) {
211 op_info
->flags
= OPTYPE_NAMED_OBJECT
;
216 * Handle the opcode based upon the opcode type
219 switch (ACPI_GET_OP_CLASS (op_info
)) {
222 status
= acpi_ds_result_stack_push (walk_state
);
223 if (ACPI_FAILURE (status
)) {
227 status
= acpi_ds_exec_begin_control_op (walk_state
, op
);
231 case OPTYPE_NAMED_OBJECT
:
233 if (walk_state
->walk_type
== WALK_METHOD
) {
235 * Found a named object declaration during method
236 * execution; we must enter this object into the
237 * namespace. The created object is temporary and
238 * will be deleted upon completion of the execution
242 status
= acpi_ds_load2_begin_op (op
->opcode
, op
, walk_state
, NULL
);
246 if (op
->opcode
== AML_REGION_OP
) {
247 status
= acpi_ds_result_stack_push (walk_state
);
253 /* most operators with arguments */
255 case OPTYPE_MONADIC1
:
257 case OPTYPE_MONADIC2
:
258 case OPTYPE_MONADIC2_r
:
260 case OPTYPE_DYADIC2_r
:
261 case OPTYPE_DYADIC2_s
:
262 case OPTYPE_RECONFIGURATION
:
266 case OPTYPE_CREATE_FIELD
:
268 /* Start a new result/operand state */
270 status
= acpi_ds_result_stack_push (walk_state
);
278 /* Nothing to do here during method execution */
284 /*****************************************************************************
286 * FUNCTION: Acpi_ds_exec_end_op
288 * PARAMETERS: Walk_state - Current state of the parse tree walk
289 * Op - Op that has been just been completed in the
290 * walk; Arguments have now been evaluated.
294 * DESCRIPTION: Ascending callback used during the execution of control
295 * methods. The only thing we really need to do here is to
296 * notice the beginning of IF, ELSE, and WHILE blocks.
298 ****************************************************************************/
301 acpi_ds_exec_end_op (
302 ACPI_WALK_STATE
*walk_state
,
303 ACPI_PARSE_OBJECT
*op
)
305 ACPI_STATUS status
= AE_OK
;
308 ACPI_PARSE_OBJECT
*next_op
;
309 ACPI_NAMESPACE_NODE
*node
;
310 ACPI_PARSE_OBJECT
*first_arg
;
311 ACPI_OPERAND_OBJECT
*result_obj
= NULL
;
312 ACPI_OPCODE_INFO
*op_info
;
316 opcode
= (u16
) op
->opcode
;
319 op_info
= acpi_ps_get_opcode_info (op
->opcode
);
320 if (ACPI_GET_OP_TYPE (op_info
) != ACPI_OP_TYPE_OPCODE
) {
321 return (AE_NOT_IMPLEMENTED
);
324 optype
= (u8
) ACPI_GET_OP_CLASS (op_info
);
325 first_arg
= op
->value
.arg
;
327 /* Init the walk state */
329 walk_state
->num_operands
= 0;
330 walk_state
->return_desc
= NULL
;
331 walk_state
->op_info
= op_info
;
332 walk_state
->opcode
= opcode
;
335 /* Call debugger for single step support (DEBUG build only) */
337 DEBUGGER_EXEC (status
= acpi_db_single_step (walk_state
, op
, optype
));
338 DEBUGGER_EXEC (if (ACPI_FAILURE (status
)) {return (status
);});
341 /* Decode the opcode */
344 case OPTYPE_UNDEFINED
:
346 return (AE_NOT_IMPLEMENTED
);
353 case OPTYPE_CONSTANT
: /* argument type only */
354 case OPTYPE_LITERAL
: /* argument type only */
355 case OPTYPE_DATA_TERM
: /* argument type only */
356 case OPTYPE_LOCAL_VARIABLE
: /* argument type only */
357 case OPTYPE_METHOD_ARGUMENT
: /* argument type only */
361 /* most operators with arguments */
363 case OPTYPE_MONADIC1
:
365 case OPTYPE_MONADIC2
:
366 case OPTYPE_MONADIC2_r
:
368 case OPTYPE_DYADIC2_r
:
369 case OPTYPE_DYADIC2_s
:
370 case OPTYPE_RECONFIGURATION
:
376 /* Build resolved operand stack */
378 status
= acpi_ds_create_operands (walk_state
, first_arg
);
379 if (ACPI_FAILURE (status
)) {
383 operand_index
= walk_state
->num_operands
- 1;
386 /* Done with this result state (Now that operand stack is built) */
388 status
= acpi_ds_result_stack_pop (walk_state
);
389 if (ACPI_FAILURE (status
)) {
394 case OPTYPE_MONADIC1
:
396 /* 1 Operand, 0 External_result, 0 Internal_result */
398 status
= acpi_aml_exec_monadic1 (opcode
, walk_state
);
402 case OPTYPE_MONADIC2
:
404 /* 1 Operand, 0 External_result, 1 Internal_result */
406 status
= acpi_aml_exec_monadic2 (opcode
, walk_state
, &result_obj
);
410 case OPTYPE_MONADIC2_r
:
412 /* 1 Operand, 1 External_result, 1 Internal_result */
414 status
= acpi_aml_exec_monadic2_r (opcode
, walk_state
, &result_obj
);
420 /* 2 Operands, 0 External_result, 0 Internal_result */
422 status
= acpi_aml_exec_dyadic1 (opcode
, walk_state
);
428 /* 2 Operands, 0 External_result, 1 Internal_result */
430 status
= acpi_aml_exec_dyadic2 (opcode
, walk_state
, &result_obj
);
434 case OPTYPE_DYADIC2_r
:
436 /* 2 Operands, 1 or 2 External_results, 1 Internal_result */
438 status
= acpi_aml_exec_dyadic2_r (opcode
, walk_state
, &result_obj
);
442 case OPTYPE_DYADIC2_s
: /* Synchronization Operator */
444 /* 2 Operands, 0 External_result, 1 Internal_result */
446 status
= acpi_aml_exec_dyadic2_s (opcode
, walk_state
, &result_obj
);
450 case OPTYPE_INDEX
: /* Type 2 opcode with 3 operands */
452 /* 3 Operands, 1 External_result, 1 Internal_result */
454 status
= acpi_aml_exec_index (walk_state
, &result_obj
);
458 case OPTYPE_MATCH
: /* Type 2 opcode with 6 operands */
460 /* 6 Operands, 0 External_result, 1 Internal_result */
462 status
= acpi_aml_exec_match (walk_state
, &result_obj
);
466 case OPTYPE_RECONFIGURATION
:
468 /* 1 or 2 operands, 0 Internal Result */
470 status
= acpi_aml_exec_reconfiguration (opcode
, walk_state
);
476 /* 3 Operands, 0 External_result, 0 Internal_result */
478 status
= acpi_aml_exec_fatal (walk_state
);
483 * If a result object was returned from above, push it on the
484 * current result stack
486 if (ACPI_SUCCESS (status
) &&
488 status
= acpi_ds_result_push (result_obj
, walk_state
);
494 case OPTYPE_CONTROL
: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
496 /* 1 Operand, 0 External_result, 0 Internal_result */
498 status
= acpi_ds_exec_end_control_op (walk_state
, op
);
500 acpi_ds_result_stack_pop (walk_state
);
504 case OPTYPE_METHOD_CALL
:
507 * (AML_METHODCALL) Op->Value->Arg->Node contains
508 * the method Node pointer
510 /* Next_op points to the op that holds the method name */
513 node
= next_op
->node
;
515 /* Next_op points to first argument op */
517 next_op
= next_op
->next
;
520 * Get the method's arguments and put them on the operand stack
522 status
= acpi_ds_create_operands (walk_state
, next_op
);
523 if (ACPI_FAILURE (status
)) {
528 * Since the operands will be passed to another
529 * control method, we must resolve all local
530 * references here (Local variables, arguments
531 * to *this* method, etc.)
534 status
= acpi_ds_resolve_operands (walk_state
);
535 if (ACPI_FAILURE (status
)) {
540 * Tell the walk loop to preempt this running method and
541 * execute the new method
543 status
= AE_CTRL_TRANSFER
;
546 * Return now; we don't want to disturb anything,
547 * especially the operand count!
553 case OPTYPE_CREATE_FIELD
:
555 status
= acpi_ds_load2_end_op (walk_state
, op
);
556 if (ACPI_FAILURE (status
)) {
560 status
= acpi_ds_eval_field_unit_operands (walk_state
, op
);
564 case OPTYPE_NAMED_OBJECT
:
566 status
= acpi_ds_load2_end_op (walk_state
, op
);
567 if (ACPI_FAILURE (status
)) {
571 switch (op
->opcode
) {
574 status
= acpi_ds_eval_region_operands (walk_state
, op
);
575 if (ACPI_FAILURE (status
)) {
579 status
= acpi_ds_result_stack_pop (walk_state
);
589 /* Alias creation was already handled by call
595 /* Nothing needs to be done */
605 status
= AE_NOT_IMPLEMENTED
;
611 * ACPI 2.0 support for 64-bit integers:
612 * Truncate numeric result value if we are executing from a 32-bit ACPI table
614 acpi_aml_truncate_for32bit_table (result_obj
, walk_state
);
617 * Check if we just completed the evaluation of a
618 * conditional predicate
621 if ((walk_state
->control_state
) &&
622 (walk_state
->control_state
->common
.state
==
623 CONTROL_PREDICATE_EXECUTING
) &&
624 (walk_state
->control_state
->control
.predicate_op
== op
)) {
625 status
= acpi_ds_get_predicate_value (walk_state
, op
, (u32
) result_obj
);
632 /* Break to debugger to display result */
634 DEBUGGER_EXEC (acpi_db_display_result_object (result_obj
, walk_state
));
637 * Delete the result op if and only if:
638 * Parent will not use the result -- such as any
639 * non-nested type2 op in a method (parent will be method)
641 acpi_ds_delete_result_if_not_used (op
, result_obj
, walk_state
);
644 /* Always clear the object stack */
646 /* TBD: [Investigate] Clear stack of return value,
647 but don't delete it */
648 walk_state
->num_operands
= 0;