diff options
Diffstat (limited to 'drivers/acpi/dispatcher/dswexec.c')
-rw-r--r-- | drivers/acpi/dispatcher/dswexec.c | 746 |
1 files changed, 0 insertions, 746 deletions
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c deleted file mode 100644 index 2482cbd37f25..000000000000 --- a/drivers/acpi/dispatcher/dswexec.c +++ /dev/null @@ -1,746 +0,0 @@ -/****************************************************************************** - * - * Module Name: dswexec - Dispatcher method execution callbacks; - * dispatch to interpreter. - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2008, Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#include <acpi/acpi.h> -#include <acpi/accommon.h> -#include <acpi/acparser.h> -#include <acpi/amlcode.h> -#include <acpi/acdispat.h> -#include <acpi/acinterp.h> -#include <acpi/acnamesp.h> -#include <acpi/acdebug.h> - -#define _COMPONENT ACPI_DISPATCHER -ACPI_MODULE_NAME("dswexec") - -/* - * Dispatch table for opcode classes - */ -static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch[] = { - acpi_ex_opcode_0A_0T_1R, - acpi_ex_opcode_1A_0T_0R, - acpi_ex_opcode_1A_0T_1R, - acpi_ex_opcode_1A_1T_0R, - acpi_ex_opcode_1A_1T_1R, - acpi_ex_opcode_2A_0T_0R, - acpi_ex_opcode_2A_0T_1R, - acpi_ex_opcode_2A_1T_1R, - acpi_ex_opcode_2A_2T_1R, - acpi_ex_opcode_3A_0T_0R, - acpi_ex_opcode_3A_1T_1R, - acpi_ex_opcode_6A_0T_1R -}; - -/***************************************************************************** - * - * FUNCTION: acpi_ds_get_predicate_value - * - * PARAMETERS: walk_state - Current state of the parse tree walk - * result_obj - if non-zero, pop result from result stack - * - * RETURN: Status - * - * DESCRIPTION: Get the result of a predicate evaluation - * - ****************************************************************************/ - -acpi_status -acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, - union acpi_operand_object *result_obj) -{ - acpi_status status = AE_OK; - union acpi_operand_object *obj_desc; - union acpi_operand_object *local_obj_desc = NULL; - - ACPI_FUNCTION_TRACE_PTR(ds_get_predicate_value, walk_state); - - walk_state->control_state->common.state = 0; - - if (result_obj) { - status = acpi_ds_result_pop(&obj_desc, walk_state); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Could not get result from predicate evaluation")); - - return_ACPI_STATUS(status); - } - } else { - status = acpi_ds_create_operand(walk_state, walk_state->op, 0); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - status = - acpi_ex_resolve_to_value(&walk_state->operands[0], - walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - obj_desc = walk_state->operands[0]; - } - - if (!obj_desc) { - ACPI_ERROR((AE_INFO, - "No predicate ObjDesc=%p State=%p", - obj_desc, walk_state)); - - return_ACPI_STATUS(AE_AML_NO_OPERAND); - } - - /* - * Result of predicate evaluation must be an Integer - * object. Implicitly convert the argument if necessary. - */ - status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, 16); - if (ACPI_FAILURE(status)) { - goto cleanup; - } - - if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) { - ACPI_ERROR((AE_INFO, - "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X", - obj_desc, walk_state, - ACPI_GET_OBJECT_TYPE(obj_desc))); - - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - - /* Truncate the predicate to 32-bits if necessary */ - - acpi_ex_truncate_for32bit_table(local_obj_desc); - - /* - * Save the result of the predicate evaluation on - * the control stack - */ - if (local_obj_desc->integer.value) { - walk_state->control_state->common.value = TRUE; - } else { - /* - * Predicate is FALSE, we will just toss the - * rest of the package - */ - walk_state->control_state->common.value = FALSE; - status = AE_CTRL_FALSE; - } - - /* Predicate can be used for an implicit return value */ - - (void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE); - - cleanup: - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", - walk_state->control_state->common.value, - walk_state->op)); - - /* Break to debugger to display result */ - - ACPI_DEBUGGER_EXEC(acpi_db_display_result_object - (local_obj_desc, walk_state)); - - /* - * Delete the predicate result object (we know that - * we don't need it anymore) - */ - if (local_obj_desc != obj_desc) { - acpi_ut_remove_reference(local_obj_desc); - } - acpi_ut_remove_reference(obj_desc); - - walk_state->control_state->common.state = ACPI_CONTROL_NORMAL; - return_ACPI_STATUS(status); -} - -/***************************************************************************** - * - * FUNCTION: acpi_ds_exec_begin_op - * - * PARAMETERS: walk_state - Current state of the parse tree walk - * out_op - Where to return op if a new one is created - * - * RETURN: Status - * - * DESCRIPTION: Descending callback used during the execution of control - * methods. This is where most operators and operands are - * dispatched to the interpreter. - * - ****************************************************************************/ - -acpi_status -acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, - union acpi_parse_object **out_op) -{ - union acpi_parse_object *op; - acpi_status status = AE_OK; - u32 opcode_class; - - ACPI_FUNCTION_TRACE_PTR(ds_exec_begin_op, walk_state); - - op = walk_state->op; - if (!op) { - status = acpi_ds_load2_begin_op(walk_state, out_op); - if (ACPI_FAILURE(status)) { - goto error_exit; - } - - op = *out_op; - walk_state->op = op; - walk_state->opcode = op->common.aml_opcode; - walk_state->op_info = - acpi_ps_get_opcode_info(op->common.aml_opcode); - - if (acpi_ns_opens_scope(walk_state->op_info->object_type)) { - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "(%s) Popping scope for Op %p\n", - acpi_ut_get_type_name(walk_state-> - op_info-> - object_type), - op)); - - status = acpi_ds_scope_stack_pop(walk_state); - if (ACPI_FAILURE(status)) { - goto error_exit; - } - } - } - - if (op == walk_state->origin) { - if (out_op) { - *out_op = op; - } - - return_ACPI_STATUS(AE_OK); - } - - /* - * If the previous opcode was a conditional, this opcode - * must be the beginning of the associated predicate. - * Save this knowledge in the current scope descriptor - */ - if ((walk_state->control_state) && - (walk_state->control_state->common.state == - ACPI_CONTROL_CONDITIONAL_EXECUTING)) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Exec predicate Op=%p State=%p\n", op, - walk_state)); - - walk_state->control_state->common.state = - ACPI_CONTROL_PREDICATE_EXECUTING; - - /* Save start of predicate */ - - walk_state->control_state->control.predicate_op = op; - } - - opcode_class = walk_state->op_info->class; - - /* We want to send namepaths to the load code */ - - if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { - opcode_class = AML_CLASS_NAMED_OBJECT; - } - - /* - * Handle the opcode based upon the opcode type - */ - switch (opcode_class) { - case AML_CLASS_CONTROL: - - status = acpi_ds_exec_begin_control_op(walk_state, op); - break; - - case AML_CLASS_NAMED_OBJECT: - - if (walk_state->walk_type & ACPI_WALK_METHOD) { - /* - * Found a named object declaration during method execution; - * we must enter this object into the namespace. The created - * object is temporary and will be deleted upon completion of - * the execution of this method. - */ - status = acpi_ds_load2_begin_op(walk_state, NULL); - } - - break; - - case AML_CLASS_EXECUTE: - case AML_CLASS_CREATE: - - break; - - default: - break; - } - - /* Nothing to do here during method execution */ - - return_ACPI_STATUS(status); - - error_exit: - status = acpi_ds_method_error(status, walk_state); - return_ACPI_STATUS(status); -} - -/***************************************************************************** - * - * FUNCTION: acpi_ds_exec_end_op - * - * PARAMETERS: walk_state - Current state of the parse tree walk - * - * RETURN: Status - * - * DESCRIPTION: Ascending callback used during the execution of control - * methods. The only thing we really need to do here is to - * notice the beginning of IF, ELSE, and WHILE blocks. - * - ****************************************************************************/ - -acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) -{ - union acpi_parse_object *op; - acpi_status status = AE_OK; - u32 op_type; - u32 op_class; - union acpi_parse_object *next_op; - union acpi_parse_object *first_arg; - - ACPI_FUNCTION_TRACE_PTR(ds_exec_end_op, walk_state); - - op = walk_state->op; - op_type = walk_state->op_info->type; - op_class = walk_state->op_info->class; - - if (op_class == AML_CLASS_UNKNOWN) { - ACPI_ERROR((AE_INFO, "Unknown opcode %X", - op->common.aml_opcode)); - return_ACPI_STATUS(AE_NOT_IMPLEMENTED); - } - - first_arg = op->common.value.arg; - - /* Init the walk state */ - - walk_state->num_operands = 0; - walk_state->operand_index = 0; - walk_state->return_desc = NULL; - walk_state->result_obj = NULL; - - /* Call debugger for single step support (DEBUG build only) */ - - ACPI_DEBUGGER_EXEC(status = - acpi_db_single_step(walk_state, op, op_class)); - ACPI_DEBUGGER_EXEC(if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status);} - ) ; - - /* Decode the Opcode Class */ - - switch (op_class) { - case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */ - - if (walk_state->opcode == AML_INT_NAMEPATH_OP) { - status = acpi_ds_evaluate_name_path(walk_state); - if (ACPI_FAILURE(status)) { - goto cleanup; - } - } - break; - - case AML_CLASS_EXECUTE: /* Most operators with arguments */ - - /* Build resolved operand stack */ - - status = acpi_ds_create_operands(walk_state, first_arg); - if (ACPI_FAILURE(status)) { - goto cleanup; - } - - /* - * All opcodes require operand resolution, with the only exceptions - * being the object_type and size_of operators. - */ - if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) { - - /* Resolve all operands */ - - status = acpi_ex_resolve_operands(walk_state->opcode, - &(walk_state-> - operands - [walk_state-> - num_operands - 1]), - walk_state); - } - - if (ACPI_SUCCESS(status)) { - /* - * Dispatch the request to the appropriate interpreter handler - * routine. There is one routine per opcode "type" based upon the - * number of opcode arguments and return type. - */ - status = - acpi_gbl_op_type_dispatch[op_type] (walk_state); - } else { - /* - * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the - * Local is uninitialized. - */ - if ((status == AE_AML_UNINITIALIZED_LOCAL) && - (walk_state->opcode == AML_STORE_OP) && - (walk_state->operands[0]->common.type == - ACPI_TYPE_LOCAL_REFERENCE) - && (walk_state->operands[1]->common.type == - ACPI_TYPE_LOCAL_REFERENCE) - && (walk_state->operands[0]->reference.class == - walk_state->operands[1]->reference.class) - && (walk_state->operands[0]->reference.value == - walk_state->operands[1]->reference.value)) { - status = AE_OK; - } else { - ACPI_EXCEPTION((AE_INFO, status, - "While resolving operands for [%s]", - acpi_ps_get_opcode_name - (walk_state->opcode))); - } - } - - /* Always delete the argument objects and clear the operand stack */ - - acpi_ds_clear_operands(walk_state); - - /* - * If a result object was returned from above, push it on the - * current result stack - */ - if (ACPI_SUCCESS(status) && walk_state->result_obj) { - status = - acpi_ds_result_push(walk_state->result_obj, - walk_state); - } - break; - - default: - - switch (op_type) { - case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */ - - /* 1 Operand, 0 external_result, 0 internal_result */ - - status = acpi_ds_exec_end_control_op(walk_state, op); - - break; - - case AML_TYPE_METHOD_CALL: - - /* - * If the method is referenced from within a package - * declaration, it is not a invocation of the method, just - * a reference to it. - */ - if ((op->asl.parent) && - ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) - || (op->asl.parent->asl.aml_opcode == - AML_VAR_PACKAGE_OP))) { - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Method Reference in a Package, Op=%p\n", - op)); - - op->common.node = - (struct acpi_namespace_node *)op->asl.value. - arg->asl.node; - acpi_ut_add_reference(op->asl.value.arg->asl. - node->object); - return_ACPI_STATUS(AE_OK); - } - - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Method invocation, Op=%p\n", op)); - - /* - * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains - * the method Node pointer - */ - /* next_op points to the op that holds the method name */ - - next_op = first_arg; - - /* next_op points to first argument op */ - - next_op = next_op->common.next; - - /* - * Get the method's arguments and put them on the operand stack - */ - status = acpi_ds_create_operands(walk_state, next_op); - if (ACPI_FAILURE(status)) { - break; - } - - /* - * Since the operands will be passed to another control method, - * we must resolve all local references here (Local variables, - * arguments to *this* method, etc.) - */ - status = acpi_ds_resolve_operands(walk_state); - if (ACPI_FAILURE(status)) { - - /* On error, clear all resolved operands */ - - acpi_ds_clear_operands(walk_state); - break; - } - - /* - * Tell the walk loop to preempt this running method and - * execute the new method - */ - status = AE_CTRL_TRANSFER; - - /* - * Return now; we don't want to disturb anything, - * especially the operand count! - */ - return_ACPI_STATUS(status); - - case AML_TYPE_CREATE_FIELD: - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Executing CreateField Buffer/Index Op=%p\n", - op)); - - status = acpi_ds_load2_end_op(walk_state); - if (ACPI_FAILURE(status)) { - break; - } - - status = - acpi_ds_eval_buffer_field_operands(walk_state, op); - break; - - case AML_TYPE_CREATE_OBJECT: - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Executing CreateObject (Buffer/Package) Op=%p\n", - op)); - - switch (op->common.parent->common.aml_opcode) { - case AML_NAME_OP: - - /* - * Put the Node on the object stack (Contains the ACPI Name - * of this object) - */ - walk_state->operands[0] = - (void *)op->common.parent->common.node; - walk_state->num_operands = 1; - - status = acpi_ds_create_node(walk_state, - op->common.parent-> - common.node, - op->common.parent); - if (ACPI_FAILURE(status)) { - break; - } - - /* Fall through */ - /*lint -fallthrough */ - - case AML_INT_EVAL_SUBTREE_OP: - - status = - acpi_ds_eval_data_object_operands - (walk_state, op, - acpi_ns_get_attached_object(op->common. - parent->common. - node)); - break; - - default: - - status = - acpi_ds_eval_data_object_operands - (walk_state, op, NULL); - break; - } - - /* - * If a result object was returned from above, push it on the - * current result stack - */ - if (walk_state->result_obj) { - status = - acpi_ds_result_push(walk_state->result_obj, - walk_state); - } - break; - - case AML_TYPE_NAMED_FIELD: - case AML_TYPE_NAMED_COMPLEX: - case AML_TYPE_NAMED_SIMPLE: - case AML_TYPE_NAMED_NO_OBJ: - - status = acpi_ds_load2_end_op(walk_state); - if (ACPI_FAILURE(status)) { - break; - } - - if (op->common.aml_opcode == AML_REGION_OP) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Executing OpRegion Address/Length Op=%p\n", - op)); - - status = - acpi_ds_eval_region_operands(walk_state, - op); - if (ACPI_FAILURE(status)) { - break; - } - } else if (op->common.aml_opcode == AML_DATA_REGION_OP) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Executing DataTableRegion Strings Op=%p\n", - op)); - - status = - acpi_ds_eval_table_region_operands - (walk_state, op); - if (ACPI_FAILURE(status)) { - break; - } - } else if (op->common.aml_opcode == AML_BANK_FIELD_OP) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Executing BankField Op=%p\n", - op)); - - status = - acpi_ds_eval_bank_field_operands(walk_state, - op); - if (ACPI_FAILURE(status)) { - break; - } - } - break; - - case AML_TYPE_UNDEFINED: - - ACPI_ERROR((AE_INFO, - "Undefined opcode type Op=%p", op)); - return_ACPI_STATUS(AE_NOT_IMPLEMENTED); - - case AML_TYPE_BOGUS: - - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Internal opcode=%X type Op=%p\n", - walk_state->opcode, op)); - break; - - default: - - ACPI_ERROR((AE_INFO, - "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p", - op_class, op_type, op->common.aml_opcode, - op)); - - status = AE_NOT_IMPLEMENTED; - break; - } - } - - /* - * ACPI 2.0 support for 64-bit integers: Truncate numeric - * result value if we are executing from a 32-bit ACPI table - */ - acpi_ex_truncate_for32bit_table(walk_state->result_obj); - - /* - * Check if we just completed the evaluation of a - * conditional predicate - */ - if ((ACPI_SUCCESS(status)) && - (walk_state->control_state) && - (walk_state->control_state->common.state == - ACPI_CONTROL_PREDICATE_EXECUTING) && - (walk_state->control_state->control.predicate_op == op)) { - status = - acpi_ds_get_predicate_value(walk_state, - walk_state->result_obj); - walk_state->result_obj = NULL; - } - - cleanup: - - if (walk_state->result_obj) { - - /* Break to debugger to display result */ - - ACPI_DEBUGGER_EXEC(acpi_db_display_result_object - (walk_state->result_obj, walk_state)); - - /* - * Delete the result op if and only if: - * Parent will not use the result -- such as any - * non-nested type2 op in a method (parent will be method) - */ - acpi_ds_delete_result_if_not_used(op, walk_state->result_obj, - walk_state); - } -#ifdef _UNDER_DEVELOPMENT - - if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) { - acpi_db_method_end(walk_state); - } -#endif - - /* Invoke exception handler on error */ - - if (ACPI_FAILURE(status)) { - status = acpi_ds_method_error(status, walk_state); - } - - /* Always clear the object stack */ - - walk_state->num_operands = 0; - return_ACPI_STATUS(status); -} |