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, ¶m_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