mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
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:
parent
ef3efb439a
commit
6218ab30da
@ -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
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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, ¶m_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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user