ACPICA: Debugger: add "background" command for method execution
authorBob Moore <robert.moore@intel.com>
Fri, 17 Nov 2017 23:42:26 +0000 (15:42 -0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 27 Nov 2017 00:20:32 +0000 (01:20 +0100)
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: Bob Moore <robert.moore@intel.com>
Signed-off-by: Erik Schmauss <erik.schmauss@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/acpica/acdebug.h
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/dbexec.c
drivers/acpi/acpica/dbinput.c

index 71743e5252f5736b6c5cb0f4b438558f4a66816a..54b8d9df9423cd252c19bb31b6f810d9cb1616c1 100644 (file)
@@ -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);
index bed041d41596b9613a6d36c4bf8860493ba5d80d..a56675f0661eb18b13adf49a27b1cfeb68f7b8d5 100644 (file)
@@ -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];
index 3b30319752f046e4a8f20782d6a59596b575ccbd..ed088fceb18d3c98b8bb59d1903186ad991afb30 100644 (file)
@@ -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
index 2626d79db064efa6a93516a7f23e7b16326c6817..954ca3b981a73286ef1953defd11dc9a2ba8d851 100644 (file)
@@ -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],