Commit 060c859d authored by Bob Moore's avatar Bob Moore Committed by Rafael J. Wysocki
Browse files

ACPICA: Debugger: add "background" command for method execution

ACPICA commit d7b44738a48caa9f669b8dbf0024d456711aec31

Allows a single task to execute in the background, while control
returns to the debugger prompt.

Also, cleanup the debugger help screen.

Link: https://github.com/acpica/acpica/commit/d7b44738


Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarErik Schmauss <erik.schmauss@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent d41bf52e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -222,6 +222,10 @@ ACPI_DBR_DEPENDENT_RETURN_VOID(void
void
acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags);

void
acpi_db_create_execution_thread(char *method_name_arg,
				char **arguments, acpi_object_type *types);

void
acpi_db_create_execution_threads(char *num_threads_arg,
				 char *num_loops_arg, char *method_name_arg);
+7 −6
Original line number Diff line number Diff line
@@ -1218,16 +1218,17 @@ struct acpi_db_method_info {
	acpi_object_type *types;

	/*
	 * Arguments to be passed to method for the command
	 * Threads -
	 *   the Number of threads, ID of current thread and
	 *   Index of current thread inside all them created.
	 * Arguments to be passed to method for the commands Threads and
	 * Background. Note, ACPI specifies a maximum of 7 arguments (0 - 6).
	 *
	 * For the Threads command, the Number of threads, ID of current
	 * thread and Index of current thread inside all them created.
	 */
	char init_args;
#ifdef ACPI_DEBUGGER
	acpi_object_type arg_types[4];
	acpi_object_type arg_types[ACPI_METHOD_NUM_ARGS];
#endif
	char *arguments[4];
	char *arguments[ACPI_METHOD_NUM_ARGS];
	char num_threads_str[11];
	char id_of_thread_str[11];
	char index_of_thread_str[11];
+109 −1
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ static acpi_status
acpi_db_execution_walk(acpi_handle obj_handle,
		       u32 nesting_level, void *context, void **return_value);

static void ACPI_SYSTEM_XFACE acpi_db_single_execution_thread(void *context);

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_delete_objects
@@ -229,7 +231,7 @@ static acpi_status acpi_db_execute_setup(struct acpi_db_method_info *info)

	ACPI_FUNCTION_NAME(db_execute_setup);

	/* Catenate the current scope to the supplied name */
	/* Concatenate the current scope to the supplied name */

	info->pathname[0] = 0;
	if ((info->name[0] != '\\') && (info->name[0] != '/')) {
@@ -609,6 +611,112 @@ static void ACPI_SYSTEM_XFACE acpi_db_method_thread(void *context)
	}
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_single_execution_thread
 *
 * PARAMETERS:  context                 - Method info struct
 *
 * RETURN:      None
 *
 * DESCRIPTION: Create one thread and execute a method
 *
 ******************************************************************************/

static void ACPI_SYSTEM_XFACE acpi_db_single_execution_thread(void *context)
{
	struct acpi_db_method_info *info = context;
	acpi_status status;
	struct acpi_buffer return_obj;

	acpi_os_printf("\n");

	status = acpi_db_execute_method(info, &return_obj);
	if (ACPI_FAILURE(status)) {
		acpi_os_printf("%s During evaluation of %s\n",
			       acpi_format_exception(status), info->pathname);
		return;
	}

	/* Display a return object, if any */

	if (return_obj.length) {
		acpi_os_printf("Evaluation of %s returned object %p, "
			       "external buffer length %X\n",
			       acpi_gbl_db_method_info.pathname,
			       return_obj.pointer, (u32)return_obj.length);

		acpi_db_dump_external_object(return_obj.pointer, 1);
	}

	acpi_os_printf("\nBackground thread completed\n%c ",
		       ACPI_DEBUGGER_COMMAND_PROMPT);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_create_execution_thread
 *
 * PARAMETERS:  method_name_arg         - Control method to execute
 *              arguments               - Array of arguments to the method
 *              types                   - Corresponding array of object types
 *
 * RETURN:      None
 *
 * DESCRIPTION: Create a single thread to evaluate a namespace object. Handles
 *              arguments passed on command line for control methods.
 *
 ******************************************************************************/

void
acpi_db_create_execution_thread(char *method_name_arg,
				char **arguments, acpi_object_type *types)
{
	acpi_status status;
	u32 i;

	memset(&acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info));
	acpi_gbl_db_method_info.name = method_name_arg;
	acpi_gbl_db_method_info.init_args = 1;
	acpi_gbl_db_method_info.args = acpi_gbl_db_method_info.arguments;
	acpi_gbl_db_method_info.types = acpi_gbl_db_method_info.arg_types;

	/* Setup method arguments, up to 7 (0-6) */

	for (i = 0; (i < ACPI_METHOD_NUM_ARGS) && *arguments; i++) {
		acpi_gbl_db_method_info.arguments[i] = *arguments;
		arguments++;

		acpi_gbl_db_method_info.arg_types[i] = *types;
		types++;
	}

	status = acpi_db_execute_setup(&acpi_gbl_db_method_info);
	if (ACPI_FAILURE(status)) {
		return;
	}

	/* Get the NS node, determines existence also */

	status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname,
				 &acpi_gbl_db_method_info.method);
	if (ACPI_FAILURE(status)) {
		acpi_os_printf("%s Could not get handle for %s\n",
			       acpi_format_exception(status),
			       acpi_gbl_db_method_info.pathname);
		return;
	}

	status = acpi_os_execute(OSL_DEBUGGER_EXEC_THREAD,
				 acpi_db_single_execution_thread,
				 &acpi_gbl_db_method_info);
	if (ACPI_FAILURE(status)) {
		return;
	}

	acpi_os_printf("\nBackground thread started\n");
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_create_execution_threads
+86 −59
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ enum acpi_ex_debugger_commands {
	CMD_UNLOAD,

	CMD_TERMINATE,
	CMD_BACKGROUND,
	CMD_THREADS,

	CMD_TEST,
@@ -212,6 +213,7 @@ static const struct acpi_db_command_info acpi_gbl_db_commands[] = {
	{"UNLOAD", 1},

	{"TERMINATE", 0},
	{"BACKGROUND", 1},
	{"THREADS", 3},

	{"TEST", 1},
@@ -222,9 +224,56 @@ static const struct acpi_db_command_info acpi_gbl_db_commands[] = {
/*
 * Help for all debugger commands. First argument is the number of lines
 * of help to output for the command.
 *
 * Note: Some commands are not supported by the kernel-level version of
 * the debugger.
 */
static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
	{0, "\nGeneral-Purpose Commands:", "\n"},
	{0, "\nNamespace Access:", "\n"},
	{1, "  Businfo", "Display system bus info\n"},
	{1, "  Disassemble <Method>", "Disassemble a control method\n"},
	{1, "  Find <AcpiName> (? is wildcard)",
	 "Find ACPI name(s) with wildcards\n"},
	{1, "  Integrity", "Validate namespace integrity\n"},
	{1, "  Methods", "Display list of loaded control methods\n"},
	{1, "  Namespace [Object] [Depth]",
	 "Display loaded namespace tree/subtree\n"},
	{1, "  Notify <Object> <Value>", "Send a notification on Object\n"},
	{1, "  Objects [ObjectType]",
	 "Display summary of all objects or just given type\n"},
	{1, "  Owner <OwnerId> [Depth]",
	 "Display loaded namespace by object owner\n"},
	{1, "  Paths", "Display full pathnames of namespace objects\n"},
	{1, "  Predefined", "Check all predefined names\n"},
	{1, "  Prefix [<Namepath>]", "Set or Get current execution prefix\n"},
	{1, "  References <Addr>", "Find all references to object at addr\n"},
	{1, "  Resources [DeviceName]",
	 "Display Device resources (no arg = all devices)\n"},
	{1, "  Set N <NamedObject> <Value>", "Set value for named integer\n"},
	{1, "  Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"},
	{1, "  Type <Object>", "Display object type\n"},

	{0, "\nControl Method Execution:", "\n"},
	{1, "  Evaluate <Namepath> [Arguments]",
	 "Evaluate object or control method\n"},
	{1, "  Execute <Namepath> [Arguments]", "Synonym for Evaluate\n"},
#ifdef ACPI_APPLICATION
	{1, "  Background <Namepath> [Arguments]",
	 "Evaluate object/method in a separate thread\n"},
	{1, "  Thread <Threads><Loops><NamePath>",
	 "Spawn threads to execute method(s)\n"},
#endif
	{1, "  Debug <Namepath> [Arguments]", "Single-Step a control method\n"},
	{7, "  [Arguments] formats:", "Control method argument formats\n"},
	{1, "     Hex Integer", "Integer\n"},
	{1, "     \"Ascii String\"", "String\n"},
	{1, "     (Hex Byte List)", "Buffer\n"},
	{1, "         (01 42 7A BF)", "Buffer example (4 bytes)\n"},
	{1, "     [Package Element List]", "Package\n"},
	{1, "         [0x01 0x1234 \"string\"]",
	 "Package example (3 elements)\n"},

	{0, "\nMiscellaneous:", "\n"},
	{1, "  Allocations", "Display list of current memory allocations\n"},
	{2, "  Dump <Address>|<Namepath>", "\n"},
	{0, "       [Byte|Word|Dword|Qword]",
@@ -248,46 +297,30 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
	{1, "     Stack", "Display CPU stack usage\n"},
	{1, "     Tables", "Info about current ACPI table(s)\n"},
	{1, "  Tables", "Display info about loaded ACPI tables\n"},
#ifdef ACPI_APPLICATION
	{1, "  Terminate", "Delete namespace and all internal objects\n"},
#endif
	{1, "  ! <CommandNumber>", "Execute command from history buffer\n"},
	{1, "  !!", "Execute last command again\n"},

	{0, "\nNamespace Access Commands:", "\n"},
	{1, "  Businfo", "Display system bus info\n"},
	{1, "  Disassemble <Method>", "Disassemble a control method\n"},
	{1, "  Find <AcpiName> (? is wildcard)",
	 "Find ACPI name(s) with wildcards\n"},
	{1, "  Integrity", "Validate namespace integrity\n"},
	{1, "  Methods", "Display list of loaded control methods\n"},
	{1, "  Namespace [Object] [Depth]",
	 "Display loaded namespace tree/subtree\n"},
	{1, "  Notify <Object> <Value>", "Send a notification on Object\n"},
	{1, "  Objects [ObjectType]",
	 "Display summary of all objects or just given type\n"},
	{1, "  Owner <OwnerId> [Depth]",
	 "Display loaded namespace by object owner\n"},
	{1, "  Paths", "Display full pathnames of namespace objects\n"},
	{1, "  Predefined", "Check all predefined names\n"},
	{1, "  Prefix [<Namepath>]", "Set or Get current execution prefix\n"},
	{1, "  References <Addr>", "Find all references to object at addr\n"},
	{1, "  Resources [DeviceName]",
	 "Display Device resources (no arg = all devices)\n"},
	{1, "  Set N <NamedObject> <Value>", "Set value for named integer\n"},
	{1, "  Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"},
	{1, "  Type <Object>", "Display object type\n"},
	{0, "\nMethod and Namespace Debugging:", "\n"},
	{5, "  Trace <State> [<Namepath>] [Once]",
	 "Trace control method execution\n"},
	{1, "     Enable", "Enable all messages\n"},
	{1, "     Disable", "Disable tracing\n"},
	{1, "     Method", "Enable method execution messages\n"},
	{1, "     Opcode", "Enable opcode execution messages\n"},
	{3, "  Test <TestName>", "Invoke a debug test\n"},
	{1, "     Objects", "Read/write/compare all namespace data objects\n"},
	{1, "     Predefined",
	 "Validate all ACPI predefined names (_STA, etc.)\n"},
	{1, "  Execute predefined",
	 "Execute all predefined (public) methods\n"},

	{0, "\nControl Method Execution Commands:", "\n"},
	{0, "\nControl Method Single-Step Execution:", "\n"},
	{1, "  Arguments (or Args)", "Display method arguments\n"},
	{1, "  Breakpoint <AmlOffset>", "Set an AML execution breakpoint\n"},
	{1, "  Call", "Run to next control method invocation\n"},
	{1, "  Debug <Namepath> [Arguments]", "Single Step a control method\n"},
	{6, "  Evaluate", "Synonym for Execute\n"},
	{5, "  Execute <Namepath> [Arguments]", "Execute control method\n"},
	{1, "     Hex Integer", "Integer method argument\n"},
	{1, "     \"Ascii String\"", "String method argument\n"},
	{1, "     (Hex Byte List)", "Buffer method argument\n"},
	{1, "     [Package Element List]", "Package method argument\n"},
	{5, "  Execute predefined",
	 "Execute all predefined (public) methods\n"},
	{1, "  Go", "Allow method to run to completion\n"},
	{1, "  Information", "Display info about the current method\n"},
	{1, "  Into", "Step into (not over) a method call\n"},
@@ -296,41 +329,24 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
	{1, "  Results", "Display method result stack\n"},
	{1, "  Set <A|L> <#> <Value>", "Set method data (Arguments/Locals)\n"},
	{1, "  Stop", "Terminate control method\n"},
	{5, "  Trace <State> [<Namepath>] [Once]",
	 "Trace control method execution\n"},
	{1, "     Enable", "Enable all messages\n"},
	{1, "     Disable", "Disable tracing\n"},
	{1, "     Method", "Enable method execution messages\n"},
	{1, "     Opcode", "Enable opcode execution messages\n"},
	{1, "  Tree", "Display control method calling tree\n"},
	{1, "  <Enter>", "Single step next AML opcode (over calls)\n"},

#ifdef ACPI_APPLICATION
	{0, "\nHardware Simulation Commands:", "\n"},
	{1, "  EnableAcpi", "Enable ACPI (hardware) mode\n"},
	{1, "  Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"},
	{1, "  Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"},
	{1, "  Gpes", "Display info on all GPE devices\n"},
	{1, "  Sci", "Generate an SCI\n"},
	{1, "  Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},

	{0, "\nFile I/O Commands:", "\n"},
	{0, "\nFile Operations:", "\n"},
	{1, "  Close", "Close debug output file\n"},
	{1, "  Load <Input Filename>", "Load ACPI table from a file\n"},
	{1, "  Open <Output Filename>", "Open a file for debug output\n"},
	{1, "  Unload <Namepath>",
	 "Unload an ACPI table via namespace object\n"},

	{0, "\nUser Space Commands:", "\n"},
	{1, "  Terminate", "Delete namespace and all internal objects\n"},
	{1, "  Thread <Threads><Loops><NamePath>",
	 "Spawn threads to execute method(s)\n"},

	{0, "\nDebug Test Commands:", "\n"},
	{3, "  Test <TestName>", "Invoke a debug test\n"},
	{1, "     Objects", "Read/write/compare all namespace data objects\n"},
	{1, "     Predefined",
	 "Execute all ACPI predefined names (_STA, etc.)\n"},
	{0, "\nHardware Simulation:", "\n"},
	{1, "  EnableAcpi", "Enable ACPI (hardware) mode\n"},
	{1, "  Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"},
	{1, "  Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"},
	{1, "  Gpes", "Display info on all GPE devices\n"},
	{1, "  Sci", "Generate an SCI\n"},
	{1, "  Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
#endif
	{0, NULL, NULL}
};
@@ -442,11 +458,15 @@ static void acpi_db_display_help(char *command)

		/* No argument to help, display help for all commands */

		acpi_os_printf("\nSummary of AML Debugger Commands\n\n");

		while (next->invocation) {
			acpi_os_printf("%-38s%s", next->invocation,
				       next->description);
			next++;
		}
		acpi_os_printf("\n");

	} else {
		/* Display help for all commands that match the subtring */

@@ -1087,6 +1107,13 @@ acpi_db_command_dispatch(char *input_buffer,
		/*  acpi_initialize (NULL); */
		break;

	case CMD_BACKGROUND:

		acpi_db_create_execution_thread(acpi_gbl_db_args[1],
						&acpi_gbl_db_args[2],
						&acpi_gbl_db_arg_types[2]);
		break;

	case CMD_THREADS:

		acpi_db_create_execution_threads(acpi_gbl_db_args[1],