GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / acpi / acpica / dbobject.c
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 ((status & AE_CODE_MASK) == AE_CODE_CONTROL) {
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 refererence */
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         obj_desc = walk_state->method_desc;
398
399         /* There are no locals for the module-level code case */
400
401         if (node == acpi_gbl_root_node) {
402                 return;
403         }
404
405         if (!node) {
406                 acpi_os_printf
407                     ("No method node (Executing subtree for buffer or opregion)\n");
408                 return;
409         }
410
411         if (node->type != ACPI_TYPE_METHOD) {
412                 acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
413                 return;
414         }
415
416         /* Are any locals actually set? */
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                         display_locals = TRUE;
422                         break;
423                 }
424         }
425
426         /* If any are set, only display the ones that are set */
427
428         if (display_locals) {
429                 acpi_os_printf
430                     ("\nInitialized Local Variables for Method [%4.4s]:\n",
431                      acpi_ut_get_node_name(node));
432
433                 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
434                         obj_desc = walk_state->local_variables[i].object;
435                         if (obj_desc) {
436                                 acpi_os_printf("  Local%X: ", i);
437                                 acpi_db_display_internal_object(obj_desc,
438                                                                 walk_state);
439                         }
440                 }
441         } else {
442                 acpi_os_printf
443                     ("No Local Variables are initialized for Method [%4.4s]\n",
444                      acpi_ut_get_node_name(node));
445         }
446 }
447
448 /*******************************************************************************
449  *
450  * FUNCTION:    acpi_db_decode_arguments
451  *
452  * PARAMETERS:  walk_state      - State for current method
453  *
454  * RETURN:      None
455  *
456  * DESCRIPTION: Display all arguments for the currently running control method
457  *
458  ******************************************************************************/
459
460 void acpi_db_decode_arguments(struct acpi_walk_state *walk_state)
461 {
462         u32 i;
463         union acpi_operand_object *obj_desc;
464         struct acpi_namespace_node *node;
465         u8 display_args = FALSE;
466
467         node = walk_state->method_node;
468         obj_desc = walk_state->method_desc;
469
470         /* There are no arguments for the module-level code case */
471
472         if (node == acpi_gbl_root_node) {
473                 return;
474         }
475
476         if (!node) {
477                 acpi_os_printf
478                     ("No method node (Executing subtree for buffer or opregion)\n");
479                 return;
480         }
481
482         if (node->type != ACPI_TYPE_METHOD) {
483                 acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
484                 return;
485         }
486
487         /* Are any arguments actually set? */
488
489         for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
490                 obj_desc = walk_state->arguments[i].object;
491                 if (obj_desc) {
492                         display_args = TRUE;
493                         break;
494                 }
495         }
496
497         /* If any are set, only display the ones that are set */
498
499         if (display_args) {
500                 acpi_os_printf("Initialized Arguments for Method [%4.4s]:  "
501                                "(%X arguments defined for method invocation)\n",
502                                acpi_ut_get_node_name(node),
503                                node->object->method.param_count);
504
505                 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
506                         obj_desc = walk_state->arguments[i].object;
507                         if (obj_desc) {
508                                 acpi_os_printf("  Arg%u:   ", i);
509                                 acpi_db_display_internal_object(obj_desc,
510                                                                 walk_state);
511                         }
512                 }
513         } else {
514                 acpi_os_printf
515                     ("No Arguments are initialized for method [%4.4s]\n",
516                      acpi_ut_get_node_name(node));
517         }
518 }