xref: /openbmc/linux/drivers/acpi/acpica/dbmethod.c (revision 6218ab30)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
299575102SLv Zheng /*******************************************************************************
399575102SLv Zheng  *
499575102SLv Zheng  * Module Name: dbmethod - Debug commands for control methods
599575102SLv Zheng  *
699575102SLv Zheng  ******************************************************************************/
799575102SLv Zheng 
899575102SLv Zheng #include <acpi/acpi.h>
999575102SLv Zheng #include "accommon.h"
1099575102SLv Zheng #include "acdispat.h"
1199575102SLv Zheng #include "acnamesp.h"
1299575102SLv Zheng #include "acdebug.h"
1399575102SLv Zheng #include "acparser.h"
1499575102SLv Zheng #include "acpredef.h"
1599575102SLv Zheng 
1699575102SLv Zheng #define _COMPONENT          ACPI_CA_DEBUGGER
1799575102SLv Zheng ACPI_MODULE_NAME("dbmethod")
1899575102SLv Zheng 
1960361b75SBob Moore /* Local prototypes */
2060361b75SBob Moore static acpi_status
2160361b75SBob Moore acpi_db_walk_for_execute(acpi_handle obj_handle,
2260361b75SBob Moore 			 u32 nesting_level, void *context, void **return_value);
2360361b75SBob Moore 
246218ab30SBob Moore static acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node);
256218ab30SBob Moore 
2699575102SLv Zheng /*******************************************************************************
2799575102SLv Zheng  *
2899575102SLv Zheng  * FUNCTION:    acpi_db_set_method_breakpoint
2999575102SLv Zheng  *
3099575102SLv Zheng  * PARAMETERS:  location            - AML offset of breakpoint
3199575102SLv Zheng  *              walk_state          - Current walk info
3299575102SLv Zheng  *              op                  - Current Op (from parse walk)
3399575102SLv Zheng  *
3499575102SLv Zheng  * RETURN:      None
3599575102SLv Zheng  *
3699575102SLv Zheng  * DESCRIPTION: Set a breakpoint in a control method at the specified
3799575102SLv Zheng  *              AML offset
3899575102SLv Zheng  *
3999575102SLv Zheng  ******************************************************************************/
4060361b75SBob Moore 
4199575102SLv Zheng void
acpi_db_set_method_breakpoint(char * location,struct acpi_walk_state * walk_state,union acpi_parse_object * op)4299575102SLv Zheng acpi_db_set_method_breakpoint(char *location,
4399575102SLv Zheng 			      struct acpi_walk_state *walk_state,
4499575102SLv Zheng 			      union acpi_parse_object *op)
4599575102SLv Zheng {
4699575102SLv Zheng 	u32 address;
4799575102SLv Zheng 	u32 aml_offset;
4899575102SLv Zheng 
4999575102SLv Zheng 	if (!op) {
5099575102SLv Zheng 		acpi_os_printf("There is no method currently executing\n");
5199575102SLv Zheng 		return;
5299575102SLv Zheng 	}
5399575102SLv Zheng 
5499575102SLv Zheng 	/* Get and verify the breakpoint address */
5599575102SLv Zheng 
5699575102SLv Zheng 	address = strtoul(location, NULL, 16);
5799575102SLv Zheng 	aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
5899575102SLv Zheng 					walk_state->parser_state.aml_start);
5999575102SLv Zheng 	if (address <= aml_offset) {
6099575102SLv Zheng 		acpi_os_printf("Breakpoint %X is beyond current address %X\n",
6199575102SLv Zheng 			       address, aml_offset);
6299575102SLv Zheng 	}
6399575102SLv Zheng 
6499575102SLv Zheng 	/* Save breakpoint in current walk */
6599575102SLv Zheng 
6699575102SLv Zheng 	walk_state->user_breakpoint = address;
6799575102SLv Zheng 	acpi_os_printf("Breakpoint set at AML offset %X\n", address);
6899575102SLv Zheng }
6999575102SLv Zheng 
7099575102SLv Zheng /*******************************************************************************
7199575102SLv Zheng  *
7299575102SLv Zheng  * FUNCTION:    acpi_db_set_method_call_breakpoint
7399575102SLv Zheng  *
7499575102SLv Zheng  * PARAMETERS:  op                  - Current Op (from parse walk)
7599575102SLv Zheng  *
7699575102SLv Zheng  * RETURN:      None
7799575102SLv Zheng  *
7899575102SLv Zheng  * DESCRIPTION: Set a breakpoint in a control method at the specified
7999575102SLv Zheng  *              AML offset
8099575102SLv Zheng  *
8199575102SLv Zheng  ******************************************************************************/
8299575102SLv Zheng 
acpi_db_set_method_call_breakpoint(union acpi_parse_object * op)8399575102SLv Zheng void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op)
8499575102SLv Zheng {
8599575102SLv Zheng 
8699575102SLv Zheng 	if (!op) {
8799575102SLv Zheng 		acpi_os_printf("There is no method currently executing\n");
8899575102SLv Zheng 		return;
8999575102SLv Zheng 	}
9099575102SLv Zheng 
9199575102SLv Zheng 	acpi_gbl_step_to_next_call = TRUE;
9299575102SLv Zheng }
9399575102SLv Zheng 
9499575102SLv Zheng /*******************************************************************************
9599575102SLv Zheng  *
9699575102SLv Zheng  * FUNCTION:    acpi_db_set_method_data
9799575102SLv Zheng  *
9899575102SLv Zheng  * PARAMETERS:  type_arg        - L for local, A for argument
9999575102SLv Zheng  *              index_arg       - which one
10099575102SLv Zheng  *              value_arg       - Value to set.
10199575102SLv Zheng  *
10299575102SLv Zheng  * RETURN:      None
10399575102SLv Zheng  *
10499575102SLv Zheng  * DESCRIPTION: Set a local or argument for the running control method.
10599575102SLv Zheng  *              NOTE: only object supported is Number.
10699575102SLv Zheng  *
10799575102SLv Zheng  ******************************************************************************/
10899575102SLv Zheng 
acpi_db_set_method_data(char * type_arg,char * index_arg,char * value_arg)10999575102SLv Zheng void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg)
11099575102SLv Zheng {
11199575102SLv Zheng 	char type;
11299575102SLv Zheng 	u32 index;
11399575102SLv Zheng 	u32 value;
11499575102SLv Zheng 	struct acpi_walk_state *walk_state;
11599575102SLv Zheng 	union acpi_operand_object *obj_desc;
11699575102SLv Zheng 	acpi_status status;
11799575102SLv Zheng 	struct acpi_namespace_node *node;
11899575102SLv Zheng 
11999575102SLv Zheng 	/* Validate type_arg */
12099575102SLv Zheng 
12199575102SLv Zheng 	acpi_ut_strupr(type_arg);
12299575102SLv Zheng 	type = type_arg[0];
12399575102SLv Zheng 	if ((type != 'L') && (type != 'A') && (type != 'N')) {
12499575102SLv Zheng 		acpi_os_printf("Invalid SET operand: %s\n", type_arg);
12599575102SLv Zheng 		return;
12699575102SLv Zheng 	}
12799575102SLv Zheng 
12899575102SLv Zheng 	value = strtoul(value_arg, NULL, 16);
12999575102SLv Zheng 
13099575102SLv Zheng 	if (type == 'N') {
13199575102SLv Zheng 		node = acpi_db_convert_to_node(index_arg);
13299575102SLv Zheng 		if (!node) {
13399575102SLv Zheng 			return;
13499575102SLv Zheng 		}
13599575102SLv Zheng 
13699575102SLv Zheng 		if (node->type != ACPI_TYPE_INTEGER) {
13799575102SLv Zheng 			acpi_os_printf("Can only set Integer nodes\n");
13899575102SLv Zheng 			return;
13999575102SLv Zheng 		}
14099575102SLv Zheng 		obj_desc = node->object;
14199575102SLv Zheng 		obj_desc->integer.value = value;
14299575102SLv Zheng 		return;
14399575102SLv Zheng 	}
14499575102SLv Zheng 
14599575102SLv Zheng 	/* Get the index and value */
14699575102SLv Zheng 
14799575102SLv Zheng 	index = strtoul(index_arg, NULL, 16);
14899575102SLv Zheng 
14999575102SLv Zheng 	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
15099575102SLv Zheng 	if (!walk_state) {
15199575102SLv Zheng 		acpi_os_printf("There is no method currently executing\n");
15299575102SLv Zheng 		return;
15399575102SLv Zheng 	}
15499575102SLv Zheng 
15599575102SLv Zheng 	/* Create and initialize the new object */
15699575102SLv Zheng 
15799575102SLv Zheng 	obj_desc = acpi_ut_create_integer_object((u64)value);
15899575102SLv Zheng 	if (!obj_desc) {
15999575102SLv Zheng 		acpi_os_printf("Could not create an internal object\n");
16099575102SLv Zheng 		return;
16199575102SLv Zheng 	}
16299575102SLv Zheng 
16399575102SLv Zheng 	/* Store the new object into the target */
16499575102SLv Zheng 
16599575102SLv Zheng 	switch (type) {
16699575102SLv Zheng 	case 'A':
16799575102SLv Zheng 
16899575102SLv Zheng 		/* Set a method argument */
16999575102SLv Zheng 
17099575102SLv Zheng 		if (index > ACPI_METHOD_MAX_ARG) {
17199575102SLv Zheng 			acpi_os_printf("Arg%u - Invalid argument name\n",
17299575102SLv Zheng 				       index);
17399575102SLv Zheng 			goto cleanup;
17499575102SLv Zheng 		}
17599575102SLv Zheng 
17699575102SLv Zheng 		status = acpi_ds_store_object_to_local(ACPI_REFCLASS_ARG,
17799575102SLv Zheng 						       index, obj_desc,
17899575102SLv Zheng 						       walk_state);
17999575102SLv Zheng 		if (ACPI_FAILURE(status)) {
18099575102SLv Zheng 			goto cleanup;
18199575102SLv Zheng 		}
18299575102SLv Zheng 
18399575102SLv Zheng 		obj_desc = walk_state->arguments[index].object;
18499575102SLv Zheng 
18599575102SLv Zheng 		acpi_os_printf("Arg%u: ", index);
18699575102SLv Zheng 		acpi_db_display_internal_object(obj_desc, walk_state);
18799575102SLv Zheng 		break;
18899575102SLv Zheng 
18999575102SLv Zheng 	case 'L':
19099575102SLv Zheng 
19199575102SLv Zheng 		/* Set a method local */
19299575102SLv Zheng 
19399575102SLv Zheng 		if (index > ACPI_METHOD_MAX_LOCAL) {
19499575102SLv Zheng 			acpi_os_printf
19599575102SLv Zheng 			    ("Local%u - Invalid local variable name\n", index);
19699575102SLv Zheng 			goto cleanup;
19799575102SLv Zheng 		}
19899575102SLv Zheng 
19999575102SLv Zheng 		status = acpi_ds_store_object_to_local(ACPI_REFCLASS_LOCAL,
20099575102SLv Zheng 						       index, obj_desc,
20199575102SLv Zheng 						       walk_state);
20299575102SLv Zheng 		if (ACPI_FAILURE(status)) {
20399575102SLv Zheng 			goto cleanup;
20499575102SLv Zheng 		}
20599575102SLv Zheng 
20699575102SLv Zheng 		obj_desc = walk_state->local_variables[index].object;
20799575102SLv Zheng 
20899575102SLv Zheng 		acpi_os_printf("Local%u: ", index);
20999575102SLv Zheng 		acpi_db_display_internal_object(obj_desc, walk_state);
21099575102SLv Zheng 		break;
21199575102SLv Zheng 
21299575102SLv Zheng 	default:
21399575102SLv Zheng 
21499575102SLv Zheng 		break;
21599575102SLv Zheng 	}
21699575102SLv Zheng 
21799575102SLv Zheng cleanup:
21899575102SLv Zheng 	acpi_ut_remove_reference(obj_desc);
21999575102SLv Zheng }
22099575102SLv Zheng 
221fb2ef998SBob Moore #ifdef ACPI_DISASSEMBLER
22299575102SLv Zheng /*******************************************************************************
22399575102SLv Zheng  *
22499575102SLv Zheng  * FUNCTION:    acpi_db_disassemble_aml
22599575102SLv Zheng  *
22699575102SLv Zheng  * PARAMETERS:  statements          - Number of statements to disassemble
22799575102SLv Zheng  *              op                  - Current Op (from parse walk)
22899575102SLv Zheng  *
22999575102SLv Zheng  * RETURN:      None
23099575102SLv Zheng  *
23199575102SLv Zheng  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
23299575102SLv Zheng  *              of statements specified.
23399575102SLv Zheng  *
23499575102SLv Zheng  ******************************************************************************/
23599575102SLv Zheng 
acpi_db_disassemble_aml(char * statements,union acpi_parse_object * op)23699575102SLv Zheng void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op)
23799575102SLv Zheng {
23899575102SLv Zheng 	u32 num_statements = 8;
23999575102SLv Zheng 
24099575102SLv Zheng 	if (!op) {
24199575102SLv Zheng 		acpi_os_printf("There is no method currently executing\n");
24299575102SLv Zheng 		return;
24399575102SLv Zheng 	}
24499575102SLv Zheng 
24599575102SLv Zheng 	if (statements) {
24699575102SLv Zheng 		num_statements = strtoul(statements, NULL, 0);
24799575102SLv Zheng 	}
248fb2ef998SBob Moore 
24999575102SLv Zheng 	acpi_dm_disassemble(NULL, op, num_statements);
25099575102SLv Zheng }
25199575102SLv Zheng 
25299575102SLv Zheng /*******************************************************************************
25399575102SLv Zheng  *
25499575102SLv Zheng  * FUNCTION:    acpi_db_disassemble_method
25599575102SLv Zheng  *
25699575102SLv Zheng  * PARAMETERS:  name            - Name of control method
25799575102SLv Zheng  *
25899575102SLv Zheng  * RETURN:      None
25999575102SLv Zheng  *
26099575102SLv Zheng  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
26199575102SLv Zheng  *              of statements specified.
26299575102SLv Zheng  *
26399575102SLv Zheng  ******************************************************************************/
26499575102SLv Zheng 
acpi_db_disassemble_method(char * name)26599575102SLv Zheng acpi_status acpi_db_disassemble_method(char *name)
26699575102SLv Zheng {
26799575102SLv Zheng 	acpi_status status;
26899575102SLv Zheng 	union acpi_parse_object *op;
26999575102SLv Zheng 	struct acpi_walk_state *walk_state;
27099575102SLv Zheng 	union acpi_operand_object *obj_desc;
27199575102SLv Zheng 	struct acpi_namespace_node *method;
27299575102SLv Zheng 
27399575102SLv Zheng 	method = acpi_db_convert_to_node(name);
27499575102SLv Zheng 	if (!method) {
27599575102SLv Zheng 		return (AE_BAD_PARAMETER);
27699575102SLv Zheng 	}
27799575102SLv Zheng 
27899575102SLv Zheng 	if (method->type != ACPI_TYPE_METHOD) {
27999575102SLv Zheng 		ACPI_ERROR((AE_INFO, "%s (%s): Object must be a control method",
28099575102SLv Zheng 			    name, acpi_ut_get_type_name(method->type)));
28199575102SLv Zheng 		return (AE_BAD_PARAMETER);
28299575102SLv Zheng 	}
28399575102SLv Zheng 
28499575102SLv Zheng 	obj_desc = method->object;
28599575102SLv Zheng 
28699575102SLv Zheng 	op = acpi_ps_create_scope_op(obj_desc->method.aml_start);
28799575102SLv Zheng 	if (!op) {
28899575102SLv Zheng 		return (AE_NO_MEMORY);
28999575102SLv Zheng 	}
29099575102SLv Zheng 
29199575102SLv Zheng 	/* Create and initialize a new walk state */
29299575102SLv Zheng 
29399575102SLv Zheng 	walk_state = acpi_ds_create_walk_state(0, op, NULL, NULL);
29499575102SLv Zheng 	if (!walk_state) {
29599575102SLv Zheng 		return (AE_NO_MEMORY);
29699575102SLv Zheng 	}
29799575102SLv Zheng 
29899575102SLv Zheng 	status = acpi_ds_init_aml_walk(walk_state, op, NULL,
29999575102SLv Zheng 				       obj_desc->method.aml_start,
30099575102SLv Zheng 				       obj_desc->method.aml_length, NULL,
30199575102SLv Zheng 				       ACPI_IMODE_LOAD_PASS1);
30299575102SLv Zheng 	if (ACPI_FAILURE(status)) {
30399575102SLv Zheng 		return (status);
30499575102SLv Zheng 	}
30599575102SLv Zheng 
30699575102SLv Zheng 	status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
30767a72420SBob Moore 	if (ACPI_FAILURE(status)) {
30867a72420SBob Moore 		return (status);
30967a72420SBob Moore 	}
31067a72420SBob Moore 
31199575102SLv Zheng 	walk_state->owner_id = obj_desc->method.owner_id;
31299575102SLv Zheng 
31399575102SLv Zheng 	/* Push start scope on scope stack and make it current */
31499575102SLv Zheng 
31599575102SLv Zheng 	status = acpi_ds_scope_stack_push(method, method->type, walk_state);
31699575102SLv Zheng 	if (ACPI_FAILURE(status)) {
31799575102SLv Zheng 		return (status);
31899575102SLv Zheng 	}
31999575102SLv Zheng 
32099575102SLv Zheng 	/* Parse the entire method AML including deferred operators */
32199575102SLv Zheng 
32299575102SLv Zheng 	walk_state->parse_flags &= ~ACPI_PARSE_DELETE_TREE;
32399575102SLv Zheng 	walk_state->parse_flags |= ACPI_PARSE_DISASSEMBLE;
32499575102SLv Zheng 
32599575102SLv Zheng 	status = acpi_ps_parse_aml(walk_state);
326edc5935eSBob Moore 	if (ACPI_FAILURE(status)) {
327edc5935eSBob Moore 		return (status);
328edc5935eSBob Moore 	}
329edc5935eSBob Moore 
33099575102SLv Zheng 	(void)acpi_dm_parse_deferred_ops(op);
33199575102SLv Zheng 
33299575102SLv Zheng 	/* Now we can disassemble the method */
33399575102SLv Zheng 
33499575102SLv Zheng 	acpi_gbl_dm_opt_verbose = FALSE;
33599575102SLv Zheng 	acpi_dm_disassemble(NULL, op, 0);
33699575102SLv Zheng 	acpi_gbl_dm_opt_verbose = TRUE;
33799575102SLv Zheng 
33899575102SLv Zheng 	acpi_ps_delete_parse_tree(op);
33999575102SLv Zheng 
34099575102SLv Zheng 	/* Method cleanup */
34199575102SLv Zheng 
34299575102SLv Zheng 	acpi_ns_delete_namespace_subtree(method);
34399575102SLv Zheng 	acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
34499575102SLv Zheng 	acpi_ut_release_owner_id(&obj_desc->method.owner_id);
34599575102SLv Zheng 	return (AE_OK);
34699575102SLv Zheng }
347fb2ef998SBob Moore #endif
34860361b75SBob Moore 
34960361b75SBob Moore /*******************************************************************************
35060361b75SBob Moore  *
3516218ab30SBob Moore  * FUNCTION:    acpi_db_evaluate_object
35260361b75SBob Moore  *
3536218ab30SBob Moore  * PARAMETERS:  node                - Namespace node for the object
35460361b75SBob Moore  *
35560361b75SBob Moore  * RETURN:      Status
35660361b75SBob Moore  *
3576218ab30SBob Moore  * DESCRIPTION: Main execution function for the Evaluate/Execute/All debugger
3586218ab30SBob Moore  *              commands.
35960361b75SBob Moore  *
36060361b75SBob Moore  ******************************************************************************/
36160361b75SBob Moore 
acpi_db_evaluate_object(struct acpi_namespace_node * node)3626218ab30SBob Moore static acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node)
36360361b75SBob Moore {
36460361b75SBob Moore 	char *pathname;
36560361b75SBob Moore 	u32 i;
36660361b75SBob Moore 	struct acpi_device_info *obj_info;
36760361b75SBob Moore 	struct acpi_object_list param_objects;
36860361b75SBob Moore 	union acpi_object params[ACPI_METHOD_NUM_ARGS];
3696218ab30SBob Moore 	struct acpi_buffer return_obj;
3706218ab30SBob Moore 	acpi_status status;
37160361b75SBob Moore 
37260361b75SBob Moore 	pathname = acpi_ns_get_external_pathname(node);
37360361b75SBob Moore 	if (!pathname) {
37460361b75SBob Moore 		return (AE_OK);
37560361b75SBob Moore 	}
37660361b75SBob Moore 
37760361b75SBob Moore 	/* Get the object info for number of method parameters */
37860361b75SBob Moore 
3796218ab30SBob Moore 	status = acpi_get_object_info(node, &obj_info);
38060361b75SBob Moore 	if (ACPI_FAILURE(status)) {
3811f67ef69SColin Ian King 		ACPI_FREE(pathname);
38260361b75SBob Moore 		return (status);
38360361b75SBob Moore 	}
38460361b75SBob Moore 
38560361b75SBob Moore 	param_objects.pointer = NULL;
38660361b75SBob Moore 	param_objects.count = 0;
38760361b75SBob Moore 
38860361b75SBob Moore 	if (obj_info->type == ACPI_TYPE_METHOD) {
38960361b75SBob Moore 
39060361b75SBob Moore 		/* Setup default parameters */
39160361b75SBob Moore 
39260361b75SBob Moore 		for (i = 0; i < obj_info->param_count; i++) {
39360361b75SBob Moore 			params[i].type = ACPI_TYPE_INTEGER;
39460361b75SBob Moore 			params[i].integer.value = 1;
39560361b75SBob Moore 		}
39660361b75SBob Moore 
39760361b75SBob Moore 		param_objects.pointer = params;
39860361b75SBob Moore 		param_objects.count = obj_info->param_count;
39960361b75SBob Moore 	}
40060361b75SBob Moore 
40160361b75SBob Moore 	ACPI_FREE(obj_info);
40260361b75SBob Moore 	return_obj.pointer = NULL;
40360361b75SBob Moore 	return_obj.length = ACPI_ALLOCATE_BUFFER;
40460361b75SBob Moore 
40560361b75SBob Moore 	/* Do the actual method execution */
40660361b75SBob Moore 
40760361b75SBob Moore 	acpi_gbl_method_executing = TRUE;
40860361b75SBob Moore 
40960361b75SBob Moore 	status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
4106218ab30SBob Moore 	acpi_gbl_method_executing = FALSE;
41160361b75SBob Moore 
41260361b75SBob Moore 	acpi_os_printf("%-32s returned %s\n", pathname,
41360361b75SBob Moore 		       acpi_format_exception(status));
4146218ab30SBob Moore 	if (return_obj.length) {
4156218ab30SBob Moore 		acpi_os_printf("Evaluation of %s returned object %p, "
4166218ab30SBob Moore 			       "external buffer length %X\n",
4176218ab30SBob Moore 			       pathname, return_obj.pointer,
4186218ab30SBob Moore 			       (u32)return_obj.length);
4196218ab30SBob Moore 
4206218ab30SBob Moore 		acpi_db_dump_external_object(return_obj.pointer, 1);
4216218ab30SBob Moore 		acpi_os_printf("\n");
4226218ab30SBob Moore 	}
4236218ab30SBob Moore 
42460361b75SBob Moore 	ACPI_FREE(pathname);
42560361b75SBob Moore 
42660361b75SBob Moore 	/* Ignore status from method execution */
42760361b75SBob Moore 
4286218ab30SBob Moore 	return (AE_OK);
4296218ab30SBob Moore 
4306218ab30SBob Moore 	/* Update count, check if we have executed enough methods */
4316218ab30SBob Moore 
4326218ab30SBob Moore }
4336218ab30SBob Moore 
4346218ab30SBob Moore /*******************************************************************************
4356218ab30SBob Moore  *
4366218ab30SBob Moore  * FUNCTION:    acpi_db_walk_for_execute
4376218ab30SBob Moore  *
4386218ab30SBob Moore  * PARAMETERS:  Callback from walk_namespace
4396218ab30SBob Moore  *
4406218ab30SBob Moore  * RETURN:      Status
4416218ab30SBob Moore  *
4426218ab30SBob Moore  * DESCRIPTION: Batch execution function. Evaluates all "predefined" objects --
4436218ab30SBob Moore  *              the nameseg begins with an underscore.
4446218ab30SBob Moore  *
4456218ab30SBob Moore  ******************************************************************************/
4466218ab30SBob Moore 
4476218ab30SBob Moore static acpi_status
acpi_db_walk_for_execute(acpi_handle obj_handle,u32 nesting_level,void * context,void ** return_value)4486218ab30SBob Moore acpi_db_walk_for_execute(acpi_handle obj_handle,
4496218ab30SBob Moore 			 u32 nesting_level, void *context, void **return_value)
4506218ab30SBob Moore {
4516218ab30SBob Moore 	struct acpi_namespace_node *node =
4526218ab30SBob Moore 	    (struct acpi_namespace_node *)obj_handle;
4536218ab30SBob Moore 	struct acpi_db_execute_walk *info =
4546218ab30SBob Moore 	    (struct acpi_db_execute_walk *)context;
4556218ab30SBob Moore 	acpi_status status;
4566218ab30SBob Moore 	const union acpi_predefined_info *predefined;
4576218ab30SBob Moore 
4586218ab30SBob Moore 	predefined = acpi_ut_match_predefined_method(node->name.ascii);
4596218ab30SBob Moore 	if (!predefined) {
4606218ab30SBob Moore 		return (AE_OK);
4616218ab30SBob Moore 	}
4626218ab30SBob Moore 
4636218ab30SBob Moore 	if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
4646218ab30SBob Moore 		return (AE_OK);
4656218ab30SBob Moore 	}
4666218ab30SBob Moore 
4676218ab30SBob Moore 	acpi_db_evaluate_object(node);
4686218ab30SBob Moore 
4696218ab30SBob Moore 	/* Ignore status from object evaluation */
4706218ab30SBob Moore 
47160361b75SBob Moore 	status = AE_OK;
47260361b75SBob Moore 
47360361b75SBob Moore 	/* Update count, check if we have executed enough methods */
47460361b75SBob Moore 
47560361b75SBob Moore 	info->count++;
47660361b75SBob Moore 	if (info->count >= info->max_count) {
47760361b75SBob Moore 		status = AE_CTRL_TERMINATE;
47860361b75SBob Moore 	}
47960361b75SBob Moore 
48060361b75SBob Moore 	return (status);
48160361b75SBob Moore }
48260361b75SBob Moore 
48360361b75SBob Moore /*******************************************************************************
48460361b75SBob Moore  *
4856218ab30SBob Moore  * FUNCTION:    acpi_db_walk_for_execute_all
4866218ab30SBob Moore  *
4876218ab30SBob Moore  * PARAMETERS:  Callback from walk_namespace
4886218ab30SBob Moore  *
4896218ab30SBob Moore  * RETURN:      Status
4906218ab30SBob Moore  *
4916218ab30SBob Moore  * DESCRIPTION: Batch execution function. Evaluates all objects whose path ends
4926218ab30SBob Moore  *              with the nameseg "Info->NameSeg". Used for the "ALL" command.
4936218ab30SBob Moore  *
4946218ab30SBob Moore  ******************************************************************************/
4956218ab30SBob Moore 
4966218ab30SBob Moore static acpi_status
acpi_db_walk_for_execute_all(acpi_handle obj_handle,u32 nesting_level,void * context,void ** return_value)4976218ab30SBob Moore acpi_db_walk_for_execute_all(acpi_handle obj_handle,
4986218ab30SBob Moore 			     u32 nesting_level,
4996218ab30SBob Moore 			     void *context, void **return_value)
5006218ab30SBob Moore {
5016218ab30SBob Moore 	struct acpi_namespace_node *node =
5026218ab30SBob Moore 	    (struct acpi_namespace_node *)obj_handle;
5036218ab30SBob Moore 	struct acpi_db_execute_walk *info =
5046218ab30SBob Moore 	    (struct acpi_db_execute_walk *)context;
5056218ab30SBob Moore 	acpi_status status;
5066218ab30SBob Moore 
5076218ab30SBob Moore 	if (!ACPI_COMPARE_NAMESEG(node->name.ascii, info->name_seg)) {
5086218ab30SBob Moore 		return (AE_OK);
5096218ab30SBob Moore 	}
5106218ab30SBob Moore 
5116218ab30SBob Moore 	if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
5126218ab30SBob Moore 		return (AE_OK);
5136218ab30SBob Moore 	}
5146218ab30SBob Moore 
5156218ab30SBob Moore 	/* Now evaluate the input object (node) */
5166218ab30SBob Moore 
5176218ab30SBob Moore 	acpi_db_evaluate_object(node);
5186218ab30SBob Moore 
5196218ab30SBob Moore 	/* Ignore status from method execution */
5206218ab30SBob Moore 
5216218ab30SBob Moore 	status = AE_OK;
5226218ab30SBob Moore 
5236218ab30SBob Moore 	/* Update count of executed methods/objects */
5246218ab30SBob Moore 
5256218ab30SBob Moore 	info->count++;
5266218ab30SBob Moore 	return (status);
5276218ab30SBob Moore }
5286218ab30SBob Moore 
5296218ab30SBob Moore /*******************************************************************************
5306218ab30SBob Moore  *
53160361b75SBob Moore  * FUNCTION:    acpi_db_evaluate_predefined_names
53260361b75SBob Moore  *
53360361b75SBob Moore  * PARAMETERS:  None
53460361b75SBob Moore  *
53560361b75SBob Moore  * RETURN:      None
53660361b75SBob Moore  *
53760361b75SBob Moore  * DESCRIPTION: Namespace batch execution. Execute predefined names in the
53860361b75SBob Moore  *              namespace, up to the max count, if specified.
53960361b75SBob Moore  *
54060361b75SBob Moore  ******************************************************************************/
54160361b75SBob Moore 
acpi_db_evaluate_predefined_names(void)54260361b75SBob Moore void acpi_db_evaluate_predefined_names(void)
54360361b75SBob Moore {
54460361b75SBob Moore 	struct acpi_db_execute_walk info;
54560361b75SBob Moore 
54660361b75SBob Moore 	info.count = 0;
54760361b75SBob Moore 	info.max_count = ACPI_UINT32_MAX;
54860361b75SBob Moore 
54960361b75SBob Moore 	/* Search all nodes in namespace */
55060361b75SBob Moore 
55160361b75SBob Moore 	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
55260361b75SBob Moore 				  ACPI_UINT32_MAX, acpi_db_walk_for_execute,
55360361b75SBob Moore 				  NULL, (void *)&info, NULL);
55460361b75SBob Moore 
55560361b75SBob Moore 	acpi_os_printf("Evaluated %u predefined names in the namespace\n",
55660361b75SBob Moore 		       info.count);
55760361b75SBob Moore }
5586218ab30SBob Moore 
5596218ab30SBob Moore /*******************************************************************************
5606218ab30SBob Moore  *
5616218ab30SBob Moore  * FUNCTION:    acpi_db_evaluate_all
5626218ab30SBob Moore  *
5636218ab30SBob Moore  * PARAMETERS:  none_acpi_gbl_db_method_info
5646218ab30SBob Moore  *
5656218ab30SBob Moore  * RETURN:      None
5666218ab30SBob Moore  *
5676218ab30SBob Moore  * DESCRIPTION: Namespace batch execution. Implements the "ALL" command.
5686218ab30SBob Moore  *              Execute all namepaths whose final nameseg matches the
5696218ab30SBob Moore  *              input nameseg.
5706218ab30SBob Moore  *
5716218ab30SBob Moore  ******************************************************************************/
5726218ab30SBob Moore 
acpi_db_evaluate_all(char * name_seg)5736218ab30SBob Moore void acpi_db_evaluate_all(char *name_seg)
5746218ab30SBob Moore {
5756218ab30SBob Moore 	struct acpi_db_execute_walk info;
5766218ab30SBob Moore 
5776218ab30SBob Moore 	info.count = 0;
5786218ab30SBob Moore 	info.max_count = ACPI_UINT32_MAX;
5796218ab30SBob Moore 	ACPI_COPY_NAMESEG(info.name_seg, name_seg);
5806218ab30SBob Moore 	info.name_seg[ACPI_NAMESEG_SIZE] = 0;
5816218ab30SBob Moore 
5826218ab30SBob Moore 	/* Search all nodes in namespace */
5836218ab30SBob Moore 
5846218ab30SBob Moore 	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
5856218ab30SBob Moore 				  ACPI_UINT32_MAX, acpi_db_walk_for_execute_all,
5866218ab30SBob Moore 				  NULL, (void *)&info, NULL);
5876218ab30SBob Moore 
5886218ab30SBob Moore 	acpi_os_printf("Evaluated %u names in the namespace\n", info.count);
5896218ab30SBob Moore }
590