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