162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/******************************************************************************* 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: dbmethod - Debug commands for control methods 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci ******************************************************************************/ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <acpi/acpi.h> 962306a36Sopenharmony_ci#include "accommon.h" 1062306a36Sopenharmony_ci#include "acdispat.h" 1162306a36Sopenharmony_ci#include "acnamesp.h" 1262306a36Sopenharmony_ci#include "acdebug.h" 1362306a36Sopenharmony_ci#include "acparser.h" 1462306a36Sopenharmony_ci#include "acpredef.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define _COMPONENT ACPI_CA_DEBUGGER 1762306a36Sopenharmony_ciACPI_MODULE_NAME("dbmethod") 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* Local prototypes */ 2062306a36Sopenharmony_cistatic acpi_status 2162306a36Sopenharmony_ciacpi_db_walk_for_execute(acpi_handle obj_handle, 2262306a36Sopenharmony_ci u32 nesting_level, void *context, void **return_value); 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/******************************************************************************* 2762306a36Sopenharmony_ci * 2862306a36Sopenharmony_ci * FUNCTION: acpi_db_set_method_breakpoint 2962306a36Sopenharmony_ci * 3062306a36Sopenharmony_ci * PARAMETERS: location - AML offset of breakpoint 3162306a36Sopenharmony_ci * walk_state - Current walk info 3262306a36Sopenharmony_ci * op - Current Op (from parse walk) 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci * RETURN: None 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * DESCRIPTION: Set a breakpoint in a control method at the specified 3762306a36Sopenharmony_ci * AML offset 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci ******************************************************************************/ 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_civoid 4262306a36Sopenharmony_ciacpi_db_set_method_breakpoint(char *location, 4362306a36Sopenharmony_ci struct acpi_walk_state *walk_state, 4462306a36Sopenharmony_ci union acpi_parse_object *op) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci u32 address; 4762306a36Sopenharmony_ci u32 aml_offset; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci if (!op) { 5062306a36Sopenharmony_ci acpi_os_printf("There is no method currently executing\n"); 5162306a36Sopenharmony_ci return; 5262306a36Sopenharmony_ci } 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci /* Get and verify the breakpoint address */ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci address = strtoul(location, NULL, 16); 5762306a36Sopenharmony_ci aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml, 5862306a36Sopenharmony_ci walk_state->parser_state.aml_start); 5962306a36Sopenharmony_ci if (address <= aml_offset) { 6062306a36Sopenharmony_ci acpi_os_printf("Breakpoint %X is beyond current address %X\n", 6162306a36Sopenharmony_ci address, aml_offset); 6262306a36Sopenharmony_ci } 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci /* Save breakpoint in current walk */ 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci walk_state->user_breakpoint = address; 6762306a36Sopenharmony_ci acpi_os_printf("Breakpoint set at AML offset %X\n", address); 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/******************************************************************************* 7162306a36Sopenharmony_ci * 7262306a36Sopenharmony_ci * FUNCTION: acpi_db_set_method_call_breakpoint 7362306a36Sopenharmony_ci * 7462306a36Sopenharmony_ci * PARAMETERS: op - Current Op (from parse walk) 7562306a36Sopenharmony_ci * 7662306a36Sopenharmony_ci * RETURN: None 7762306a36Sopenharmony_ci * 7862306a36Sopenharmony_ci * DESCRIPTION: Set a breakpoint in a control method at the specified 7962306a36Sopenharmony_ci * AML offset 8062306a36Sopenharmony_ci * 8162306a36Sopenharmony_ci ******************************************************************************/ 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_civoid acpi_db_set_method_call_breakpoint(union acpi_parse_object *op) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if (!op) { 8762306a36Sopenharmony_ci acpi_os_printf("There is no method currently executing\n"); 8862306a36Sopenharmony_ci return; 8962306a36Sopenharmony_ci } 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci acpi_gbl_step_to_next_call = TRUE; 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/******************************************************************************* 9562306a36Sopenharmony_ci * 9662306a36Sopenharmony_ci * FUNCTION: acpi_db_set_method_data 9762306a36Sopenharmony_ci * 9862306a36Sopenharmony_ci * PARAMETERS: type_arg - L for local, A for argument 9962306a36Sopenharmony_ci * index_arg - which one 10062306a36Sopenharmony_ci * value_arg - Value to set. 10162306a36Sopenharmony_ci * 10262306a36Sopenharmony_ci * RETURN: None 10362306a36Sopenharmony_ci * 10462306a36Sopenharmony_ci * DESCRIPTION: Set a local or argument for the running control method. 10562306a36Sopenharmony_ci * NOTE: only object supported is Number. 10662306a36Sopenharmony_ci * 10762306a36Sopenharmony_ci ******************************************************************************/ 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_civoid acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci char type; 11262306a36Sopenharmony_ci u32 index; 11362306a36Sopenharmony_ci u32 value; 11462306a36Sopenharmony_ci struct acpi_walk_state *walk_state; 11562306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 11662306a36Sopenharmony_ci acpi_status status; 11762306a36Sopenharmony_ci struct acpi_namespace_node *node; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci /* Validate type_arg */ 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci acpi_ut_strupr(type_arg); 12262306a36Sopenharmony_ci type = type_arg[0]; 12362306a36Sopenharmony_ci if ((type != 'L') && (type != 'A') && (type != 'N')) { 12462306a36Sopenharmony_ci acpi_os_printf("Invalid SET operand: %s\n", type_arg); 12562306a36Sopenharmony_ci return; 12662306a36Sopenharmony_ci } 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci value = strtoul(value_arg, NULL, 16); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci if (type == 'N') { 13162306a36Sopenharmony_ci node = acpi_db_convert_to_node(index_arg); 13262306a36Sopenharmony_ci if (!node) { 13362306a36Sopenharmony_ci return; 13462306a36Sopenharmony_ci } 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci if (node->type != ACPI_TYPE_INTEGER) { 13762306a36Sopenharmony_ci acpi_os_printf("Can only set Integer nodes\n"); 13862306a36Sopenharmony_ci return; 13962306a36Sopenharmony_ci } 14062306a36Sopenharmony_ci obj_desc = node->object; 14162306a36Sopenharmony_ci obj_desc->integer.value = value; 14262306a36Sopenharmony_ci return; 14362306a36Sopenharmony_ci } 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci /* Get the index and value */ 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci index = strtoul(index_arg, NULL, 16); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); 15062306a36Sopenharmony_ci if (!walk_state) { 15162306a36Sopenharmony_ci acpi_os_printf("There is no method currently executing\n"); 15262306a36Sopenharmony_ci return; 15362306a36Sopenharmony_ci } 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci /* Create and initialize the new object */ 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci obj_desc = acpi_ut_create_integer_object((u64)value); 15862306a36Sopenharmony_ci if (!obj_desc) { 15962306a36Sopenharmony_ci acpi_os_printf("Could not create an internal object\n"); 16062306a36Sopenharmony_ci return; 16162306a36Sopenharmony_ci } 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* Store the new object into the target */ 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci switch (type) { 16662306a36Sopenharmony_ci case 'A': 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci /* Set a method argument */ 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci if (index > ACPI_METHOD_MAX_ARG) { 17162306a36Sopenharmony_ci acpi_os_printf("Arg%u - Invalid argument name\n", 17262306a36Sopenharmony_ci index); 17362306a36Sopenharmony_ci goto cleanup; 17462306a36Sopenharmony_ci } 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci status = acpi_ds_store_object_to_local(ACPI_REFCLASS_ARG, 17762306a36Sopenharmony_ci index, obj_desc, 17862306a36Sopenharmony_ci walk_state); 17962306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 18062306a36Sopenharmony_ci goto cleanup; 18162306a36Sopenharmony_ci } 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci obj_desc = walk_state->arguments[index].object; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci acpi_os_printf("Arg%u: ", index); 18662306a36Sopenharmony_ci acpi_db_display_internal_object(obj_desc, walk_state); 18762306a36Sopenharmony_ci break; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci case 'L': 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci /* Set a method local */ 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci if (index > ACPI_METHOD_MAX_LOCAL) { 19462306a36Sopenharmony_ci acpi_os_printf 19562306a36Sopenharmony_ci ("Local%u - Invalid local variable name\n", index); 19662306a36Sopenharmony_ci goto cleanup; 19762306a36Sopenharmony_ci } 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci status = acpi_ds_store_object_to_local(ACPI_REFCLASS_LOCAL, 20062306a36Sopenharmony_ci index, obj_desc, 20162306a36Sopenharmony_ci walk_state); 20262306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 20362306a36Sopenharmony_ci goto cleanup; 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci obj_desc = walk_state->local_variables[index].object; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci acpi_os_printf("Local%u: ", index); 20962306a36Sopenharmony_ci acpi_db_display_internal_object(obj_desc, walk_state); 21062306a36Sopenharmony_ci break; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci default: 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci break; 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_cicleanup: 21862306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 21962306a36Sopenharmony_ci} 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci#ifdef ACPI_DISASSEMBLER 22262306a36Sopenharmony_ci/******************************************************************************* 22362306a36Sopenharmony_ci * 22462306a36Sopenharmony_ci * FUNCTION: acpi_db_disassemble_aml 22562306a36Sopenharmony_ci * 22662306a36Sopenharmony_ci * PARAMETERS: statements - Number of statements to disassemble 22762306a36Sopenharmony_ci * op - Current Op (from parse walk) 22862306a36Sopenharmony_ci * 22962306a36Sopenharmony_ci * RETURN: None 23062306a36Sopenharmony_ci * 23162306a36Sopenharmony_ci * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number 23262306a36Sopenharmony_ci * of statements specified. 23362306a36Sopenharmony_ci * 23462306a36Sopenharmony_ci ******************************************************************************/ 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_civoid acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci u32 num_statements = 8; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci if (!op) { 24162306a36Sopenharmony_ci acpi_os_printf("There is no method currently executing\n"); 24262306a36Sopenharmony_ci return; 24362306a36Sopenharmony_ci } 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci if (statements) { 24662306a36Sopenharmony_ci num_statements = strtoul(statements, NULL, 0); 24762306a36Sopenharmony_ci } 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci acpi_dm_disassemble(NULL, op, num_statements); 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci/******************************************************************************* 25362306a36Sopenharmony_ci * 25462306a36Sopenharmony_ci * FUNCTION: acpi_db_disassemble_method 25562306a36Sopenharmony_ci * 25662306a36Sopenharmony_ci * PARAMETERS: name - Name of control method 25762306a36Sopenharmony_ci * 25862306a36Sopenharmony_ci * RETURN: None 25962306a36Sopenharmony_ci * 26062306a36Sopenharmony_ci * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number 26162306a36Sopenharmony_ci * of statements specified. 26262306a36Sopenharmony_ci * 26362306a36Sopenharmony_ci ******************************************************************************/ 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ciacpi_status acpi_db_disassemble_method(char *name) 26662306a36Sopenharmony_ci{ 26762306a36Sopenharmony_ci acpi_status status; 26862306a36Sopenharmony_ci union acpi_parse_object *op; 26962306a36Sopenharmony_ci struct acpi_walk_state *walk_state; 27062306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 27162306a36Sopenharmony_ci struct acpi_namespace_node *method; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci method = acpi_db_convert_to_node(name); 27462306a36Sopenharmony_ci if (!method) { 27562306a36Sopenharmony_ci return (AE_BAD_PARAMETER); 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci if (method->type != ACPI_TYPE_METHOD) { 27962306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "%s (%s): Object must be a control method", 28062306a36Sopenharmony_ci name, acpi_ut_get_type_name(method->type))); 28162306a36Sopenharmony_ci return (AE_BAD_PARAMETER); 28262306a36Sopenharmony_ci } 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci obj_desc = method->object; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci op = acpi_ps_create_scope_op(obj_desc->method.aml_start); 28762306a36Sopenharmony_ci if (!op) { 28862306a36Sopenharmony_ci return (AE_NO_MEMORY); 28962306a36Sopenharmony_ci } 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci /* Create and initialize a new walk state */ 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci walk_state = acpi_ds_create_walk_state(0, op, NULL, NULL); 29462306a36Sopenharmony_ci if (!walk_state) { 29562306a36Sopenharmony_ci return (AE_NO_MEMORY); 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci status = acpi_ds_init_aml_walk(walk_state, op, NULL, 29962306a36Sopenharmony_ci obj_desc->method.aml_start, 30062306a36Sopenharmony_ci obj_desc->method.aml_length, NULL, 30162306a36Sopenharmony_ci ACPI_IMODE_LOAD_PASS1); 30262306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 30362306a36Sopenharmony_ci return (status); 30462306a36Sopenharmony_ci } 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id); 30762306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 30862306a36Sopenharmony_ci return (status); 30962306a36Sopenharmony_ci } 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci walk_state->owner_id = obj_desc->method.owner_id; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci /* Push start scope on scope stack and make it current */ 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci status = acpi_ds_scope_stack_push(method, method->type, walk_state); 31662306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 31762306a36Sopenharmony_ci return (status); 31862306a36Sopenharmony_ci } 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci /* Parse the entire method AML including deferred operators */ 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci walk_state->parse_flags &= ~ACPI_PARSE_DELETE_TREE; 32362306a36Sopenharmony_ci walk_state->parse_flags |= ACPI_PARSE_DISASSEMBLE; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci status = acpi_ps_parse_aml(walk_state); 32662306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 32762306a36Sopenharmony_ci return (status); 32862306a36Sopenharmony_ci } 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci (void)acpi_dm_parse_deferred_ops(op); 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci /* Now we can disassemble the method */ 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci acpi_gbl_dm_opt_verbose = FALSE; 33562306a36Sopenharmony_ci acpi_dm_disassemble(NULL, op, 0); 33662306a36Sopenharmony_ci acpi_gbl_dm_opt_verbose = TRUE; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci acpi_ps_delete_parse_tree(op); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci /* Method cleanup */ 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci acpi_ns_delete_namespace_subtree(method); 34362306a36Sopenharmony_ci acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id); 34462306a36Sopenharmony_ci acpi_ut_release_owner_id(&obj_desc->method.owner_id); 34562306a36Sopenharmony_ci return (AE_OK); 34662306a36Sopenharmony_ci} 34762306a36Sopenharmony_ci#endif 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci/******************************************************************************* 35062306a36Sopenharmony_ci * 35162306a36Sopenharmony_ci * FUNCTION: acpi_db_evaluate_object 35262306a36Sopenharmony_ci * 35362306a36Sopenharmony_ci * PARAMETERS: node - Namespace node for the object 35462306a36Sopenharmony_ci * 35562306a36Sopenharmony_ci * RETURN: Status 35662306a36Sopenharmony_ci * 35762306a36Sopenharmony_ci * DESCRIPTION: Main execution function for the Evaluate/Execute/All debugger 35862306a36Sopenharmony_ci * commands. 35962306a36Sopenharmony_ci * 36062306a36Sopenharmony_ci ******************************************************************************/ 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_cistatic acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci char *pathname; 36562306a36Sopenharmony_ci u32 i; 36662306a36Sopenharmony_ci struct acpi_device_info *obj_info; 36762306a36Sopenharmony_ci struct acpi_object_list param_objects; 36862306a36Sopenharmony_ci union acpi_object params[ACPI_METHOD_NUM_ARGS]; 36962306a36Sopenharmony_ci struct acpi_buffer return_obj; 37062306a36Sopenharmony_ci acpi_status status; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci pathname = acpi_ns_get_external_pathname(node); 37362306a36Sopenharmony_ci if (!pathname) { 37462306a36Sopenharmony_ci return (AE_OK); 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci /* Get the object info for number of method parameters */ 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci status = acpi_get_object_info(node, &obj_info); 38062306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 38162306a36Sopenharmony_ci ACPI_FREE(pathname); 38262306a36Sopenharmony_ci return (status); 38362306a36Sopenharmony_ci } 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci param_objects.pointer = NULL; 38662306a36Sopenharmony_ci param_objects.count = 0; 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci if (obj_info->type == ACPI_TYPE_METHOD) { 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci /* Setup default parameters */ 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci for (i = 0; i < obj_info->param_count; i++) { 39362306a36Sopenharmony_ci params[i].type = ACPI_TYPE_INTEGER; 39462306a36Sopenharmony_ci params[i].integer.value = 1; 39562306a36Sopenharmony_ci } 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci param_objects.pointer = params; 39862306a36Sopenharmony_ci param_objects.count = obj_info->param_count; 39962306a36Sopenharmony_ci } 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci ACPI_FREE(obj_info); 40262306a36Sopenharmony_ci return_obj.pointer = NULL; 40362306a36Sopenharmony_ci return_obj.length = ACPI_ALLOCATE_BUFFER; 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci /* Do the actual method execution */ 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci acpi_gbl_method_executing = TRUE; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci status = acpi_evaluate_object(node, NULL, ¶m_objects, &return_obj); 41062306a36Sopenharmony_ci acpi_gbl_method_executing = FALSE; 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci acpi_os_printf("%-32s returned %s\n", pathname, 41362306a36Sopenharmony_ci acpi_format_exception(status)); 41462306a36Sopenharmony_ci if (return_obj.length) { 41562306a36Sopenharmony_ci acpi_os_printf("Evaluation of %s returned object %p, " 41662306a36Sopenharmony_ci "external buffer length %X\n", 41762306a36Sopenharmony_ci pathname, return_obj.pointer, 41862306a36Sopenharmony_ci (u32)return_obj.length); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci acpi_db_dump_external_object(return_obj.pointer, 1); 42162306a36Sopenharmony_ci acpi_os_printf("\n"); 42262306a36Sopenharmony_ci } 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci ACPI_FREE(pathname); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci /* Ignore status from method execution */ 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci return (AE_OK); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci /* Update count, check if we have executed enough methods */ 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci/******************************************************************************* 43562306a36Sopenharmony_ci * 43662306a36Sopenharmony_ci * FUNCTION: acpi_db_walk_for_execute 43762306a36Sopenharmony_ci * 43862306a36Sopenharmony_ci * PARAMETERS: Callback from walk_namespace 43962306a36Sopenharmony_ci * 44062306a36Sopenharmony_ci * RETURN: Status 44162306a36Sopenharmony_ci * 44262306a36Sopenharmony_ci * DESCRIPTION: Batch execution function. Evaluates all "predefined" objects -- 44362306a36Sopenharmony_ci * the nameseg begins with an underscore. 44462306a36Sopenharmony_ci * 44562306a36Sopenharmony_ci ******************************************************************************/ 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_cistatic acpi_status 44862306a36Sopenharmony_ciacpi_db_walk_for_execute(acpi_handle obj_handle, 44962306a36Sopenharmony_ci u32 nesting_level, void *context, void **return_value) 45062306a36Sopenharmony_ci{ 45162306a36Sopenharmony_ci struct acpi_namespace_node *node = 45262306a36Sopenharmony_ci (struct acpi_namespace_node *)obj_handle; 45362306a36Sopenharmony_ci struct acpi_db_execute_walk *info = 45462306a36Sopenharmony_ci (struct acpi_db_execute_walk *)context; 45562306a36Sopenharmony_ci acpi_status status; 45662306a36Sopenharmony_ci const union acpi_predefined_info *predefined; 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci predefined = acpi_ut_match_predefined_method(node->name.ascii); 45962306a36Sopenharmony_ci if (!predefined) { 46062306a36Sopenharmony_ci return (AE_OK); 46162306a36Sopenharmony_ci } 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci if (node->type == ACPI_TYPE_LOCAL_SCOPE) { 46462306a36Sopenharmony_ci return (AE_OK); 46562306a36Sopenharmony_ci } 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci acpi_db_evaluate_object(node); 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci /* Ignore status from object evaluation */ 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci status = AE_OK; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci /* Update count, check if we have executed enough methods */ 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci info->count++; 47662306a36Sopenharmony_ci if (info->count >= info->max_count) { 47762306a36Sopenharmony_ci status = AE_CTRL_TERMINATE; 47862306a36Sopenharmony_ci } 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci return (status); 48162306a36Sopenharmony_ci} 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci/******************************************************************************* 48462306a36Sopenharmony_ci * 48562306a36Sopenharmony_ci * FUNCTION: acpi_db_walk_for_execute_all 48662306a36Sopenharmony_ci * 48762306a36Sopenharmony_ci * PARAMETERS: Callback from walk_namespace 48862306a36Sopenharmony_ci * 48962306a36Sopenharmony_ci * RETURN: Status 49062306a36Sopenharmony_ci * 49162306a36Sopenharmony_ci * DESCRIPTION: Batch execution function. Evaluates all objects whose path ends 49262306a36Sopenharmony_ci * with the nameseg "Info->NameSeg". Used for the "ALL" command. 49362306a36Sopenharmony_ci * 49462306a36Sopenharmony_ci ******************************************************************************/ 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_cistatic acpi_status 49762306a36Sopenharmony_ciacpi_db_walk_for_execute_all(acpi_handle obj_handle, 49862306a36Sopenharmony_ci u32 nesting_level, 49962306a36Sopenharmony_ci void *context, void **return_value) 50062306a36Sopenharmony_ci{ 50162306a36Sopenharmony_ci struct acpi_namespace_node *node = 50262306a36Sopenharmony_ci (struct acpi_namespace_node *)obj_handle; 50362306a36Sopenharmony_ci struct acpi_db_execute_walk *info = 50462306a36Sopenharmony_ci (struct acpi_db_execute_walk *)context; 50562306a36Sopenharmony_ci acpi_status status; 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ci if (!ACPI_COMPARE_NAMESEG(node->name.ascii, info->name_seg)) { 50862306a36Sopenharmony_ci return (AE_OK); 50962306a36Sopenharmony_ci } 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci if (node->type == ACPI_TYPE_LOCAL_SCOPE) { 51262306a36Sopenharmony_ci return (AE_OK); 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci /* Now evaluate the input object (node) */ 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci acpi_db_evaluate_object(node); 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci /* Ignore status from method execution */ 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci status = AE_OK; 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci /* Update count of executed methods/objects */ 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci info->count++; 52662306a36Sopenharmony_ci return (status); 52762306a36Sopenharmony_ci} 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci/******************************************************************************* 53062306a36Sopenharmony_ci * 53162306a36Sopenharmony_ci * FUNCTION: acpi_db_evaluate_predefined_names 53262306a36Sopenharmony_ci * 53362306a36Sopenharmony_ci * PARAMETERS: None 53462306a36Sopenharmony_ci * 53562306a36Sopenharmony_ci * RETURN: None 53662306a36Sopenharmony_ci * 53762306a36Sopenharmony_ci * DESCRIPTION: Namespace batch execution. Execute predefined names in the 53862306a36Sopenharmony_ci * namespace, up to the max count, if specified. 53962306a36Sopenharmony_ci * 54062306a36Sopenharmony_ci ******************************************************************************/ 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_civoid acpi_db_evaluate_predefined_names(void) 54362306a36Sopenharmony_ci{ 54462306a36Sopenharmony_ci struct acpi_db_execute_walk info; 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci info.count = 0; 54762306a36Sopenharmony_ci info.max_count = ACPI_UINT32_MAX; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci /* Search all nodes in namespace */ 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 55262306a36Sopenharmony_ci ACPI_UINT32_MAX, acpi_db_walk_for_execute, 55362306a36Sopenharmony_ci NULL, (void *)&info, NULL); 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci acpi_os_printf("Evaluated %u predefined names in the namespace\n", 55662306a36Sopenharmony_ci info.count); 55762306a36Sopenharmony_ci} 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci/******************************************************************************* 56062306a36Sopenharmony_ci * 56162306a36Sopenharmony_ci * FUNCTION: acpi_db_evaluate_all 56262306a36Sopenharmony_ci * 56362306a36Sopenharmony_ci * PARAMETERS: none_acpi_gbl_db_method_info 56462306a36Sopenharmony_ci * 56562306a36Sopenharmony_ci * RETURN: None 56662306a36Sopenharmony_ci * 56762306a36Sopenharmony_ci * DESCRIPTION: Namespace batch execution. Implements the "ALL" command. 56862306a36Sopenharmony_ci * Execute all namepaths whose final nameseg matches the 56962306a36Sopenharmony_ci * input nameseg. 57062306a36Sopenharmony_ci * 57162306a36Sopenharmony_ci ******************************************************************************/ 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_civoid acpi_db_evaluate_all(char *name_seg) 57462306a36Sopenharmony_ci{ 57562306a36Sopenharmony_ci struct acpi_db_execute_walk info; 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci info.count = 0; 57862306a36Sopenharmony_ci info.max_count = ACPI_UINT32_MAX; 57962306a36Sopenharmony_ci ACPI_COPY_NAMESEG(info.name_seg, name_seg); 58062306a36Sopenharmony_ci info.name_seg[ACPI_NAMESEG_SIZE] = 0; 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci /* Search all nodes in namespace */ 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 58562306a36Sopenharmony_ci ACPI_UINT32_MAX, acpi_db_walk_for_execute_all, 58662306a36Sopenharmony_ci NULL, (void *)&info, NULL); 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci acpi_os_printf("Evaluated %u names in the namespace\n", info.count); 58962306a36Sopenharmony_ci} 590