📄 psloop.c
字号:
status = acpi_ps_get_next_arg(walk_state, parser_state, GET_CURRENT_ARG_TYPE (walk_state-> arg_types), &arg); if (ACPI_FAILURE(status)) { goto close_this_op; } if (arg) { arg->common.aml_offset = walk_state->aml_offset; acpi_ps_append_arg(op, arg); } INCREMENT_ARG_LIST(walk_state-> arg_types); } /* Special processing for certain opcodes */ /* TBD (remove): Temporary mechanism to disable this code if needed */#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) && ((walk_state-> parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { /* * We want to skip If/Else/While constructs during Pass1 * because we want to actually conditionally execute the * code during Pass2. * * Except for disassembly, where we always want to * walk the If/Else/While packages */ switch (op->common.aml_opcode) { case AML_IF_OP: case AML_ELSE_OP: case AML_WHILE_OP: ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Pass1: Skipping an If/Else/While body\n")); /* Skip body of if/else/while in pass 1 */ parser_state->aml = parser_state->pkg_end; walk_state->arg_count = 0; break; default: break; } }#endif switch (op->common.aml_opcode) { case AML_METHOD_OP: /* * Skip parsing of control method * because we don't have enough info in the first pass * to parse it correctly. * * Save the length and address of the body */ op->named.data = parser_state->aml; op->named.length = (u32) (parser_state->pkg_end - parser_state->aml); /* Skip body of method */ parser_state->aml = parser_state->pkg_end; walk_state->arg_count = 0; break; case AML_BUFFER_OP: case AML_PACKAGE_OP: case AML_VAR_PACKAGE_OP: if ((op->common.parent) && (op->common.parent->common. aml_opcode == AML_NAME_OP) && (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2)) { /* * Skip parsing of Buffers and Packages * because we don't have enough info in the first pass * to parse them correctly. */ op->named.data = aml_op_start; op->named.length = (u32) (parser_state-> pkg_end - aml_op_start); /* Skip body */ parser_state->aml = parser_state->pkg_end; walk_state->arg_count = 0; } break; case AML_WHILE_OP: if (walk_state->control_state) { walk_state->control_state-> control.package_end = parser_state->pkg_end; } break; default: /* No action for all other opcodes */ break; } break; } } /* Check for arguments that need to be processed */ if (walk_state->arg_count) { /* * There are arguments (complex ones), push Op and * prepare for argument */ status = acpi_ps_push_scope(parser_state, op, walk_state->arg_types, walk_state->arg_count); if (ACPI_FAILURE(status)) { goto close_this_op; } op = NULL; continue; } /* * All arguments have been processed -- Op is complete, * prepare for next */ walk_state->op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); if (walk_state->op_info->flags & AML_NAMED) { if (acpi_gbl_depth) { acpi_gbl_depth--; } if (op->common.aml_opcode == AML_REGION_OP) { /* * Skip parsing of control method or opregion body, * because we don't have enough info in the first pass * to parse them correctly. * * Completed parsing an op_region declaration, we now * know the length. */ op->named.length = (u32) (parser_state->aml - op->named.data); } } if (walk_state->op_info->flags & AML_CREATE) { /* * Backup to beginning of create_xXXfield declaration (1 for * Opcode) * * body_length is unknown until we parse the body */ op->named.length = (u32) (parser_state->aml - op->named.data); } /* This op complete, notify the dispatcher */ if (walk_state->ascending_callback != NULL) { walk_state->op = op; walk_state->opcode = op->common.aml_opcode; status = walk_state->ascending_callback(walk_state); status = acpi_ps_next_parse_state(walk_state, op, status); if (status == AE_CTRL_PENDING) { status = AE_OK; goto close_this_op; } } close_this_op: /* * Finished one argument of the containing scope */ parser_state->scope->parse_scope.arg_count--; /* Finished with pre_op */ if (pre_op) { acpi_ps_free_op(pre_op); pre_op = NULL; } /* Close this Op (will result in parse subtree deletion) */ status2 = acpi_ps_complete_this_op(walk_state, op); if (ACPI_FAILURE(status2)) { return_ACPI_STATUS(status2); } op = NULL; switch (status) { case AE_OK: break; case AE_CTRL_TRANSFER: /* We are about to transfer to a called method. */ walk_state->prev_op = op; walk_state->prev_arg_types = walk_state->arg_types; return_ACPI_STATUS(status); case AE_CTRL_END: acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); if (op) { walk_state->op = op; walk_state->op_info = acpi_ps_get_opcode_info(op->common. aml_opcode); walk_state->opcode = op->common.aml_opcode; status = walk_state->ascending_callback(walk_state); status = acpi_ps_next_parse_state(walk_state, op, status); status2 = acpi_ps_complete_this_op(walk_state, op); if (ACPI_FAILURE(status2)) { return_ACPI_STATUS(status2); } op = NULL; } status = AE_OK; break; case AE_CTRL_BREAK: case AE_CTRL_CONTINUE: /* Pop off scopes until we find the While */ while (!op || (op->common.aml_opcode != AML_WHILE_OP)) { acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); } /* Close this iteration of the While loop */ walk_state->op = op; walk_state->op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); walk_state->opcode = op->common.aml_opcode; status = walk_state->ascending_callback(walk_state); status = acpi_ps_next_parse_state(walk_state, op, status); status2 = acpi_ps_complete_this_op(walk_state, op); if (ACPI_FAILURE(status2)) { return_ACPI_STATUS(status2); } op = NULL; status = AE_OK; break; case AE_CTRL_TERMINATE: status = AE_OK; /* Clean up */ do { if (op) { status2 = acpi_ps_complete_this_op(walk_state, op); if (ACPI_FAILURE(status2)) { return_ACPI_STATUS(status2); } } acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); } while (op); return_ACPI_STATUS(status); default: /* All other non-AE_OK status */ do { if (op) { status2 = acpi_ps_complete_this_op(walk_state, op); if (ACPI_FAILURE(status2)) { return_ACPI_STATUS(status2); } } acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); } while (op); /* * TBD: Cleanup parse ops on error */#if 0 if (op == NULL) { acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); }#endif walk_state->prev_op = op; walk_state->prev_arg_types = walk_state->arg_types; return_ACPI_STATUS(status); } /* This scope complete? */ if (acpi_ps_has_completed_scope(parser_state)) { acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op)); } else { op = NULL; } } /* while parser_state->Aml */ /* * Complete the last Op (if not completed), and clear the scope stack. * It is easily possible to end an AML "package" with an unbounded number * of open scopes (such as when several ASL blocks are closed with * sequential closing braces). We want to terminate each one cleanly. */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n", op)); do { if (op) { if (walk_state->ascending_callback != NULL) { walk_state->op = op; walk_state->op_info = acpi_ps_get_opcode_info(op->common. aml_opcode); walk_state->opcode = op->common.aml_opcode; status = walk_state->ascending_callback(walk_state); status = acpi_ps_next_parse_state(walk_state, op, status); if (status == AE_CTRL_PENDING) { status = AE_OK; goto close_this_op; } if (status == AE_CTRL_TERMINATE) { status = AE_OK; /* Clean up */ do { if (op) { status2 = acpi_ps_complete_this_op (walk_state, op); if (ACPI_FAILURE (status2)) { return_ACPI_STATUS (status2); } } acpi_ps_pop_scope(parser_state, &op, &walk_state-> arg_types, &walk_state-> arg_count); } while (op); return_ACPI_STATUS(status); } else if (ACPI_FAILURE(status)) { /* First error is most important */ (void) acpi_ps_complete_this_op(walk_state, op); return_ACPI_STATUS(status); } } status2 = acpi_ps_complete_this_op(walk_state, op); if (ACPI_FAILURE(status2)) { return_ACPI_STATUS(status2); } } acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); } while (op); return_ACPI_STATUS(status);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -