Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: dbobject - ACPI object decode and display
4
 *
5
 ******************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2015, 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 
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
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
 
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) \"%.24s",
146
			       obj_desc->string.length,
147
			       obj_desc->string.pointer);
148
 
149
		if (obj_desc->string.length > 24) {
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
 
183
static void acpi_db_decode_node(struct acpi_namespace_node *node)
184
{
185
 
186
	acpi_os_printf("          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
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("\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(" ");
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("          ");
389
			acpi_db_decode_internal_object(obj_desc);
390
			break;
391
		}
392
		break;
393
 
394
	default:
395
 
396
		acpi_os_printf(" [%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
 
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
 
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
}