ACPICA: Debugger: Add a new command: "ALL <NameSeg>"

This command will execute/evaluate all objects with a match to the
<NameSeg> argument.

ACPICA commit a1a32ec054f067d1617067e2bafb0a27a8728e07

Link: https://github.com/acpica/acpica/commit/a1a32ec0
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Erik Kaneda <erik.kaneda@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Bob Moore 2020-10-07 19:54:01 -07:00 committed by Rafael J. Wysocki
parent ef3efb439a
commit 6218ab30da
4 changed files with 188 additions and 34 deletions

View File

@ -37,12 +37,14 @@ struct acpi_db_argument_info {
struct acpi_db_execute_walk {
u32 count;
u32 max_count;
char name_seg[ACPI_NAMESEG_SIZE + 1];
};
#define PARAM_LIST(pl) pl
#define EX_NO_SINGLE_STEP 1
#define EX_SINGLE_STEP 2
#define EX_ALL 4
/*
* dbxface - external debugger interfaces
@ -124,6 +126,8 @@ void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op);
void acpi_db_evaluate_predefined_names(void);
void acpi_db_evaluate_all(char *name_seg);
/*
* dbnames - namespace commands
*/

View File

@ -86,7 +86,8 @@ void acpi_db_delete_objects(u32 count, union acpi_object *objects)
*
* RETURN: Status
*
* DESCRIPTION: Execute a control method.
* DESCRIPTION: Execute a control method. Used to evaluate objects via the
* "EXECUTE" or "EVALUATE" commands.
*
******************************************************************************/
@ -314,11 +315,12 @@ acpi_db_execution_walk(acpi_handle obj_handle,
status = acpi_evaluate_object(node, NULL, NULL, &return_obj);
acpi_gbl_method_executing = FALSE;
acpi_os_printf("Evaluation of [%4.4s] returned %s\n",
acpi_ut_get_node_name(node),
acpi_format_exception(status));
acpi_gbl_method_executing = FALSE;
return (AE_OK);
}
@ -334,7 +336,8 @@ acpi_db_execution_walk(acpi_handle obj_handle,
* RETURN: None
*
* DESCRIPTION: Execute a control method. Name is relative to the current
* scope.
* scope. Function used for the "EXECUTE", "EVALUATE", and
* "ALL" commands
*
******************************************************************************/
@ -372,6 +375,12 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags)
return;
}
if ((flags & EX_ALL) && (strlen(name) > 4)) {
acpi_os_printf("Input name (%s) must be a 4-char NameSeg\n",
name);
return;
}
name_string = ACPI_ALLOCATE(strlen(name) + 1);
if (!name_string) {
return;
@ -389,13 +398,24 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags)
return;
}
acpi_gbl_db_method_info.name = name_string;
acpi_gbl_db_method_info.args = args;
acpi_gbl_db_method_info.types = types;
acpi_gbl_db_method_info.flags = flags;
/* Command (ALL <nameseg>) to execute all methods of a particular name */
return_obj.pointer = NULL;
return_obj.length = ACPI_ALLOCATE_BUFFER;
else if (flags & EX_ALL) {
acpi_gbl_db_method_info.name = name_string;
return_obj.pointer = NULL;
return_obj.length = ACPI_ALLOCATE_BUFFER;
acpi_db_evaluate_all(name_string);
ACPI_FREE(name_string);
return;
} else {
acpi_gbl_db_method_info.name = name_string;
acpi_gbl_db_method_info.args = args;
acpi_gbl_db_method_info.types = types;
acpi_gbl_db_method_info.flags = flags;
return_obj.pointer = NULL;
return_obj.length = ACPI_ALLOCATE_BUFFER;
}
status = acpi_db_execute_setup(&acpi_gbl_db_method_info);
if (ACPI_FAILURE(status)) {
@ -450,6 +470,7 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags)
(u32)return_obj.length);
acpi_db_dump_external_object(return_obj.pointer, 1);
acpi_os_printf("\n");
/* Dump a _PLD buffer if present */

View File

@ -37,6 +37,7 @@ acpi_db_match_command_help(const char *command,
enum acpi_ex_debugger_commands {
CMD_NOT_FOUND = 0,
CMD_NULL,
CMD_ALL,
CMD_ALLOCATIONS,
CMD_ARGS,
CMD_ARGUMENTS,
@ -115,6 +116,7 @@ enum acpi_ex_debugger_commands {
static const struct acpi_db_command_info acpi_gbl_db_commands[] = {
{"<NOT FOUND>", 0},
{"<NULL>", 0},
{"ALL", 1},
{"ALLOCATIONS", 0},
{"ARGS", 0},
{"ARGUMENTS", 0},
@ -222,6 +224,7 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
{1, " Type <Object>", "Display object type\n"},
{0, "\nControl Method Execution:", "\n"},
{1, " All <NameSeg>", "Evaluate all objects named NameSeg\n"},
{1, " Evaluate <Namepath> [Arguments]",
"Evaluate object or control method\n"},
{1, " Execute <Namepath> [Arguments]", "Synonym for Evaluate\n"},
@ -740,6 +743,15 @@ acpi_db_command_dispatch(char *input_buffer,
}
break;
case CMD_ALL:
acpi_os_printf("Executing all objects with NameSeg: %s\n",
acpi_gbl_db_args[1]);
acpi_db_execute(acpi_gbl_db_args[1], &acpi_gbl_db_args[2],
&acpi_gbl_db_arg_types[2],
EX_NO_SINGLE_STEP | EX_ALL);
break;
case CMD_ALLOCATIONS:
#ifdef ACPI_DBG_TRACK_ALLOCATIONS

View File

@ -21,6 +21,8 @@ static acpi_status
acpi_db_walk_for_execute(acpi_handle obj_handle,
u32 nesting_level, void *context, void **return_value);
static acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node);
/*******************************************************************************
*
* FUNCTION: acpi_db_set_method_breakpoint
@ -346,42 +348,26 @@ acpi_status acpi_db_disassemble_method(char *name)
/*******************************************************************************
*
* FUNCTION: acpi_db_walk_for_execute
* FUNCTION: acpi_db_evaluate_object
*
* PARAMETERS: Callback from walk_namespace
* PARAMETERS: node - Namespace node for the object
*
* RETURN: Status
*
* DESCRIPTION: Batch execution module. Currently only executes predefined
* ACPI names.
* DESCRIPTION: Main execution function for the Evaluate/Execute/All debugger
* commands.
*
******************************************************************************/
static acpi_status
acpi_db_walk_for_execute(acpi_handle obj_handle,
u32 nesting_level, void *context, void **return_value)
static acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node)
{
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);
}
struct acpi_buffer return_obj;
acpi_status status;
pathname = acpi_ns_get_external_pathname(node);
if (!pathname) {
@ -390,7 +376,7 @@ acpi_db_walk_for_execute(acpi_handle obj_handle,
/* Get the object info for number of method parameters */
status = acpi_get_object_info(obj_handle, &obj_info);
status = acpi_get_object_info(node, &obj_info);
if (ACPI_FAILURE(status)) {
ACPI_FREE(pathname);
return (status);
@ -421,14 +407,67 @@ acpi_db_walk_for_execute(acpi_handle obj_handle,
acpi_gbl_method_executing = TRUE;
status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
acpi_gbl_method_executing = FALSE;
acpi_os_printf("%-32s returned %s\n", pathname,
acpi_format_exception(status));
acpi_gbl_method_executing = FALSE;
if (return_obj.length) {
acpi_os_printf("Evaluation of %s returned object %p, "
"external buffer length %X\n",
pathname, return_obj.pointer,
(u32)return_obj.length);
acpi_db_dump_external_object(return_obj.pointer, 1);
acpi_os_printf("\n");
}
ACPI_FREE(pathname);
/* Ignore status from method execution */
return (AE_OK);
/* Update count, check if we have executed enough methods */
}
/*******************************************************************************
*
* FUNCTION: acpi_db_walk_for_execute
*
* PARAMETERS: Callback from walk_namespace
*
* RETURN: Status
*
* DESCRIPTION: Batch execution function. Evaluates all "predefined" objects --
* the nameseg begins with an underscore.
*
******************************************************************************/
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;
acpi_status status;
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);
}
acpi_db_evaluate_object(node);
/* Ignore status from object evaluation */
status = AE_OK;
/* Update count, check if we have executed enough methods */
@ -441,6 +480,52 @@ acpi_db_walk_for_execute(acpi_handle obj_handle,
return (status);
}
/*******************************************************************************
*
* FUNCTION: acpi_db_walk_for_execute_all
*
* PARAMETERS: Callback from walk_namespace
*
* RETURN: Status
*
* DESCRIPTION: Batch execution function. Evaluates all objects whose path ends
* with the nameseg "Info->NameSeg". Used for the "ALL" command.
*
******************************************************************************/
static acpi_status
acpi_db_walk_for_execute_all(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;
acpi_status status;
if (!ACPI_COMPARE_NAMESEG(node->name.ascii, info->name_seg)) {
return (AE_OK);
}
if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
return (AE_OK);
}
/* Now evaluate the input object (node) */
acpi_db_evaluate_object(node);
/* Ignore status from method execution */
status = AE_OK;
/* Update count of executed methods/objects */
info->count++;
return (status);
}
/*******************************************************************************
*
* FUNCTION: acpi_db_evaluate_predefined_names
@ -470,3 +555,35 @@ void acpi_db_evaluate_predefined_names(void)
acpi_os_printf("Evaluated %u predefined names in the namespace\n",
info.count);
}
/*******************************************************************************
*
* FUNCTION: acpi_db_evaluate_all
*
* PARAMETERS: none_acpi_gbl_db_method_info
*
* RETURN: None
*
* DESCRIPTION: Namespace batch execution. Implements the "ALL" command.
* Execute all namepaths whose final nameseg matches the
* input nameseg.
*
******************************************************************************/
void acpi_db_evaluate_all(char *name_seg)
{
struct acpi_db_execute_walk info;
info.count = 0;
info.max_count = ACPI_UINT32_MAX;
ACPI_COPY_NAMESEG(info.name_seg, name_seg);
info.name_seg[ACPI_NAMESEG_SIZE] = 0;
/* Search all nodes in namespace */
(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, acpi_db_walk_for_execute_all,
NULL, (void *)&info, NULL);
acpi_os_printf("Evaluated %u names in the namespace\n", info.count);
}