ACPICA: Debugger: Add a new command: "ALL <NameSeg>"
authorBob Moore <robert.moore@intel.com>
Thu, 8 Oct 2020 02:54:01 +0000 (19:54 -0700)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 8 Oct 2020 16:03:55 +0000 (18:03 +0200)
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>
drivers/acpi/acpica/acdebug.h
drivers/acpi/acpica/dbexec.c
drivers/acpi/acpica/dbinput.c
drivers/acpi/acpica/dbmethod.c

index a676daaa2da5093c313f985f855ed1933f3f14d6..f8a3abdfe25086ba60adb471135dd37444cdc00c 100644 (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
  */
index 4027eaab18a4df819124974892d91c86bba871cf..d3a9521e2dc888d3d497b7de02ad9fa558cef5f5 100644 (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 */
 
index 568d1b0b1f5d7dc54339dfb828d7b5d2190191a1..2952856b8a6755fba25f4f704c07aa9e6f695a0e 100644 (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
index 4e48a7de7413e0b44092ce484b95c5ce73bc01e1..889d13828e492b22ad84a0d8b19bc5c6881eba6e 100644 (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);
+}