Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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
 50ACPI_MODULE_NAME("dbobject")
 51
 52/* Local prototypes */
 53static 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
 70void
 71acpi_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
119void 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
183static 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
231void
232acpi_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
416void 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
481void 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}