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;