diff options
author | Bob Moore <robert.moore@intel.com> | 2016-09-07 02:05:41 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-09-09 20:36:20 -0400 |
commit | 60361b75848c8614233e3374ef5a0056527f0385 (patch) | |
tree | 27a6b845daa6021fdf389ea6fe9370ff17c0cb10 | |
parent | 6bd483c0367f1e1c9d4e970d6ccdadf53d571916 (diff) |
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: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/acpica/acdebug.h | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/dbexec.c | 62 | ||||
-rw-r--r-- | drivers/acpi/acpica/dbinput.c | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/dbmethod.c | 132 |
4 files changed, 169 insertions, 29 deletions
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index f6404ea928cb..94737f8845ac 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -155,7 +155,7 @@ acpi_status acpi_db_disassemble_method(char *name); | |||
155 | 155 | ||
156 | void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op); | 156 | void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op); |
157 | 157 | ||
158 | void acpi_db_batch_execute(char *count_arg); | 158 | void acpi_db_evaluate_predefined_names(void); |
159 | 159 | ||
160 | /* | 160 | /* |
161 | * dbnames - namespace commands | 161 | * dbnames - namespace commands |
diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c index 12df2915ad74..fe3da7c31bb7 100644 --- a/drivers/acpi/acpica/dbexec.c +++ b/drivers/acpi/acpica/dbexec.c | |||
@@ -392,42 +392,48 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags) | |||
392 | acpi_db_execution_walk, NULL, NULL, | 392 | acpi_db_execution_walk, NULL, NULL, |
393 | NULL); | 393 | NULL); |
394 | return; | 394 | return; |
395 | } else { | 395 | } |
396 | name_string = ACPI_ALLOCATE(strlen(name) + 1); | ||
397 | if (!name_string) { | ||
398 | return; | ||
399 | } | ||
400 | 396 | ||
401 | memset(&acpi_gbl_db_method_info, 0, | 397 | name_string = ACPI_ALLOCATE(strlen(name) + 1); |
402 | sizeof(struct acpi_db_method_info)); | 398 | if (!name_string) { |
399 | return; | ||
400 | } | ||
403 | 401 | ||
404 | strcpy(name_string, name); | 402 | memset(&acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info)); |
405 | acpi_ut_strupr(name_string); | 403 | strcpy(name_string, name); |
406 | acpi_gbl_db_method_info.name = name_string; | 404 | acpi_ut_strupr(name_string); |
407 | acpi_gbl_db_method_info.args = args; | ||
408 | acpi_gbl_db_method_info.types = types; | ||
409 | acpi_gbl_db_method_info.flags = flags; | ||
410 | 405 | ||
411 | return_obj.pointer = NULL; | 406 | /* Subcommand to Execute all predefined names in the namespace */ |
412 | return_obj.length = ACPI_ALLOCATE_BUFFER; | ||
413 | 407 | ||
414 | status = acpi_db_execute_setup(&acpi_gbl_db_method_info); | 408 | if (!strncmp(name_string, "PREDEF", 6)) { |
415 | if (ACPI_FAILURE(status)) { | 409 | acpi_db_evaluate_predefined_names(); |
416 | ACPI_FREE(name_string); | 410 | ACPI_FREE(name_string); |
417 | return; | 411 | return; |
418 | } | 412 | } |
419 | 413 | ||
420 | /* Get the NS node, determines existence also */ | 414 | acpi_gbl_db_method_info.name = name_string; |
415 | acpi_gbl_db_method_info.args = args; | ||
416 | acpi_gbl_db_method_info.types = types; | ||
417 | acpi_gbl_db_method_info.flags = flags; | ||
421 | 418 | ||
422 | status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname, | 419 | return_obj.pointer = NULL; |
423 | &acpi_gbl_db_method_info.method); | 420 | return_obj.length = ACPI_ALLOCATE_BUFFER; |
424 | if (ACPI_SUCCESS(status)) { | 421 | |
425 | status = | 422 | status = acpi_db_execute_setup(&acpi_gbl_db_method_info); |
426 | acpi_db_execute_method(&acpi_gbl_db_method_info, | 423 | if (ACPI_FAILURE(status)) { |
427 | &return_obj); | ||
428 | } | ||
429 | ACPI_FREE(name_string); | 424 | ACPI_FREE(name_string); |
425 | return; | ||
426 | } | ||
427 | |||
428 | /* Get the NS node, determines existence also */ | ||
429 | |||
430 | status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname, | ||
431 | &acpi_gbl_db_method_info.method); | ||
432 | if (ACPI_SUCCESS(status)) { | ||
433 | status = acpi_db_execute_method(&acpi_gbl_db_method_info, | ||
434 | &return_obj); | ||
430 | } | 435 | } |
436 | ACPI_FREE(name_string); | ||
431 | 437 | ||
432 | /* | 438 | /* |
433 | * Allow any handlers in separate threads to complete. | 439 | * Allow any handlers in separate threads to complete. |
diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c index 7cd5d2e022da..068214f9cc9d 100644 --- a/drivers/acpi/acpica/dbinput.c +++ b/drivers/acpi/acpica/dbinput.c | |||
@@ -286,6 +286,8 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = { | |||
286 | {1, " \"Ascii String\"", "String method argument\n"}, | 286 | {1, " \"Ascii String\"", "String method argument\n"}, |
287 | {1, " (Hex Byte List)", "Buffer method argument\n"}, | 287 | {1, " (Hex Byte List)", "Buffer method argument\n"}, |
288 | {1, " [Package Element List]", "Package method argument\n"}, | 288 | {1, " [Package Element List]", "Package method argument\n"}, |
289 | {5, " Execute predefined", | ||
290 | "Execute all predefined (public) methods\n"}, | ||
289 | {1, " Go", "Allow method to run to completion\n"}, | 291 | {1, " Go", "Allow method to run to completion\n"}, |
290 | {1, " Information", "Display info about the current method\n"}, | 292 | {1, " Information", "Display info about the current method\n"}, |
291 | {1, " Into", "Step into (not over) a method call\n"}, | 293 | {1, " Into", "Step into (not over) a method call\n"}, |
diff --git a/drivers/acpi/acpica/dbmethod.c b/drivers/acpi/acpica/dbmethod.c index f17a86f6b16b..314b94cf086a 100644 --- a/drivers/acpi/acpica/dbmethod.c +++ b/drivers/acpi/acpica/dbmethod.c | |||
@@ -52,6 +52,11 @@ | |||
52 | #define _COMPONENT ACPI_CA_DEBUGGER | 52 | #define _COMPONENT ACPI_CA_DEBUGGER |
53 | ACPI_MODULE_NAME("dbmethod") | 53 | ACPI_MODULE_NAME("dbmethod") |
54 | 54 | ||
55 | /* Local prototypes */ | ||
56 | static acpi_status | ||
57 | acpi_db_walk_for_execute(acpi_handle obj_handle, | ||
58 | u32 nesting_level, void *context, void **return_value); | ||
59 | |||
55 | /******************************************************************************* | 60 | /******************************************************************************* |
56 | * | 61 | * |
57 | * FUNCTION: acpi_db_set_method_breakpoint | 62 | * FUNCTION: acpi_db_set_method_breakpoint |
@@ -66,6 +71,7 @@ ACPI_MODULE_NAME("dbmethod") | |||
66 | * AML offset | 71 | * AML offset |
67 | * | 72 | * |
68 | ******************************************************************************/ | 73 | ******************************************************************************/ |
74 | |||
69 | void | 75 | void |
70 | acpi_db_set_method_breakpoint(char *location, | 76 | acpi_db_set_method_breakpoint(char *location, |
71 | struct acpi_walk_state *walk_state, | 77 | struct acpi_walk_state *walk_state, |
@@ -367,3 +373,129 @@ acpi_status acpi_db_disassemble_method(char *name) | |||
367 | acpi_ut_release_owner_id(&obj_desc->method.owner_id); | 373 | acpi_ut_release_owner_id(&obj_desc->method.owner_id); |
368 | return (AE_OK); | 374 | return (AE_OK); |
369 | } | 375 | } |
376 | |||
377 | /******************************************************************************* | ||
378 | * | ||
379 | * FUNCTION: acpi_db_walk_for_execute | ||
380 | * | ||
381 | * PARAMETERS: Callback from walk_namespace | ||
382 | * | ||
383 | * RETURN: Status | ||
384 | * | ||
385 | * DESCRIPTION: Batch execution module. Currently only executes predefined | ||
386 | * ACPI names. | ||
387 | * | ||
388 | ******************************************************************************/ | ||
389 | |||
390 | static acpi_status | ||
391 | acpi_db_walk_for_execute(acpi_handle obj_handle, | ||
392 | u32 nesting_level, void *context, void **return_value) | ||
393 | { | ||
394 | struct acpi_namespace_node *node = | ||
395 | (struct acpi_namespace_node *)obj_handle; | ||
396 | struct acpi_db_execute_walk *info = | ||
397 | (struct acpi_db_execute_walk *)context; | ||
398 | struct acpi_buffer return_obj; | ||
399 | acpi_status status; | ||
400 | char *pathname; | ||
401 | u32 i; | ||
402 | struct acpi_device_info *obj_info; | ||
403 | struct acpi_object_list param_objects; | ||
404 | union acpi_object params[ACPI_METHOD_NUM_ARGS]; | ||
405 | const union acpi_predefined_info *predefined; | ||
406 | |||
407 | predefined = acpi_ut_match_predefined_method(node->name.ascii); | ||
408 | if (!predefined) { | ||
409 | return (AE_OK); | ||
410 | } | ||
411 | |||
412 | if (node->type == ACPI_TYPE_LOCAL_SCOPE) { | ||
413 | return (AE_OK); | ||
414 | } | ||
415 | |||
416 | pathname = acpi_ns_get_external_pathname(node); | ||
417 | if (!pathname) { | ||
418 | return (AE_OK); | ||
419 | } | ||
420 | |||
421 | /* Get the object info for number of method parameters */ | ||
422 | |||
423 | status = acpi_get_object_info(obj_handle, &obj_info); | ||
424 | if (ACPI_FAILURE(status)) { | ||
425 | return (status); | ||
426 | } | ||
427 | |||
428 | param_objects.pointer = NULL; | ||
429 | param_objects.count = 0; | ||
430 | |||
431 | if (obj_info->type == ACPI_TYPE_METHOD) { | ||
432 | |||
433 | /* Setup default parameters */ | ||
434 | |||
435 | for (i = 0; i < obj_info->param_count; i++) { | ||
436 | params[i].type = ACPI_TYPE_INTEGER; | ||
437 | params[i].integer.value = 1; | ||
438 | } | ||
439 | |||
440 | param_objects.pointer = params; | ||
441 | param_objects.count = obj_info->param_count; | ||
442 | } | ||
443 | |||
444 | ACPI_FREE(obj_info); | ||
445 | return_obj.pointer = NULL; | ||
446 | return_obj.length = ACPI_ALLOCATE_BUFFER; | ||
447 | |||
448 | /* Do the actual method execution */ | ||
449 | |||
450 | acpi_gbl_method_executing = TRUE; | ||
451 | |||
452 | status = acpi_evaluate_object(node, NULL, ¶m_objects, &return_obj); | ||
453 | |||
454 | acpi_os_printf("%-32s returned %s\n", pathname, | ||
455 | acpi_format_exception(status)); | ||
456 | acpi_gbl_method_executing = FALSE; | ||
457 | ACPI_FREE(pathname); | ||
458 | |||
459 | /* Ignore status from method execution */ | ||
460 | |||
461 | status = AE_OK; | ||
462 | |||
463 | /* Update count, check if we have executed enough methods */ | ||
464 | |||
465 | info->count++; | ||
466 | if (info->count >= info->max_count) { | ||
467 | status = AE_CTRL_TERMINATE; | ||
468 | } | ||
469 | |||
470 | return (status); | ||
471 | } | ||
472 | |||
473 | /******************************************************************************* | ||
474 | * | ||
475 | * FUNCTION: acpi_db_evaluate_predefined_names | ||
476 | * | ||
477 | * PARAMETERS: None | ||
478 | * | ||
479 | * RETURN: None | ||
480 | * | ||
481 | * DESCRIPTION: Namespace batch execution. Execute predefined names in the | ||
482 | * namespace, up to the max count, if specified. | ||
483 | * | ||
484 | ******************************************************************************/ | ||
485 | |||
486 | void acpi_db_evaluate_predefined_names(void) | ||
487 | { | ||
488 | struct acpi_db_execute_walk info; | ||
489 | |||
490 | info.count = 0; | ||
491 | info.max_count = ACPI_UINT32_MAX; | ||
492 | |||
493 | /* Search all nodes in namespace */ | ||
494 | |||
495 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
496 | ACPI_UINT32_MAX, acpi_db_walk_for_execute, | ||
497 | NULL, (void *)&info, NULL); | ||
498 | |||
499 | acpi_os_printf("Evaluated %u predefined names in the namespace\n", | ||
500 | info.count); | ||
501 | } | ||