xref: /openbmc/linux/drivers/acpi/acpica/dbobject.c (revision 137c0118)
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: dbobject - ACPI object decode and display
5  *
6  ******************************************************************************/
7 
8 #include <acpi/acpi.h>
9 #include "accommon.h"
10 #include "acnamesp.h"
11 #include "acdebug.h"
12 
13 #define _COMPONENT          ACPI_CA_DEBUGGER
14 ACPI_MODULE_NAME("dbobject")
15 
16 /* Local prototypes */
17 static void acpi_db_decode_node(struct acpi_namespace_node *node);
18 
19 /*******************************************************************************
20  *
21  * FUNCTION:    acpi_db_dump_method_info
22  *
23  * PARAMETERS:  status          - Method execution status
24  *              walk_state      - Current state of the parse tree walk
25  *
26  * RETURN:      None
27  *
28  * DESCRIPTION: Called when a method has been aborted because of an error.
29  *              Dumps the method execution stack, and the method locals/args,
30  *              and disassembles the AML opcode that failed.
31  *
32  ******************************************************************************/
33 
34 void
35 acpi_db_dump_method_info(acpi_status status, struct acpi_walk_state *walk_state)
36 {
37 	struct acpi_thread_state *thread;
38 
39 	/* Ignore control codes, they are not errors */
40 
41 	if ((status & AE_CODE_MASK) == AE_CODE_CONTROL) {
42 		return;
43 	}
44 
45 	/* We may be executing a deferred opcode */
46 
47 	if (walk_state->deferred_node) {
48 		acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
49 		return;
50 	}
51 
52 	/*
53 	 * If there is no Thread, we are not actually executing a method.
54 	 * This can happen when the iASL compiler calls the interpreter
55 	 * to perform constant folding.
56 	 */
57 	thread = walk_state->thread;
58 	if (!thread) {
59 		return;
60 	}
61 
62 	/* Display the method locals and arguments */
63 
64 	acpi_os_printf("\n");
65 	acpi_db_decode_locals(walk_state);
66 	acpi_os_printf("\n");
67 	acpi_db_decode_arguments(walk_state);
68 	acpi_os_printf("\n");
69 }
70 
71 /*******************************************************************************
72  *
73  * FUNCTION:    acpi_db_decode_internal_object
74  *
75  * PARAMETERS:  obj_desc        - Object to be displayed
76  *
77  * RETURN:      None
78  *
79  * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
80  *
81  ******************************************************************************/
82 
83 void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc)
84 {
85 	u32 i;
86 
87 	if (!obj_desc) {
88 		acpi_os_printf(" Uninitialized");
89 		return;
90 	}
91 
92 	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
93 		acpi_os_printf(" %p [%s]", obj_desc,
94 			       acpi_ut_get_descriptor_name(obj_desc));
95 		return;
96 	}
97 
98 	acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc));
99 
100 	switch (obj_desc->common.type) {
101 	case ACPI_TYPE_INTEGER:
102 
103 		acpi_os_printf(" %8.8X%8.8X",
104 			       ACPI_FORMAT_UINT64(obj_desc->integer.value));
105 		break;
106 
107 	case ACPI_TYPE_STRING:
108 
109 		acpi_os_printf("(%u) \"%.60s",
110 			       obj_desc->string.length,
111 			       obj_desc->string.pointer);
112 
113 		if (obj_desc->string.length > 60) {
114 			acpi_os_printf("...");
115 		} else {
116 			acpi_os_printf("\"");
117 		}
118 		break;
119 
120 	case ACPI_TYPE_BUFFER:
121 
122 		acpi_os_printf("(%u)", obj_desc->buffer.length);
123 		for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) {
124 			acpi_os_printf(" %2.2X", obj_desc->buffer.pointer[i]);
125 		}
126 		break;
127 
128 	default:
129 
130 		acpi_os_printf(" %p", obj_desc);
131 		break;
132 	}
133 }
134 
135 /*******************************************************************************
136  *
137  * FUNCTION:    acpi_db_decode_node
138  *
139  * PARAMETERS:  node        - Object to be displayed
140  *
141  * RETURN:      None
142  *
143  * DESCRIPTION: Short display of a namespace node
144  *
145  ******************************************************************************/
146 
147 static void acpi_db_decode_node(struct acpi_namespace_node *node)
148 {
149 
150 	acpi_os_printf("<Node>          Name %4.4s",
151 		       acpi_ut_get_node_name(node));
152 
153 	if (node->flags & ANOBJ_METHOD_ARG) {
154 		acpi_os_printf(" [Method Arg]");
155 	}
156 	if (node->flags & ANOBJ_METHOD_LOCAL) {
157 		acpi_os_printf(" [Method Local]");
158 	}
159 
160 	switch (node->type) {
161 
162 		/* These types have no attached object */
163 
164 	case ACPI_TYPE_DEVICE:
165 
166 		acpi_os_printf(" Device");
167 		break;
168 
169 	case ACPI_TYPE_THERMAL:
170 
171 		acpi_os_printf(" Thermal Zone");
172 		break;
173 
174 	default:
175 
176 		acpi_db_decode_internal_object(acpi_ns_get_attached_object
177 					       (node));
178 		break;
179 	}
180 }
181 
182 /*******************************************************************************
183  *
184  * FUNCTION:    acpi_db_display_internal_object
185  *
186  * PARAMETERS:  obj_desc        - Object to be displayed
187  *              walk_state      - Current walk state
188  *
189  * RETURN:      None
190  *
191  * DESCRIPTION: Short display of an internal object
192  *
193  ******************************************************************************/
194 
195 void
196 acpi_db_display_internal_object(union acpi_operand_object *obj_desc,
197 				struct acpi_walk_state *walk_state)
198 {
199 	u8 type;
200 
201 	acpi_os_printf("%p ", obj_desc);
202 
203 	if (!obj_desc) {
204 		acpi_os_printf("<Null Object>\n");
205 		return;
206 	}
207 
208 	/* Decode the object type */
209 
210 	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
211 	case ACPI_DESC_TYPE_PARSER:
212 
213 		acpi_os_printf("<Parser> ");
214 		break;
215 
216 	case ACPI_DESC_TYPE_NAMED:
217 
218 		acpi_db_decode_node((struct acpi_namespace_node *)obj_desc);
219 		break;
220 
221 	case ACPI_DESC_TYPE_OPERAND:
222 
223 		type = obj_desc->common.type;
224 		if (type > ACPI_TYPE_LOCAL_MAX) {
225 			acpi_os_printf(" Type %X [Invalid Type]", (u32)type);
226 			return;
227 		}
228 
229 		/* Decode the ACPI object type */
230 
231 		switch (obj_desc->common.type) {
232 		case ACPI_TYPE_LOCAL_REFERENCE:
233 
234 			acpi_os_printf("[%s] ",
235 				       acpi_ut_get_reference_name(obj_desc));
236 
237 			/* Decode the refererence */
238 
239 			switch (obj_desc->reference.class) {
240 			case ACPI_REFCLASS_LOCAL:
241 
242 				acpi_os_printf("%X ",
243 					       obj_desc->reference.value);
244 				if (walk_state) {
245 					obj_desc = walk_state->local_variables
246 					    [obj_desc->reference.value].object;
247 					acpi_os_printf("%p", obj_desc);
248 					acpi_db_decode_internal_object
249 					    (obj_desc);
250 				}
251 				break;
252 
253 			case ACPI_REFCLASS_ARG:
254 
255 				acpi_os_printf("%X ",
256 					       obj_desc->reference.value);
257 				if (walk_state) {
258 					obj_desc = walk_state->arguments
259 					    [obj_desc->reference.value].object;
260 					acpi_os_printf("%p", obj_desc);
261 					acpi_db_decode_internal_object
262 					    (obj_desc);
263 				}
264 				break;
265 
266 			case ACPI_REFCLASS_INDEX:
267 
268 				switch (obj_desc->reference.target_type) {
269 				case ACPI_TYPE_BUFFER_FIELD:
270 
271 					acpi_os_printf("%p",
272 						       obj_desc->reference.
273 						       object);
274 					acpi_db_decode_internal_object
275 					    (obj_desc->reference.object);
276 					break;
277 
278 				case ACPI_TYPE_PACKAGE:
279 
280 					acpi_os_printf("%p",
281 						       obj_desc->reference.
282 						       where);
283 					if (!obj_desc->reference.where) {
284 						acpi_os_printf
285 						    (" Uninitialized WHERE pointer");
286 					} else {
287 						acpi_db_decode_internal_object(*
288 									       (obj_desc->
289 										reference.
290 										where));
291 					}
292 					break;
293 
294 				default:
295 
296 					acpi_os_printf
297 					    ("Unknown index target type");
298 					break;
299 				}
300 				break;
301 
302 			case ACPI_REFCLASS_REFOF:
303 
304 				if (!obj_desc->reference.object) {
305 					acpi_os_printf
306 					    ("Uninitialized reference subobject pointer");
307 					break;
308 				}
309 
310 				/* Reference can be to a Node or an Operand object */
311 
312 				switch (ACPI_GET_DESCRIPTOR_TYPE
313 					(obj_desc->reference.object)) {
314 				case ACPI_DESC_TYPE_NAMED:
315 
316 					acpi_db_decode_node(obj_desc->reference.
317 							    object);
318 					break;
319 
320 				case ACPI_DESC_TYPE_OPERAND:
321 
322 					acpi_db_decode_internal_object
323 					    (obj_desc->reference.object);
324 					break;
325 
326 				default:
327 					break;
328 				}
329 				break;
330 
331 			case ACPI_REFCLASS_NAME:
332 
333 				acpi_db_decode_node(obj_desc->reference.node);
334 				break;
335 
336 			case ACPI_REFCLASS_DEBUG:
337 			case ACPI_REFCLASS_TABLE:
338 
339 				acpi_os_printf("\n");
340 				break;
341 
342 			default:	/* Unknown reference class */
343 
344 				acpi_os_printf("%2.2X\n",
345 					       obj_desc->reference.class);
346 				break;
347 			}
348 			break;
349 
350 		default:
351 
352 			acpi_os_printf("<Obj>          ");
353 			acpi_db_decode_internal_object(obj_desc);
354 			break;
355 		}
356 		break;
357 
358 	default:
359 
360 		acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]",
361 			       acpi_ut_get_descriptor_name(obj_desc));
362 		break;
363 	}
364 
365 	acpi_os_printf("\n");
366 }
367 
368 /*******************************************************************************
369  *
370  * FUNCTION:    acpi_db_decode_locals
371  *
372  * PARAMETERS:  walk_state      - State for current method
373  *
374  * RETURN:      None
375  *
376  * DESCRIPTION: Display all locals for the currently running control method
377  *
378  ******************************************************************************/
379 
380 void acpi_db_decode_locals(struct acpi_walk_state *walk_state)
381 {
382 	u32 i;
383 	union acpi_operand_object *obj_desc;
384 	struct acpi_namespace_node *node;
385 	u8 display_locals = FALSE;
386 
387 	obj_desc = walk_state->method_desc;
388 	node = walk_state->method_node;
389 
390 	if (!node) {
391 		acpi_os_printf
392 		    ("No method node (Executing subtree for buffer or opregion)\n");
393 		return;
394 	}
395 
396 	if (node->type != ACPI_TYPE_METHOD) {
397 		acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
398 		return;
399 	}
400 
401 	/* Are any locals actually set? */
402 
403 	for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
404 		obj_desc = walk_state->local_variables[i].object;
405 		if (obj_desc) {
406 			display_locals = TRUE;
407 			break;
408 		}
409 	}
410 
411 	/* If any are set, only display the ones that are set */
412 
413 	if (display_locals) {
414 		acpi_os_printf
415 		    ("\nInitialized Local Variables for Method [%4.4s]:\n",
416 		     acpi_ut_get_node_name(node));
417 
418 		for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
419 			obj_desc = walk_state->local_variables[i].object;
420 			if (obj_desc) {
421 				acpi_os_printf("  Local%X: ", i);
422 				acpi_db_display_internal_object(obj_desc,
423 								walk_state);
424 			}
425 		}
426 	} else {
427 		acpi_os_printf
428 		    ("No Local Variables are initialized for Method [%4.4s]\n",
429 		     acpi_ut_get_node_name(node));
430 	}
431 }
432 
433 /*******************************************************************************
434  *
435  * FUNCTION:    acpi_db_decode_arguments
436  *
437  * PARAMETERS:  walk_state      - State for current method
438  *
439  * RETURN:      None
440  *
441  * DESCRIPTION: Display all arguments for the currently running control method
442  *
443  ******************************************************************************/
444 
445 void acpi_db_decode_arguments(struct acpi_walk_state *walk_state)
446 {
447 	u32 i;
448 	union acpi_operand_object *obj_desc;
449 	struct acpi_namespace_node *node;
450 	u8 display_args = FALSE;
451 
452 	node = walk_state->method_node;
453 	obj_desc = walk_state->method_desc;
454 
455 	if (!node) {
456 		acpi_os_printf
457 		    ("No method node (Executing subtree for buffer or opregion)\n");
458 		return;
459 	}
460 
461 	if (node->type != ACPI_TYPE_METHOD) {
462 		acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
463 		return;
464 	}
465 
466 	/* Are any arguments actually set? */
467 
468 	for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
469 		obj_desc = walk_state->arguments[i].object;
470 		if (obj_desc) {
471 			display_args = TRUE;
472 			break;
473 		}
474 	}
475 
476 	/* If any are set, only display the ones that are set */
477 
478 	if (display_args) {
479 		acpi_os_printf("Initialized Arguments for Method [%4.4s]:  "
480 			       "(%X arguments defined for method invocation)\n",
481 			       acpi_ut_get_node_name(node),
482 			       node->object->method.param_count);
483 
484 		for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
485 			obj_desc = walk_state->arguments[i].object;
486 			if (obj_desc) {
487 				acpi_os_printf("  Arg%u:   ", i);
488 				acpi_db_display_internal_object(obj_desc,
489 								walk_state);
490 			}
491 		}
492 	} else {
493 		acpi_os_printf
494 		    ("No Arguments are initialized for method [%4.4s]\n",
495 		     acpi_ut_get_node_name(node));
496 	}
497 }
498