dswexec.c
来自「是关于linux2.5.1的完全源码」· C语言 代码 · 共 636 行 · 第 1/2 页
C
636 行
acpi_ds_exec_end_op ( acpi_walk_state *walk_state){ acpi_parse_object *op; acpi_status status = AE_OK; u32 op_type; u32 op_class; acpi_parse_object *next_op; acpi_parse_object *first_arg; u32 i; 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_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode %X\n", op->opcode)); return_ACPI_STATUS (AE_NOT_IMPLEMENTED); } first_arg = op->value.arg; /* Init the walk state */ walk_state->num_operands = 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. -- do nothing */ 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; } /* Done with this result state (Now that operand stack is built) */ status = acpi_ds_result_stack_pop (walk_state); if (ACPI_FAILURE (status)) { goto cleanup; } /* 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)) { ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, acpi_ps_get_opcode_name (walk_state->opcode), walk_state->num_operands, "after Ex_resolve_operands"); /* * 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 { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "[%s]: Could not resolve operands, %s\n", acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception (status))); } /* Always delete the argument objects and clear the operand stack */ for (i = 0; i < walk_state->num_operands; i++) { /* * Remove a reference to all operands, including both * "Arguments" and "Targets". */ acpi_ut_remove_reference (walk_state->operands[i]); walk_state->operands[i] = NULL; } walk_state->num_operands = 0; /* * 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); acpi_ds_result_stack_pop (walk_state); break; case AML_TYPE_METHOD_CALL: ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", op)); /* * (AML_METHODCALL) Op->Value->Arg->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->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)) { 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 Create_field 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 Create_object (Buffer/Package) Op=%p\n", op)); switch (op->parent->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->parent->node; walk_state->num_operands = 1; status = acpi_ds_create_node (walk_state, op->parent->node, op->parent); if (ACPI_FAILURE (status)) { break; } /* Fall through */ case AML_INT_EVAL_SUBTREE_OP: status = acpi_ds_eval_data_object_operands (walk_state, op, acpi_ns_get_attached_object (op->parent->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 (ACPI_SUCCESS (status) && 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->opcode == AML_REGION_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Executing Op_region Address/Length Op=%p\n", op)); status = acpi_ds_eval_region_operands (walk_state, op); if (ACPI_FAILURE (status)) { break; } status = acpi_ds_result_stack_pop (walk_state); } break; case AML_TYPE_UNDEFINED: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Undefined opcode type Op=%p\n", 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_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n", op_class, op_type, op->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, walk_state); /* * Check if we just completed the evaluation of a * conditional predicate */ if ((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); } /* Always clear the object stack */ walk_state->num_operands = 0; return_ACPI_STATUS (status);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?