• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  *
3  * Module Name: dbobject - ACPI object decode and display
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acnamesp.h"
47 #include "acdebug.h"
48 
49 #define _COMPONENT          ACPI_CA_DEBUGGER
50 ACPI_MODULE_NAME("dbobject")
51 
52 /* Local prototypes */
53 static void acpi_db_decode_node(struct acpi_namespace_node *node);
54 
55 /*******************************************************************************
56  *
57  * FUNCTION:    acpi_db_dump_method_info
58  *
59  * PARAMETERS:  status          - Method execution status
60  *              walk_state      - Current state of the parse tree walk
61  *
62  * RETURN:      None
63  *
64  * DESCRIPTION: Called when a method has been aborted because of an error.
65  *              Dumps the method execution stack, and the method locals/args,
66  *              and disassembles the AML opcode that failed.
67  *
68  ******************************************************************************/
69 
70 void
acpi_db_dump_method_info(acpi_status status,struct acpi_walk_state * walk_state)71 acpi_db_dump_method_info(acpi_status status, struct acpi_walk_state *walk_state)
72 {
73 	struct acpi_thread_state *thread;
74 
75 	/* Ignore control codes, they are not errors */
76 
77 	if ((status & AE_CODE_MASK) == AE_CODE_CONTROL) {
78 		return;
79 	}
80 
81 	/* We may be executing a deferred opcode */
82 
83 	if (walk_state->deferred_node) {
84 		acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
85 		return;
86 	}
87 
88 	/*
89 	 * If there is no Thread, we are not actually executing a method.
90 	 * This can happen when the iASL compiler calls the interpreter
91 	 * to perform constant folding.
92 	 */
93 	thread = walk_state->thread;
94 	if (!thread) {
95 		return;
96 	}
97 
98 	/* Display the method locals and arguments */
99 
100 	acpi_os_printf("\n");
101 	acpi_db_decode_locals(walk_state);
102 	acpi_os_printf("\n");
103 	acpi_db_decode_arguments(walk_state);
104 	acpi_os_printf("\n");
105 }
106 
107 /*******************************************************************************
108  *
109  * FUNCTION:    acpi_db_decode_internal_object
110  *
111  * PARAMETERS:  obj_desc        - Object to be displayed
112  *
113  * RETURN:      None
114  *
115  * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
116  *
117  ******************************************************************************/
118 
acpi_db_decode_internal_object(union acpi_operand_object * obj_desc)119 void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc)
120 {
121 	u32 i;
122 
123 	if (!obj_desc) {
124 		acpi_os_printf(" Uninitialized");
125 		return;
126 	}
127 
128 	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
129 		acpi_os_printf(" %p [%s]", obj_desc,
130 			       acpi_ut_get_descriptor_name(obj_desc));
131 		return;
132 	}
133 
134 	acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc));
135 
136 	switch (obj_desc->common.type) {
137 	case ACPI_TYPE_INTEGER:
138 
139 		acpi_os_printf(" %8.8X%8.8X",
140 			       ACPI_FORMAT_UINT64(obj_desc->integer.value));
141 		break;
142 
143 	case ACPI_TYPE_STRING:
144 
145 		acpi_os_printf("(%u) \"%.60s",
146 			       obj_desc->string.length,
147 			       obj_desc->string.pointer);
148 
149 		if (obj_desc->string.length > 60) {
150 			acpi_os_printf("...");
151 		} else {
152 			acpi_os_printf("\"");
153 		}
154 		break;
155 
156 	case ACPI_TYPE_BUFFER:
157 
158 		acpi_os_printf("(%u)", obj_desc->buffer.length);
159 		for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) {
160 			acpi_os_printf(" %2.2X", obj_desc->buffer.pointer[i]);
161 		}
162 		break;
163 
164 	default:
165 
166 		acpi_os_printf(" %p", obj_desc);
167 		break;
168 	}
169 }
170 
171 /*******************************************************************************
172  *
173  * FUNCTION:    acpi_db_decode_node
174  *
175  * PARAMETERS:  node        - Object to be displayed
176  *
177  * RETURN:      None
178  *
179  * DESCRIPTION: Short display of a namespace node
180  *
181  ******************************************************************************/
182 
acpi_db_decode_node(struct acpi_namespace_node * node)183 static void acpi_db_decode_node(struct acpi_namespace_node *node)
184 {
185 
186 	acpi_os_printf("<Node>          Name %4.4s",
187 		       acpi_ut_get_node_name(node));
188 
189 	if (node->flags & ANOBJ_METHOD_ARG) {
190 		acpi_os_printf(" [Method Arg]");
191 	}
192 	if (node->flags & ANOBJ_METHOD_LOCAL) {
193 		acpi_os_printf(" [Method Local]");
194 	}
195 
196 	switch (node->type) {
197 
198 		/* These types have no attached object */
199 
200 	case ACPI_TYPE_DEVICE:
201 
202 		acpi_os_printf(" Device");
203 		break;
204 
205 	case ACPI_TYPE_THERMAL:
206 
207 		acpi_os_printf(" Thermal Zone");
208 		break;
209 
210 	default:
211 
212 		acpi_db_decode_internal_object(acpi_ns_get_attached_object
213 					       (node));
214 		break;
215 	}
216 }
217 
218 /*******************************************************************************
219  *
220  * FUNCTION:    acpi_db_display_internal_object
221  *
222  * PARAMETERS:  obj_desc        - Object to be displayed
223  *              walk_state      - Current walk state
224  *
225  * RETURN:      None
226  *
227  * DESCRIPTION: Short display of an internal object
228  *
229  ******************************************************************************/
230 
231 void
acpi_db_display_internal_object(union acpi_operand_object * obj_desc,struct acpi_walk_state * walk_state)232 acpi_db_display_internal_object(union acpi_operand_object *obj_desc,
233 				struct acpi_walk_state *walk_state)
234 {
235 	u8 type;
236 
237 	acpi_os_printf("%p ", obj_desc);
238 
239 	if (!obj_desc) {
240 		acpi_os_printf("<Null Object>\n");
241 		return;
242 	}
243 
244 	/* Decode the object type */
245 
246 	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
247 	case ACPI_DESC_TYPE_PARSER:
248 
249 		acpi_os_printf("<Parser> ");
250 		break;
251 
252 	case ACPI_DESC_TYPE_NAMED:
253 
254 		acpi_db_decode_node((struct acpi_namespace_node *)obj_desc);
255 		break;
256 
257 	case ACPI_DESC_TYPE_OPERAND:
258 
259 		type = obj_desc->common.type;
260 		if (type > ACPI_TYPE_LOCAL_MAX) {
261 			acpi_os_printf(" Type %X [Invalid Type]", (u32)type);
262 			return;
263 		}
264 
265 		/* Decode the ACPI object type */
266 
267 		switch (obj_desc->common.type) {
268 		case ACPI_TYPE_LOCAL_REFERENCE:
269 
270 			acpi_os_printf("[%s] ",
271 				       acpi_ut_get_reference_name(obj_desc));
272 
273 			/* Decode the refererence */
274 
275 			switch (obj_desc->reference.class) {
276 			case ACPI_REFCLASS_LOCAL:
277 
278 				acpi_os_printf("%X ",
279 					       obj_desc->reference.value);
280 				if (walk_state) {
281 					obj_desc = walk_state->local_variables
282 					    [obj_desc->reference.value].object;
283 					acpi_os_printf("%p", obj_desc);
284 					acpi_db_decode_internal_object
285 					    (obj_desc);
286 				}
287 				break;
288 
289 			case ACPI_REFCLASS_ARG:
290 
291 				acpi_os_printf("%X ",
292 					       obj_desc->reference.value);
293 				if (walk_state) {
294 					obj_desc = walk_state->arguments
295 					    [obj_desc->reference.value].object;
296 					acpi_os_printf("%p", obj_desc);
297 					acpi_db_decode_internal_object
298 					    (obj_desc);
299 				}
300 				break;
301 
302 			case ACPI_REFCLASS_INDEX:
303 
304 				switch (obj_desc->reference.target_type) {
305 				case ACPI_TYPE_BUFFER_FIELD:
306 
307 					acpi_os_printf("%p",
308 						       obj_desc->reference.
309 						       object);
310 					acpi_db_decode_internal_object
311 					    (obj_desc->reference.object);
312 					break;
313 
314 				case ACPI_TYPE_PACKAGE:
315 
316 					acpi_os_printf("%p",
317 						       obj_desc->reference.
318 						       where);
319 					if (!obj_desc->reference.where) {
320 						acpi_os_printf
321 						    (" Uninitialized WHERE pointer");
322 					} else {
323 						acpi_db_decode_internal_object(*
324 									       (obj_desc->
325 										reference.
326 										where));
327 					}
328 					break;
329 
330 				default:
331 
332 					acpi_os_printf
333 					    ("Unknown index target type");
334 					break;
335 				}
336 				break;
337 
338 			case ACPI_REFCLASS_REFOF:
339 
340 				if (!obj_desc->reference.object) {
341 					acpi_os_printf
342 					    ("Uninitialized reference subobject pointer");
343 					break;
344 				}
345 
346 				/* Reference can be to a Node or an Operand object */
347 
348 				switch (ACPI_GET_DESCRIPTOR_TYPE
349 					(obj_desc->reference.object)) {
350 				case ACPI_DESC_TYPE_NAMED:
351 
352 					acpi_db_decode_node(obj_desc->reference.
353 							    object);
354 					break;
355 
356 				case ACPI_DESC_TYPE_OPERAND:
357 
358 					acpi_db_decode_internal_object
359 					    (obj_desc->reference.object);
360 					break;
361 
362 				default:
363 					break;
364 				}
365 				break;
366 
367 			case ACPI_REFCLASS_NAME:
368 
369 				acpi_db_decode_node(obj_desc->reference.node);
370 				break;
371 
372 			case ACPI_REFCLASS_DEBUG:
373 			case ACPI_REFCLASS_TABLE:
374 
375 				acpi_os_printf("\n");
376 				break;
377 
378 			default:	/* Unknown reference class */
379 
380 				acpi_os_printf("%2.2X\n",
381 					       obj_desc->reference.class);
382 				break;
383 			}
384 			break;
385 
386 		default:
387 
388 			acpi_os_printf("<Obj>          ");
389 			acpi_db_decode_internal_object(obj_desc);
390 			break;
391 		}
392 		break;
393 
394 	default:
395 
396 		acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]",
397 			       acpi_ut_get_descriptor_name(obj_desc));
398 		break;
399 	}
400 
401 	acpi_os_printf("\n");
402 }
403 
404 /*******************************************************************************
405  *
406  * FUNCTION:    acpi_db_decode_locals
407  *
408  * PARAMETERS:  walk_state      - State for current method
409  *
410  * RETURN:      None
411  *
412  * DESCRIPTION: Display all locals for the currently running control method
413  *
414  ******************************************************************************/
415 
acpi_db_decode_locals(struct acpi_walk_state * walk_state)416 void acpi_db_decode_locals(struct acpi_walk_state *walk_state)
417 {
418 	u32 i;
419 	union acpi_operand_object *obj_desc;
420 	struct acpi_namespace_node *node;
421 	u8 display_locals = FALSE;
422 
423 	obj_desc = walk_state->method_desc;
424 	node = walk_state->method_node;
425 
426 	if (!node) {
427 		acpi_os_printf
428 		    ("No method node (Executing subtree for buffer or opregion)\n");
429 		return;
430 	}
431 
432 	if (node->type != ACPI_TYPE_METHOD) {
433 		acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
434 		return;
435 	}
436 
437 	/* Are any locals actually set? */
438 
439 	for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
440 		obj_desc = walk_state->local_variables[i].object;
441 		if (obj_desc) {
442 			display_locals = TRUE;
443 			break;
444 		}
445 	}
446 
447 	/* If any are set, only display the ones that are set */
448 
449 	if (display_locals) {
450 		acpi_os_printf
451 		    ("\nInitialized Local Variables for method [%4.4s]:\n",
452 		     acpi_ut_get_node_name(node));
453 
454 		for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
455 			obj_desc = walk_state->local_variables[i].object;
456 			if (obj_desc) {
457 				acpi_os_printf("  Local%X: ", i);
458 				acpi_db_display_internal_object(obj_desc,
459 								walk_state);
460 			}
461 		}
462 	} else {
463 		acpi_os_printf
464 		    ("No Local Variables are initialized for method [%4.4s]\n",
465 		     acpi_ut_get_node_name(node));
466 	}
467 }
468 
469 /*******************************************************************************
470  *
471  * FUNCTION:    acpi_db_decode_arguments
472  *
473  * PARAMETERS:  walk_state      - State for current method
474  *
475  * RETURN:      None
476  *
477  * DESCRIPTION: Display all arguments for the currently running control method
478  *
479  ******************************************************************************/
480 
acpi_db_decode_arguments(struct acpi_walk_state * walk_state)481 void acpi_db_decode_arguments(struct acpi_walk_state *walk_state)
482 {
483 	u32 i;
484 	union acpi_operand_object *obj_desc;
485 	struct acpi_namespace_node *node;
486 	u8 display_args = FALSE;
487 
488 	node = walk_state->method_node;
489 	obj_desc = walk_state->method_desc;
490 
491 	if (!node) {
492 		acpi_os_printf
493 		    ("No method node (Executing subtree for buffer or opregion)\n");
494 		return;
495 	}
496 
497 	if (node->type != ACPI_TYPE_METHOD) {
498 		acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
499 		return;
500 	}
501 
502 	/* Are any arguments actually set? */
503 
504 	for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
505 		obj_desc = walk_state->arguments[i].object;
506 		if (obj_desc) {
507 			display_args = TRUE;
508 			break;
509 		}
510 	}
511 
512 	/* If any are set, only display the ones that are set */
513 
514 	if (display_args) {
515 		acpi_os_printf("Initialized Arguments for Method [%4.4s]:  "
516 			       "(%X arguments defined for method invocation)\n",
517 			       acpi_ut_get_node_name(node),
518 			       obj_desc->method.param_count);
519 
520 		for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
521 			obj_desc = walk_state->arguments[i].object;
522 			if (obj_desc) {
523 				acpi_os_printf("  Arg%u:   ", i);
524 				acpi_db_display_internal_object(obj_desc,
525 								walk_state);
526 			}
527 		}
528 	} else {
529 		acpi_os_printf
530 		    ("No Arguments are initialized for method [%4.4s]\n",
531 		     acpi_ut_get_node_name(node));
532 	}
533 }
534