Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60361b75 authored by Bob Moore's avatar Bob Moore Committed by Rafael J. Wysocki
Browse files

ACPICA: Debugger: Add subcommand for predefined name execution

ACPICA commit be5808f0e642ff9963d86f362521b4af2340e2f5

"Execute Predefined" will execute all predefined (public) names
within the namespace.

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


Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 6bd483c0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -155,7 +155,7 @@ acpi_status acpi_db_disassemble_method(char *name);

void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op);

void acpi_db_batch_execute(char *count_arg);
void acpi_db_evaluate_predefined_names(void);

/*
 * dbnames - namespace commands
+34 −28
Original line number Diff line number Diff line
@@ -392,17 +392,25 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags)
					  acpi_db_execution_walk, NULL, NULL,
					  NULL);
		return;
	} else {
	}

	name_string = ACPI_ALLOCATE(strlen(name) + 1);
	if (!name_string) {
		return;
	}

		memset(&acpi_gbl_db_method_info, 0,
		       sizeof(struct acpi_db_method_info));

	memset(&acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info));
	strcpy(name_string, name);
	acpi_ut_strupr(name_string);

	/* Subcommand to Execute all predefined names in the namespace */

	if (!strncmp(name_string, "PREDEF", 6)) {
		acpi_db_evaluate_predefined_names();
		ACPI_FREE(name_string);
		return;
	}

	acpi_gbl_db_method_info.name = name_string;
	acpi_gbl_db_method_info.args = args;
	acpi_gbl_db_method_info.types = types;
@@ -422,12 +430,10 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags)
	status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname,
				 &acpi_gbl_db_method_info.method);
	if (ACPI_SUCCESS(status)) {
			status =
			    acpi_db_execute_method(&acpi_gbl_db_method_info,
		status = acpi_db_execute_method(&acpi_gbl_db_method_info,
						&return_obj);
	}
	ACPI_FREE(name_string);
	}

	/*
	 * Allow any handlers in separate threads to complete.
+2 −0
Original line number Diff line number Diff line
@@ -286,6 +286,8 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
	{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"},
+132 −0
Original line number Diff line number Diff line
@@ -52,6 +52,11 @@
#define _COMPONENT          ACPI_CA_DEBUGGER
ACPI_MODULE_NAME("dbmethod")

/* Local prototypes */
static acpi_status
acpi_db_walk_for_execute(acpi_handle obj_handle,
			 u32 nesting_level, void *context, void **return_value);

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_set_method_breakpoint
@@ -66,6 +71,7 @@ ACPI_MODULE_NAME("dbmethod")
 *              AML offset
 *
 ******************************************************************************/

void
acpi_db_set_method_breakpoint(char *location,
			      struct acpi_walk_state *walk_state,
@@ -367,3 +373,129 @@ acpi_status acpi_db_disassemble_method(char *name)
	acpi_ut_release_owner_id(&obj_desc->method.owner_id);
	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_walk_for_execute
 *
 * PARAMETERS:  Callback from walk_namespace
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Batch execution module. Currently only executes predefined
 *              ACPI names.
 *
 ******************************************************************************/

static acpi_status
acpi_db_walk_for_execute(acpi_handle obj_handle,
			 u32 nesting_level, void *context, void **return_value)
{
	struct acpi_namespace_node *node =
	    (struct acpi_namespace_node *)obj_handle;
	struct acpi_db_execute_walk *info =
	    (struct acpi_db_execute_walk *)context;
	struct acpi_buffer return_obj;
	acpi_status status;
	char *pathname;
	u32 i;
	struct acpi_device_info *obj_info;
	struct acpi_object_list param_objects;
	union acpi_object params[ACPI_METHOD_NUM_ARGS];
	const union acpi_predefined_info *predefined;

	predefined = acpi_ut_match_predefined_method(node->name.ascii);
	if (!predefined) {
		return (AE_OK);
	}

	if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
		return (AE_OK);
	}

	pathname = acpi_ns_get_external_pathname(node);
	if (!pathname) {
		return (AE_OK);
	}

	/* Get the object info for number of method parameters */

	status = acpi_get_object_info(obj_handle, &obj_info);
	if (ACPI_FAILURE(status)) {
		return (status);
	}

	param_objects.pointer = NULL;
	param_objects.count = 0;

	if (obj_info->type == ACPI_TYPE_METHOD) {

		/* Setup default parameters */

		for (i = 0; i < obj_info->param_count; i++) {
			params[i].type = ACPI_TYPE_INTEGER;
			params[i].integer.value = 1;
		}

		param_objects.pointer = params;
		param_objects.count = obj_info->param_count;
	}

	ACPI_FREE(obj_info);
	return_obj.pointer = NULL;
	return_obj.length = ACPI_ALLOCATE_BUFFER;

	/* Do the actual method execution */

	acpi_gbl_method_executing = TRUE;

	status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);

	acpi_os_printf("%-32s returned %s\n", pathname,
		       acpi_format_exception(status));
	acpi_gbl_method_executing = FALSE;
	ACPI_FREE(pathname);

	/* Ignore status from method execution */

	status = AE_OK;

	/* Update count, check if we have executed enough methods */

	info->count++;
	if (info->count >= info->max_count) {
		status = AE_CTRL_TERMINATE;
	}

	return (status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_evaluate_predefined_names
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Namespace batch execution. Execute predefined names in the
 *              namespace, up to the max count, if specified.
 *
 ******************************************************************************/

void acpi_db_evaluate_predefined_names(void)
{
	struct acpi_db_execute_walk info;

	info.count = 0;
	info.max_count = ACPI_UINT32_MAX;

	/* Search all nodes in namespace */

	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
				  ACPI_UINT32_MAX, acpi_db_walk_for_execute,
				  NULL, (void *)&info, NULL);

	acpi_os_printf("Evaluated %u predefined names in the namespace\n",
		       info.count);
}