/******************************************************************************* * * FUNCTION: acpi_ds_exec_begin_control_op * * PARAMETERS: walk_list - The list that owns the walk stack * op - The control Op * * RETURN: Status * * DESCRIPTION: Handles all control ops encountered during control method * execution. *
******************************************************************************/
acpi_status
acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, union acpi_parse_object *op)
{
acpi_status status = AE_OK; union acpi_generic_state *control_state;
switch (op->common.aml_opcode) { case AML_WHILE_OP: /* * If this is an additional iteration of a while loop, continue. * There is no need to allocate a new control state.
*/ if (walk_state->control_state) { if (walk_state->control_state->control.
aml_predicate_start ==
(walk_state->parser_state.aml - 1)) {
case AML_IF_OP: /* * IF/WHILE: Create a new control state to manage these * constructs. We need to manage these as a stack, in order * to handle nesting.
*/
control_state = acpi_ut_create_control_state(); if (!control_state) {
status = AE_NO_MEMORY; break;
} /* * Save a pointer to the predicate for multiple executions * of a loop
*/
control_state->control.aml_predicate_start =
walk_state->parser_state.aml - 1;
control_state->control.package_end =
walk_state->parser_state.pkg_end;
control_state->control.opcode = op->common.aml_opcode;
control_state->control.loop_timeout = acpi_os_get_timer() +
((u64)acpi_gbl_max_loop_iterations * ACPI_100NSEC_PER_SEC);
/* Push the control state on this walk's control stack */
/* Predicate is in the state object */ /* If predicate is true, the IF was executed, ignore ELSE part */
if (walk_state->last_predicate) {
status = AE_CTRL_TRUE;
}
break;
case AML_RETURN_OP:
break;
default:
break;
}
return (status);
}
/******************************************************************************* * * FUNCTION: acpi_ds_exec_end_control_op * * PARAMETERS: walk_list - The list that owns the walk stack * op - The control Op * * RETURN: Status * * DESCRIPTION: Handles all control ops encountered during control method * execution. *
******************************************************************************/
acpi_status
acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state, union acpi_parse_object *op)
{
acpi_status status = AE_OK; union acpi_generic_state *control_state;
/* * Save the result of the predicate in case there is an * ELSE to come
*/
walk_state->last_predicate =
(u8)walk_state->control_state->common.value;
/* * Pop the control state that was created at the start * of the IF and free it
*/
control_state =
acpi_ut_pop_generic_state(&walk_state->control_state);
acpi_ut_delete_generic_state(control_state); break;
control_state = walk_state->control_state; if (control_state->common.value) {
/* Predicate was true, the body of the loop was just executed */
/* * This infinite loop detection mechanism allows the interpreter * to escape possibly infinite loops. This can occur in poorly * written AML when the hardware does not respond within a while * loop and the loop does not implement a timeout.
*/ if (ACPI_TIME_AFTER(acpi_os_get_timer(),
control_state->control.
loop_timeout)) {
status = AE_AML_LOOP_TIMEOUT; break;
}
/* * Go back and evaluate the predicate and maybe execute the loop * another time
*/
status = AE_CTRL_PENDING;
walk_state->aml_last_while =
control_state->control.aml_predicate_start; break;
}
/* Predicate was false, terminate this while loop */
/* * One optional operand -- the return value * It can be either an immediate operand or a result that * has been bubbled up the tree
*/ if (op->common.value.arg) {
/* Since we have a real Return(), delete any implicit return */
acpi_ds_clear_implicit_return(walk_state);
/* Return statement has an immediate operand */
status =
acpi_ds_create_operands(walk_state,
op->common.value.arg); if (ACPI_FAILURE(status)) { return (status);
}
/* * If value being returned is a Reference (such as * an arg or local), resolve it now because it may * cease to exist at the end of the method.
*/
status =
acpi_ex_resolve_to_value(&walk_state->operands[0],
walk_state); if (ACPI_FAILURE(status)) { return (status);
}
/* * Get the return value and save as the last result * value. This is the only place where walk_state->return_desc * is set to anything other than zero!
*/
walk_state->return_desc = walk_state->operands[0];
} elseif (walk_state->result_count) {
/* Since we have a real Return(), delete any implicit return */
acpi_ds_clear_implicit_return(walk_state);
/* * The return value has come from a previous calculation. * * If value being returned is a Reference (such as * an arg or local), resolve it now because it may * cease to exist at the end of the method. * * Allow references created by the Index operator to return * unchanged.
*/ if ((ACPI_GET_DESCRIPTOR_TYPE
(walk_state->results->results.obj_desc[0]) ==
ACPI_DESC_TYPE_OPERAND)
&& ((walk_state->results->results.obj_desc[0])->
common.type == ACPI_TYPE_LOCAL_REFERENCE)
&& ((walk_state->results->results.obj_desc[0])->
reference.class != ACPI_REFCLASS_INDEX)) {
status =
acpi_ex_resolve_to_value(&walk_state->
results->results.
obj_desc[0],
walk_state); if (ACPI_FAILURE(status)) { return (status);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.