xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/dbmethod.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /*******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Module Name: dbmethod - Debug commands for control methods
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  ******************************************************************************/
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <acpi/acpi.h>
9*4882a593Smuzhiyun #include "accommon.h"
10*4882a593Smuzhiyun #include "acdispat.h"
11*4882a593Smuzhiyun #include "acnamesp.h"
12*4882a593Smuzhiyun #include "acdebug.h"
13*4882a593Smuzhiyun #include "acparser.h"
14*4882a593Smuzhiyun #include "acpredef.h"
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define _COMPONENT          ACPI_CA_DEBUGGER
17*4882a593Smuzhiyun ACPI_MODULE_NAME("dbmethod")
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* Local prototypes */
20*4882a593Smuzhiyun static acpi_status
21*4882a593Smuzhiyun acpi_db_walk_for_execute(acpi_handle obj_handle,
22*4882a593Smuzhiyun 			 u32 nesting_level, void *context, void **return_value);
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun static acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node);
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /*******************************************************************************
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * FUNCTION:    acpi_db_set_method_breakpoint
29*4882a593Smuzhiyun  *
30*4882a593Smuzhiyun  * PARAMETERS:  location            - AML offset of breakpoint
31*4882a593Smuzhiyun  *              walk_state          - Current walk info
32*4882a593Smuzhiyun  *              op                  - Current Op (from parse walk)
33*4882a593Smuzhiyun  *
34*4882a593Smuzhiyun  * RETURN:      None
35*4882a593Smuzhiyun  *
36*4882a593Smuzhiyun  * DESCRIPTION: Set a breakpoint in a control method at the specified
37*4882a593Smuzhiyun  *              AML offset
38*4882a593Smuzhiyun  *
39*4882a593Smuzhiyun  ******************************************************************************/
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun void
acpi_db_set_method_breakpoint(char * location,struct acpi_walk_state * walk_state,union acpi_parse_object * op)42*4882a593Smuzhiyun acpi_db_set_method_breakpoint(char *location,
43*4882a593Smuzhiyun 			      struct acpi_walk_state *walk_state,
44*4882a593Smuzhiyun 			      union acpi_parse_object *op)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun 	u32 address;
47*4882a593Smuzhiyun 	u32 aml_offset;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	if (!op) {
50*4882a593Smuzhiyun 		acpi_os_printf("There is no method currently executing\n");
51*4882a593Smuzhiyun 		return;
52*4882a593Smuzhiyun 	}
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	/* Get and verify the breakpoint address */
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	address = strtoul(location, NULL, 16);
57*4882a593Smuzhiyun 	aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
58*4882a593Smuzhiyun 					walk_state->parser_state.aml_start);
59*4882a593Smuzhiyun 	if (address <= aml_offset) {
60*4882a593Smuzhiyun 		acpi_os_printf("Breakpoint %X is beyond current address %X\n",
61*4882a593Smuzhiyun 			       address, aml_offset);
62*4882a593Smuzhiyun 	}
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	/* Save breakpoint in current walk */
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	walk_state->user_breakpoint = address;
67*4882a593Smuzhiyun 	acpi_os_printf("Breakpoint set at AML offset %X\n", address);
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /*******************************************************************************
71*4882a593Smuzhiyun  *
72*4882a593Smuzhiyun  * FUNCTION:    acpi_db_set_method_call_breakpoint
73*4882a593Smuzhiyun  *
74*4882a593Smuzhiyun  * PARAMETERS:  op                  - Current Op (from parse walk)
75*4882a593Smuzhiyun  *
76*4882a593Smuzhiyun  * RETURN:      None
77*4882a593Smuzhiyun  *
78*4882a593Smuzhiyun  * DESCRIPTION: Set a breakpoint in a control method at the specified
79*4882a593Smuzhiyun  *              AML offset
80*4882a593Smuzhiyun  *
81*4882a593Smuzhiyun  ******************************************************************************/
82*4882a593Smuzhiyun 
acpi_db_set_method_call_breakpoint(union acpi_parse_object * op)83*4882a593Smuzhiyun void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	if (!op) {
87*4882a593Smuzhiyun 		acpi_os_printf("There is no method currently executing\n");
88*4882a593Smuzhiyun 		return;
89*4882a593Smuzhiyun 	}
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	acpi_gbl_step_to_next_call = TRUE;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun /*******************************************************************************
95*4882a593Smuzhiyun  *
96*4882a593Smuzhiyun  * FUNCTION:    acpi_db_set_method_data
97*4882a593Smuzhiyun  *
98*4882a593Smuzhiyun  * PARAMETERS:  type_arg        - L for local, A for argument
99*4882a593Smuzhiyun  *              index_arg       - which one
100*4882a593Smuzhiyun  *              value_arg       - Value to set.
101*4882a593Smuzhiyun  *
102*4882a593Smuzhiyun  * RETURN:      None
103*4882a593Smuzhiyun  *
104*4882a593Smuzhiyun  * DESCRIPTION: Set a local or argument for the running control method.
105*4882a593Smuzhiyun  *              NOTE: only object supported is Number.
106*4882a593Smuzhiyun  *
107*4882a593Smuzhiyun  ******************************************************************************/
108*4882a593Smuzhiyun 
acpi_db_set_method_data(char * type_arg,char * index_arg,char * value_arg)109*4882a593Smuzhiyun void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	char type;
112*4882a593Smuzhiyun 	u32 index;
113*4882a593Smuzhiyun 	u32 value;
114*4882a593Smuzhiyun 	struct acpi_walk_state *walk_state;
115*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
116*4882a593Smuzhiyun 	acpi_status status;
117*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	/* Validate type_arg */
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	acpi_ut_strupr(type_arg);
122*4882a593Smuzhiyun 	type = type_arg[0];
123*4882a593Smuzhiyun 	if ((type != 'L') && (type != 'A') && (type != 'N')) {
124*4882a593Smuzhiyun 		acpi_os_printf("Invalid SET operand: %s\n", type_arg);
125*4882a593Smuzhiyun 		return;
126*4882a593Smuzhiyun 	}
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	value = strtoul(value_arg, NULL, 16);
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	if (type == 'N') {
131*4882a593Smuzhiyun 		node = acpi_db_convert_to_node(index_arg);
132*4882a593Smuzhiyun 		if (!node) {
133*4882a593Smuzhiyun 			return;
134*4882a593Smuzhiyun 		}
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 		if (node->type != ACPI_TYPE_INTEGER) {
137*4882a593Smuzhiyun 			acpi_os_printf("Can only set Integer nodes\n");
138*4882a593Smuzhiyun 			return;
139*4882a593Smuzhiyun 		}
140*4882a593Smuzhiyun 		obj_desc = node->object;
141*4882a593Smuzhiyun 		obj_desc->integer.value = value;
142*4882a593Smuzhiyun 		return;
143*4882a593Smuzhiyun 	}
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	/* Get the index and value */
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	index = strtoul(index_arg, NULL, 16);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
150*4882a593Smuzhiyun 	if (!walk_state) {
151*4882a593Smuzhiyun 		acpi_os_printf("There is no method currently executing\n");
152*4882a593Smuzhiyun 		return;
153*4882a593Smuzhiyun 	}
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	/* Create and initialize the new object */
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	obj_desc = acpi_ut_create_integer_object((u64)value);
158*4882a593Smuzhiyun 	if (!obj_desc) {
159*4882a593Smuzhiyun 		acpi_os_printf("Could not create an internal object\n");
160*4882a593Smuzhiyun 		return;
161*4882a593Smuzhiyun 	}
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	/* Store the new object into the target */
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	switch (type) {
166*4882a593Smuzhiyun 	case 'A':
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 		/* Set a method argument */
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 		if (index > ACPI_METHOD_MAX_ARG) {
171*4882a593Smuzhiyun 			acpi_os_printf("Arg%u - Invalid argument name\n",
172*4882a593Smuzhiyun 				       index);
173*4882a593Smuzhiyun 			goto cleanup;
174*4882a593Smuzhiyun 		}
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 		status = acpi_ds_store_object_to_local(ACPI_REFCLASS_ARG,
177*4882a593Smuzhiyun 						       index, obj_desc,
178*4882a593Smuzhiyun 						       walk_state);
179*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
180*4882a593Smuzhiyun 			goto cleanup;
181*4882a593Smuzhiyun 		}
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 		obj_desc = walk_state->arguments[index].object;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 		acpi_os_printf("Arg%u: ", index);
186*4882a593Smuzhiyun 		acpi_db_display_internal_object(obj_desc, walk_state);
187*4882a593Smuzhiyun 		break;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	case 'L':
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 		/* Set a method local */
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 		if (index > ACPI_METHOD_MAX_LOCAL) {
194*4882a593Smuzhiyun 			acpi_os_printf
195*4882a593Smuzhiyun 			    ("Local%u - Invalid local variable name\n", index);
196*4882a593Smuzhiyun 			goto cleanup;
197*4882a593Smuzhiyun 		}
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 		status = acpi_ds_store_object_to_local(ACPI_REFCLASS_LOCAL,
200*4882a593Smuzhiyun 						       index, obj_desc,
201*4882a593Smuzhiyun 						       walk_state);
202*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
203*4882a593Smuzhiyun 			goto cleanup;
204*4882a593Smuzhiyun 		}
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 		obj_desc = walk_state->local_variables[index].object;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 		acpi_os_printf("Local%u: ", index);
209*4882a593Smuzhiyun 		acpi_db_display_internal_object(obj_desc, walk_state);
210*4882a593Smuzhiyun 		break;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	default:
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 		break;
215*4882a593Smuzhiyun 	}
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun cleanup:
218*4882a593Smuzhiyun 	acpi_ut_remove_reference(obj_desc);
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun #ifdef ACPI_DISASSEMBLER
222*4882a593Smuzhiyun /*******************************************************************************
223*4882a593Smuzhiyun  *
224*4882a593Smuzhiyun  * FUNCTION:    acpi_db_disassemble_aml
225*4882a593Smuzhiyun  *
226*4882a593Smuzhiyun  * PARAMETERS:  statements          - Number of statements to disassemble
227*4882a593Smuzhiyun  *              op                  - Current Op (from parse walk)
228*4882a593Smuzhiyun  *
229*4882a593Smuzhiyun  * RETURN:      None
230*4882a593Smuzhiyun  *
231*4882a593Smuzhiyun  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
232*4882a593Smuzhiyun  *              of statements specified.
233*4882a593Smuzhiyun  *
234*4882a593Smuzhiyun  ******************************************************************************/
235*4882a593Smuzhiyun 
acpi_db_disassemble_aml(char * statements,union acpi_parse_object * op)236*4882a593Smuzhiyun void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	u32 num_statements = 8;
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	if (!op) {
241*4882a593Smuzhiyun 		acpi_os_printf("There is no method currently executing\n");
242*4882a593Smuzhiyun 		return;
243*4882a593Smuzhiyun 	}
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	if (statements) {
246*4882a593Smuzhiyun 		num_statements = strtoul(statements, NULL, 0);
247*4882a593Smuzhiyun 	}
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	acpi_dm_disassemble(NULL, op, num_statements);
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun /*******************************************************************************
253*4882a593Smuzhiyun  *
254*4882a593Smuzhiyun  * FUNCTION:    acpi_db_disassemble_method
255*4882a593Smuzhiyun  *
256*4882a593Smuzhiyun  * PARAMETERS:  name            - Name of control method
257*4882a593Smuzhiyun  *
258*4882a593Smuzhiyun  * RETURN:      None
259*4882a593Smuzhiyun  *
260*4882a593Smuzhiyun  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
261*4882a593Smuzhiyun  *              of statements specified.
262*4882a593Smuzhiyun  *
263*4882a593Smuzhiyun  ******************************************************************************/
264*4882a593Smuzhiyun 
acpi_db_disassemble_method(char * name)265*4882a593Smuzhiyun acpi_status acpi_db_disassemble_method(char *name)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun 	acpi_status status;
268*4882a593Smuzhiyun 	union acpi_parse_object *op;
269*4882a593Smuzhiyun 	struct acpi_walk_state *walk_state;
270*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
271*4882a593Smuzhiyun 	struct acpi_namespace_node *method;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	method = acpi_db_convert_to_node(name);
274*4882a593Smuzhiyun 	if (!method) {
275*4882a593Smuzhiyun 		return (AE_BAD_PARAMETER);
276*4882a593Smuzhiyun 	}
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	if (method->type != ACPI_TYPE_METHOD) {
279*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO, "%s (%s): Object must be a control method",
280*4882a593Smuzhiyun 			    name, acpi_ut_get_type_name(method->type)));
281*4882a593Smuzhiyun 		return (AE_BAD_PARAMETER);
282*4882a593Smuzhiyun 	}
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	obj_desc = method->object;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	op = acpi_ps_create_scope_op(obj_desc->method.aml_start);
287*4882a593Smuzhiyun 	if (!op) {
288*4882a593Smuzhiyun 		return (AE_NO_MEMORY);
289*4882a593Smuzhiyun 	}
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	/* Create and initialize a new walk state */
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	walk_state = acpi_ds_create_walk_state(0, op, NULL, NULL);
294*4882a593Smuzhiyun 	if (!walk_state) {
295*4882a593Smuzhiyun 		return (AE_NO_MEMORY);
296*4882a593Smuzhiyun 	}
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	status = acpi_ds_init_aml_walk(walk_state, op, NULL,
299*4882a593Smuzhiyun 				       obj_desc->method.aml_start,
300*4882a593Smuzhiyun 				       obj_desc->method.aml_length, NULL,
301*4882a593Smuzhiyun 				       ACPI_IMODE_LOAD_PASS1);
302*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
303*4882a593Smuzhiyun 		return (status);
304*4882a593Smuzhiyun 	}
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
307*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
308*4882a593Smuzhiyun 		return (status);
309*4882a593Smuzhiyun 	}
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	walk_state->owner_id = obj_desc->method.owner_id;
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	/* Push start scope on scope stack and make it current */
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	status = acpi_ds_scope_stack_push(method, method->type, walk_state);
316*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
317*4882a593Smuzhiyun 		return (status);
318*4882a593Smuzhiyun 	}
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	/* Parse the entire method AML including deferred operators */
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	walk_state->parse_flags &= ~ACPI_PARSE_DELETE_TREE;
323*4882a593Smuzhiyun 	walk_state->parse_flags |= ACPI_PARSE_DISASSEMBLE;
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	status = acpi_ps_parse_aml(walk_state);
326*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
327*4882a593Smuzhiyun 		return (status);
328*4882a593Smuzhiyun 	}
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	(void)acpi_dm_parse_deferred_ops(op);
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	/* Now we can disassemble the method */
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	acpi_gbl_dm_opt_verbose = FALSE;
335*4882a593Smuzhiyun 	acpi_dm_disassemble(NULL, op, 0);
336*4882a593Smuzhiyun 	acpi_gbl_dm_opt_verbose = TRUE;
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	acpi_ps_delete_parse_tree(op);
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	/* Method cleanup */
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	acpi_ns_delete_namespace_subtree(method);
343*4882a593Smuzhiyun 	acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
344*4882a593Smuzhiyun 	acpi_ut_release_owner_id(&obj_desc->method.owner_id);
345*4882a593Smuzhiyun 	return (AE_OK);
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun #endif
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun /*******************************************************************************
350*4882a593Smuzhiyun  *
351*4882a593Smuzhiyun  * FUNCTION:    acpi_db_evaluate_object
352*4882a593Smuzhiyun  *
353*4882a593Smuzhiyun  * PARAMETERS:  node                - Namespace node for the object
354*4882a593Smuzhiyun  *
355*4882a593Smuzhiyun  * RETURN:      Status
356*4882a593Smuzhiyun  *
357*4882a593Smuzhiyun  * DESCRIPTION: Main execution function for the Evaluate/Execute/All debugger
358*4882a593Smuzhiyun  *              commands.
359*4882a593Smuzhiyun  *
360*4882a593Smuzhiyun  ******************************************************************************/
361*4882a593Smuzhiyun 
acpi_db_evaluate_object(struct acpi_namespace_node * node)362*4882a593Smuzhiyun static acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun 	char *pathname;
365*4882a593Smuzhiyun 	u32 i;
366*4882a593Smuzhiyun 	struct acpi_device_info *obj_info;
367*4882a593Smuzhiyun 	struct acpi_object_list param_objects;
368*4882a593Smuzhiyun 	union acpi_object params[ACPI_METHOD_NUM_ARGS];
369*4882a593Smuzhiyun 	struct acpi_buffer return_obj;
370*4882a593Smuzhiyun 	acpi_status status;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	pathname = acpi_ns_get_external_pathname(node);
373*4882a593Smuzhiyun 	if (!pathname) {
374*4882a593Smuzhiyun 		return (AE_OK);
375*4882a593Smuzhiyun 	}
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	/* Get the object info for number of method parameters */
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	status = acpi_get_object_info(node, &obj_info);
380*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
381*4882a593Smuzhiyun 		ACPI_FREE(pathname);
382*4882a593Smuzhiyun 		return (status);
383*4882a593Smuzhiyun 	}
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	param_objects.pointer = NULL;
386*4882a593Smuzhiyun 	param_objects.count = 0;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	if (obj_info->type == ACPI_TYPE_METHOD) {
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 		/* Setup default parameters */
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 		for (i = 0; i < obj_info->param_count; i++) {
393*4882a593Smuzhiyun 			params[i].type = ACPI_TYPE_INTEGER;
394*4882a593Smuzhiyun 			params[i].integer.value = 1;
395*4882a593Smuzhiyun 		}
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 		param_objects.pointer = params;
398*4882a593Smuzhiyun 		param_objects.count = obj_info->param_count;
399*4882a593Smuzhiyun 	}
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	ACPI_FREE(obj_info);
402*4882a593Smuzhiyun 	return_obj.pointer = NULL;
403*4882a593Smuzhiyun 	return_obj.length = ACPI_ALLOCATE_BUFFER;
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 	/* Do the actual method execution */
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	acpi_gbl_method_executing = TRUE;
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
410*4882a593Smuzhiyun 	acpi_gbl_method_executing = FALSE;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	acpi_os_printf("%-32s returned %s\n", pathname,
413*4882a593Smuzhiyun 		       acpi_format_exception(status));
414*4882a593Smuzhiyun 	if (return_obj.length) {
415*4882a593Smuzhiyun 		acpi_os_printf("Evaluation of %s returned object %p, "
416*4882a593Smuzhiyun 			       "external buffer length %X\n",
417*4882a593Smuzhiyun 			       pathname, return_obj.pointer,
418*4882a593Smuzhiyun 			       (u32)return_obj.length);
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 		acpi_db_dump_external_object(return_obj.pointer, 1);
421*4882a593Smuzhiyun 		acpi_os_printf("\n");
422*4882a593Smuzhiyun 	}
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	ACPI_FREE(pathname);
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	/* Ignore status from method execution */
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	return (AE_OK);
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	/* Update count, check if we have executed enough methods */
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun /*******************************************************************************
435*4882a593Smuzhiyun  *
436*4882a593Smuzhiyun  * FUNCTION:    acpi_db_walk_for_execute
437*4882a593Smuzhiyun  *
438*4882a593Smuzhiyun  * PARAMETERS:  Callback from walk_namespace
439*4882a593Smuzhiyun  *
440*4882a593Smuzhiyun  * RETURN:      Status
441*4882a593Smuzhiyun  *
442*4882a593Smuzhiyun  * DESCRIPTION: Batch execution function. Evaluates all "predefined" objects --
443*4882a593Smuzhiyun  *              the nameseg begins with an underscore.
444*4882a593Smuzhiyun  *
445*4882a593Smuzhiyun  ******************************************************************************/
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun static acpi_status
acpi_db_walk_for_execute(acpi_handle obj_handle,u32 nesting_level,void * context,void ** return_value)448*4882a593Smuzhiyun acpi_db_walk_for_execute(acpi_handle obj_handle,
449*4882a593Smuzhiyun 			 u32 nesting_level, void *context, void **return_value)
450*4882a593Smuzhiyun {
451*4882a593Smuzhiyun 	struct acpi_namespace_node *node =
452*4882a593Smuzhiyun 	    (struct acpi_namespace_node *)obj_handle;
453*4882a593Smuzhiyun 	struct acpi_db_execute_walk *info =
454*4882a593Smuzhiyun 	    (struct acpi_db_execute_walk *)context;
455*4882a593Smuzhiyun 	acpi_status status;
456*4882a593Smuzhiyun 	const union acpi_predefined_info *predefined;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	predefined = acpi_ut_match_predefined_method(node->name.ascii);
459*4882a593Smuzhiyun 	if (!predefined) {
460*4882a593Smuzhiyun 		return (AE_OK);
461*4882a593Smuzhiyun 	}
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
464*4882a593Smuzhiyun 		return (AE_OK);
465*4882a593Smuzhiyun 	}
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	acpi_db_evaluate_object(node);
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	/* Ignore status from object evaluation */
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 	status = AE_OK;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	/* Update count, check if we have executed enough methods */
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	info->count++;
476*4882a593Smuzhiyun 	if (info->count >= info->max_count) {
477*4882a593Smuzhiyun 		status = AE_CTRL_TERMINATE;
478*4882a593Smuzhiyun 	}
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	return (status);
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun /*******************************************************************************
484*4882a593Smuzhiyun  *
485*4882a593Smuzhiyun  * FUNCTION:    acpi_db_walk_for_execute_all
486*4882a593Smuzhiyun  *
487*4882a593Smuzhiyun  * PARAMETERS:  Callback from walk_namespace
488*4882a593Smuzhiyun  *
489*4882a593Smuzhiyun  * RETURN:      Status
490*4882a593Smuzhiyun  *
491*4882a593Smuzhiyun  * DESCRIPTION: Batch execution function. Evaluates all objects whose path ends
492*4882a593Smuzhiyun  *              with the nameseg "Info->NameSeg". Used for the "ALL" command.
493*4882a593Smuzhiyun  *
494*4882a593Smuzhiyun  ******************************************************************************/
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun static acpi_status
acpi_db_walk_for_execute_all(acpi_handle obj_handle,u32 nesting_level,void * context,void ** return_value)497*4882a593Smuzhiyun acpi_db_walk_for_execute_all(acpi_handle obj_handle,
498*4882a593Smuzhiyun 			     u32 nesting_level,
499*4882a593Smuzhiyun 			     void *context, void **return_value)
500*4882a593Smuzhiyun {
501*4882a593Smuzhiyun 	struct acpi_namespace_node *node =
502*4882a593Smuzhiyun 	    (struct acpi_namespace_node *)obj_handle;
503*4882a593Smuzhiyun 	struct acpi_db_execute_walk *info =
504*4882a593Smuzhiyun 	    (struct acpi_db_execute_walk *)context;
505*4882a593Smuzhiyun 	acpi_status status;
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	if (!ACPI_COMPARE_NAMESEG(node->name.ascii, info->name_seg)) {
508*4882a593Smuzhiyun 		return (AE_OK);
509*4882a593Smuzhiyun 	}
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
512*4882a593Smuzhiyun 		return (AE_OK);
513*4882a593Smuzhiyun 	}
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	/* Now evaluate the input object (node) */
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	acpi_db_evaluate_object(node);
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 	/* Ignore status from method execution */
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	status = AE_OK;
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	/* Update count of executed methods/objects */
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	info->count++;
526*4882a593Smuzhiyun 	return (status);
527*4882a593Smuzhiyun }
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun /*******************************************************************************
530*4882a593Smuzhiyun  *
531*4882a593Smuzhiyun  * FUNCTION:    acpi_db_evaluate_predefined_names
532*4882a593Smuzhiyun  *
533*4882a593Smuzhiyun  * PARAMETERS:  None
534*4882a593Smuzhiyun  *
535*4882a593Smuzhiyun  * RETURN:      None
536*4882a593Smuzhiyun  *
537*4882a593Smuzhiyun  * DESCRIPTION: Namespace batch execution. Execute predefined names in the
538*4882a593Smuzhiyun  *              namespace, up to the max count, if specified.
539*4882a593Smuzhiyun  *
540*4882a593Smuzhiyun  ******************************************************************************/
541*4882a593Smuzhiyun 
acpi_db_evaluate_predefined_names(void)542*4882a593Smuzhiyun void acpi_db_evaluate_predefined_names(void)
543*4882a593Smuzhiyun {
544*4882a593Smuzhiyun 	struct acpi_db_execute_walk info;
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 	info.count = 0;
547*4882a593Smuzhiyun 	info.max_count = ACPI_UINT32_MAX;
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	/* Search all nodes in namespace */
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
552*4882a593Smuzhiyun 				  ACPI_UINT32_MAX, acpi_db_walk_for_execute,
553*4882a593Smuzhiyun 				  NULL, (void *)&info, NULL);
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 	acpi_os_printf("Evaluated %u predefined names in the namespace\n",
556*4882a593Smuzhiyun 		       info.count);
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun /*******************************************************************************
560*4882a593Smuzhiyun  *
561*4882a593Smuzhiyun  * FUNCTION:    acpi_db_evaluate_all
562*4882a593Smuzhiyun  *
563*4882a593Smuzhiyun  * PARAMETERS:  none_acpi_gbl_db_method_info
564*4882a593Smuzhiyun  *
565*4882a593Smuzhiyun  * RETURN:      None
566*4882a593Smuzhiyun  *
567*4882a593Smuzhiyun  * DESCRIPTION: Namespace batch execution. Implements the "ALL" command.
568*4882a593Smuzhiyun  *              Execute all namepaths whose final nameseg matches the
569*4882a593Smuzhiyun  *              input nameseg.
570*4882a593Smuzhiyun  *
571*4882a593Smuzhiyun  ******************************************************************************/
572*4882a593Smuzhiyun 
acpi_db_evaluate_all(char * name_seg)573*4882a593Smuzhiyun void acpi_db_evaluate_all(char *name_seg)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	struct acpi_db_execute_walk info;
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	info.count = 0;
578*4882a593Smuzhiyun 	info.max_count = ACPI_UINT32_MAX;
579*4882a593Smuzhiyun 	ACPI_COPY_NAMESEG(info.name_seg, name_seg);
580*4882a593Smuzhiyun 	info.name_seg[ACPI_NAMESEG_SIZE] = 0;
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 	/* Search all nodes in namespace */
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
585*4882a593Smuzhiyun 				  ACPI_UINT32_MAX, acpi_db_walk_for_execute_all,
586*4882a593Smuzhiyun 				  NULL, (void *)&info, NULL);
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	acpi_os_printf("Evaluated %u names in the namespace\n", info.count);
589*4882a593Smuzhiyun }
590