acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op) { acpi_status status = AE_OK; acpi_os_printf("\n"); /* TBD: [Restructure] Need a separate command line buffer for step mode */ while (!acpi_gbl_db_terminate_loop) { /* Force output to console until a command is entered */ acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); /* Different prompt if method is executing */ if (!acpi_gbl_method_executing) { acpi_os_printf("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); } else { acpi_os_printf("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); } /* Get the user input line */ status = acpi_os_get_line(acpi_gbl_db_line_buf, ACPI_DB_LINE_BUFFER_SIZE, NULL); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "While parsing command line")); return (status); } /* Check for single or multithreaded debug */ if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) { /* * Signal the debug thread that we have a command to execute, * and wait for the command to complete. */ acpi_os_release_mutex(acpi_gbl_db_command_ready); if (ACPI_FAILURE(status)) { return (status); } status = acpi_os_acquire_mutex(acpi_gbl_db_command_complete, ACPI_WAIT_FOREVER); if (ACPI_FAILURE(status)) { return (status); } } else { /* Just call to the command line interpreter */ acpi_db_single_thread(); } } return (status); }
static int acpi_aml_wait_command_ready(bool single_step, char *buffer, size_t length) { acpi_status status; if (single_step) acpi_os_printf("\n%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); else acpi_os_printf("\n%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); status = acpi_os_get_line(buffer, length, NULL); if (ACPI_FAILURE(status)) return -EINVAL; return 0; }
acpi_status acpi_db_single_step ( acpi_walk_state *walk_state, acpi_parse_object *op, u32 opcode_class) { acpi_parse_object *next; acpi_status status = AE_OK; u32 original_debug_level; acpi_parse_object *display_op; FUNCTION_ENTRY (); /* Is there a breakpoint set? */ if (walk_state->method_breakpoint) { /* Check if the breakpoint has been reached or passed */ if (walk_state->method_breakpoint <= op->aml_offset) { /* Hit the breakpoint, resume single step, reset breakpoint */ acpi_os_printf ("***Break*** at AML offset %X\n", op->aml_offset); acpi_gbl_cm_single_step = TRUE; acpi_gbl_step_to_next_call = FALSE; walk_state->method_breakpoint = 0; } } /* * Check if this is an opcode that we are interested in -- * namely, opcodes that have arguments */ if (op->opcode == AML_INT_NAMEDFIELD_OP) { return (AE_OK); } switch (opcode_class) { case AML_CLASS_UNKNOWN: case AML_CLASS_ARGUMENT: /* constants, literals, etc. do nothing */ return (AE_OK); break; } /* * Under certain debug conditions, display this opcode and its operands */ if ((acpi_gbl_db_output_to_file) || (acpi_gbl_cm_single_step) || (acpi_dbg_level & ACPI_LV_PARSE)) { if ((acpi_gbl_db_output_to_file) || (acpi_dbg_level & ACPI_LV_PARSE)) { acpi_os_printf ("\n[Aml_debug] Next AML Opcode to execute:\n"); } /* * Display this op (and only this op - zero out the NEXT field temporarily, * and disable parser trace output for the duration of the display because * we don't want the extraneous debug output) */ original_debug_level = acpi_dbg_level; acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS); next = op->next; op->next = NULL; display_op = op; if (op->parent) { if ((op->parent->opcode == AML_IF_OP) || (op->parent->opcode == AML_WHILE_OP)) { display_op = op->parent; } } /* Now we can display it */ acpi_db_display_op (walk_state, display_op, ACPI_UINT32_MAX); if ((op->opcode == AML_IF_OP) || (op->opcode == AML_WHILE_OP)) { if (walk_state->control_state->common.value) { acpi_os_printf ("Predicate was TRUE, executed block\n"); } else { acpi_os_printf ("Predicate is FALSE, skipping block\n"); } } else if (op->opcode == AML_ELSE_OP) { /* TBD */ } /* Restore everything */ op->next = next; acpi_os_printf ("\n"); acpi_dbg_level = original_debug_level; } /* If we are not single stepping, just continue executing the method */ if (!acpi_gbl_cm_single_step) { return (AE_OK); } /* * If we are executing a step-to-call command, * Check if this is a method call. */ if (acpi_gbl_step_to_next_call) { if (op->opcode != AML_INT_METHODCALL_OP) { /* Not a method call, just keep executing */ return (AE_OK); } /* Found a method call, stop executing */ acpi_gbl_step_to_next_call = FALSE; } /* * If the next opcode is a method call, we will "step over" it * by default. */ if (op->opcode == AML_INT_METHODCALL_OP) { acpi_gbl_cm_single_step = FALSE; /* No more single step while executing called method */ /* Set the breakpoint on the call, it will stop execution as soon as we return */ /* TBD: [Future] don't kill the user breakpoint! */ walk_state->method_breakpoint = /* Op->Aml_offset + */ 1; /* Must be non-zero! */ } /* TBD: [Investigate] what are the namespace locking issues here */ /* Acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */ /* Go into the command loop and await next user command */ acpi_gbl_method_executing = TRUE; status = AE_CTRL_TRUE; while (status == AE_CTRL_TRUE) { if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) { /* Handshake with the front-end that gets user command lines */ acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE); acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY); } else { /* Single threaded, we must get a command line ourselves */ /* Force output to console until a command is entered */ acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); /* Different prompt if method is executing */ if (!acpi_gbl_method_executing) { acpi_os_printf ("%1c ", DB_COMMAND_PROMPT); } else { acpi_os_printf ("%1c ", DB_EXECUTE_PROMPT); } /* Get the user input line */ acpi_os_get_line (acpi_gbl_db_line_buf); } status = acpi_db_command_dispatch (acpi_gbl_db_line_buf, walk_state, op); } /* Acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */ /* User commands complete, continue execution of the interrupted method */ return (status); }
static acpi_status acpi_db_start_command(struct acpi_walk_state *walk_state, union acpi_parse_object *op) { acpi_status status; /* TBD: [Investigate] are there namespace locking issues here? */ /* acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */ /* Go into the command loop and await next user command */ acpi_gbl_method_executing = TRUE; status = AE_CTRL_TRUE; while (status == AE_CTRL_TRUE) { if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) { /* Handshake with the front-end that gets user command lines */ acpi_os_release_mutex(acpi_gbl_db_command_complete); status = acpi_os_acquire_mutex(acpi_gbl_db_command_ready, ACPI_WAIT_FOREVER); if (ACPI_FAILURE(status)) { return (status); } } else { /* Single threaded, we must get a command line ourselves */ /* Force output to console until a command is entered */ acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); /* Different prompt if method is executing */ if (!acpi_gbl_method_executing) { acpi_os_printf("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); } else { acpi_os_printf("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); } /* Get the user input line */ status = acpi_os_get_line(acpi_gbl_db_line_buf, ACPI_DB_LINE_BUFFER_SIZE, NULL); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "While parsing command line")); return (status); } } status = acpi_db_command_dispatch(acpi_gbl_db_line_buf, walk_state, op); } /* acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */ return (status); }