1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
4 * Module Name: dbobject - ACPI object decode and display
6 ******************************************************************************/
13 #define _COMPONENT ACPI_CA_DEBUGGER
14 ACPI_MODULE_NAME("dbobject")
16 /* Local prototypes */
17 static void acpi_db_decode_node(struct acpi_namespace_node
*node
);
19 /*******************************************************************************
21 * FUNCTION: acpi_db_dump_method_info
23 * PARAMETERS: status - Method execution status
24 * walk_state - Current state of the parse tree walk
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.
32 ******************************************************************************/
35 acpi_db_dump_method_info(acpi_status status
, struct acpi_walk_state
*walk_state
)
37 struct acpi_thread_state
*thread
;
38 struct acpi_namespace_node
*node
;
40 node
= walk_state
->method_node
;
42 /* There are no locals or arguments for the module-level code case */
44 if (node
== acpi_gbl_root_node
) {
48 /* Ignore control codes, they are not errors */
50 if ((status
& AE_CODE_MASK
) == AE_CODE_CONTROL
) {
54 /* We may be executing a deferred opcode */
56 if (walk_state
->deferred_node
) {
57 acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
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.
66 thread
= walk_state
->thread
;
71 /* Display the method locals and arguments */
74 acpi_db_decode_locals(walk_state
);
76 acpi_db_decode_arguments(walk_state
);
80 /*******************************************************************************
82 * FUNCTION: acpi_db_decode_internal_object
84 * PARAMETERS: obj_desc - Object to be displayed
88 * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
90 ******************************************************************************/
92 void acpi_db_decode_internal_object(union acpi_operand_object
*obj_desc
)
97 acpi_os_printf(" Uninitialized");
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
));
107 acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc
));
109 switch (obj_desc
->common
.type
) {
110 case ACPI_TYPE_INTEGER
:
112 acpi_os_printf(" %8.8X%8.8X",
113 ACPI_FORMAT_UINT64(obj_desc
->integer
.value
));
116 case ACPI_TYPE_STRING
:
118 acpi_os_printf("(%u) \"%.60s",
119 obj_desc
->string
.length
,
120 obj_desc
->string
.pointer
);
122 if (obj_desc
->string
.length
> 60) {
123 acpi_os_printf("...");
125 acpi_os_printf("\"");
129 case ACPI_TYPE_BUFFER
:
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
]);
139 acpi_os_printf(" %p", obj_desc
);
144 /*******************************************************************************
146 * FUNCTION: acpi_db_decode_node
148 * PARAMETERS: node - Object to be displayed
152 * DESCRIPTION: Short display of a namespace node
154 ******************************************************************************/
156 static void acpi_db_decode_node(struct acpi_namespace_node
*node
)
159 acpi_os_printf("<Node> Name %4.4s",
160 acpi_ut_get_node_name(node
));
162 if (node
->flags
& ANOBJ_METHOD_ARG
) {
163 acpi_os_printf(" [Method Arg]");
165 if (node
->flags
& ANOBJ_METHOD_LOCAL
) {
166 acpi_os_printf(" [Method Local]");
169 switch (node
->type
) {
171 /* These types have no attached object */
173 case ACPI_TYPE_DEVICE
:
175 acpi_os_printf(" Device");
178 case ACPI_TYPE_THERMAL
:
180 acpi_os_printf(" Thermal Zone");
185 acpi_db_decode_internal_object(acpi_ns_get_attached_object
191 /*******************************************************************************
193 * FUNCTION: acpi_db_display_internal_object
195 * PARAMETERS: obj_desc - Object to be displayed
196 * walk_state - Current walk state
200 * DESCRIPTION: Short display of an internal object
202 ******************************************************************************/
205 acpi_db_display_internal_object(union acpi_operand_object
*obj_desc
,
206 struct acpi_walk_state
*walk_state
)
210 acpi_os_printf("%p ", obj_desc
);
213 acpi_os_printf("<Null Object>\n");
217 /* Decode the object type */
219 switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc
)) {
220 case ACPI_DESC_TYPE_PARSER
:
222 acpi_os_printf("<Parser> ");
225 case ACPI_DESC_TYPE_NAMED
:
227 acpi_db_decode_node((struct acpi_namespace_node
*)obj_desc
);
230 case ACPI_DESC_TYPE_OPERAND
:
232 type
= obj_desc
->common
.type
;
233 if (type
> ACPI_TYPE_LOCAL_MAX
) {
234 acpi_os_printf(" Type %X [Invalid Type]", (u32
)type
);
238 /* Decode the ACPI object type */
240 switch (obj_desc
->common
.type
) {
241 case ACPI_TYPE_LOCAL_REFERENCE
:
243 acpi_os_printf("[%s] ",
244 acpi_ut_get_reference_name(obj_desc
));
246 /* Decode the reference */
248 switch (obj_desc
->reference
.class) {
249 case ACPI_REFCLASS_LOCAL
:
251 acpi_os_printf("%X ",
252 obj_desc
->reference
.value
);
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
262 case ACPI_REFCLASS_ARG
:
264 acpi_os_printf("%X ",
265 obj_desc
->reference
.value
);
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
275 case ACPI_REFCLASS_INDEX
:
277 switch (obj_desc
->reference
.target_type
) {
278 case ACPI_TYPE_BUFFER_FIELD
:
283 acpi_db_decode_internal_object
284 (obj_desc
->reference
.object
);
287 case ACPI_TYPE_PACKAGE
:
292 if (!obj_desc
->reference
.where
) {
294 (" Uninitialized WHERE pointer");
296 acpi_db_decode_internal_object(*
306 ("Unknown index target type");
311 case ACPI_REFCLASS_REFOF
:
313 if (!obj_desc
->reference
.object
) {
315 ("Uninitialized reference subobject pointer");
319 /* Reference can be to a Node or an Operand object */
321 switch (ACPI_GET_DESCRIPTOR_TYPE
322 (obj_desc
->reference
.object
)) {
323 case ACPI_DESC_TYPE_NAMED
:
325 acpi_db_decode_node(obj_desc
->reference
.
329 case ACPI_DESC_TYPE_OPERAND
:
331 acpi_db_decode_internal_object
332 (obj_desc
->reference
.object
);
340 case ACPI_REFCLASS_NAME
:
342 acpi_db_decode_node(obj_desc
->reference
.node
);
345 case ACPI_REFCLASS_DEBUG
:
346 case ACPI_REFCLASS_TABLE
:
348 acpi_os_printf("\n");
351 default: /* Unknown reference class */
353 acpi_os_printf("%2.2X\n",
354 obj_desc
->reference
.class);
361 acpi_os_printf("<Obj> ");
362 acpi_db_decode_internal_object(obj_desc
);
369 acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]",
370 acpi_ut_get_descriptor_name(obj_desc
));
374 acpi_os_printf("\n");
377 /*******************************************************************************
379 * FUNCTION: acpi_db_decode_locals
381 * PARAMETERS: walk_state - State for current method
385 * DESCRIPTION: Display all locals for the currently running control method
387 ******************************************************************************/
389 void acpi_db_decode_locals(struct acpi_walk_state
*walk_state
)
392 union acpi_operand_object
*obj_desc
;
393 struct acpi_namespace_node
*node
;
394 u8 display_locals
= FALSE
;
396 node
= walk_state
->method_node
;
397 obj_desc
= walk_state
->method_desc
;
399 /* There are no locals for the module-level code case */
401 if (node
== acpi_gbl_root_node
) {
407 ("No method node (Executing subtree for buffer or opregion)\n");
411 if (node
->type
!= ACPI_TYPE_METHOD
) {
412 acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
416 /* Are any locals actually set? */
418 for (i
= 0; i
< ACPI_METHOD_NUM_LOCALS
; i
++) {
419 obj_desc
= walk_state
->local_variables
[i
].object
;
421 display_locals
= TRUE
;
426 /* If any are set, only display the ones that are set */
428 if (display_locals
) {
430 ("\nInitialized Local Variables for Method [%4.4s]:\n",
431 acpi_ut_get_node_name(node
));
433 for (i
= 0; i
< ACPI_METHOD_NUM_LOCALS
; i
++) {
434 obj_desc
= walk_state
->local_variables
[i
].object
;
436 acpi_os_printf(" Local%X: ", i
);
437 acpi_db_display_internal_object(obj_desc
,
443 ("No Local Variables are initialized for Method [%4.4s]\n",
444 acpi_ut_get_node_name(node
));
448 /*******************************************************************************
450 * FUNCTION: acpi_db_decode_arguments
452 * PARAMETERS: walk_state - State for current method
456 * DESCRIPTION: Display all arguments for the currently running control method
458 ******************************************************************************/
460 void acpi_db_decode_arguments(struct acpi_walk_state
*walk_state
)
463 union acpi_operand_object
*obj_desc
;
464 struct acpi_namespace_node
*node
;
465 u8 display_args
= FALSE
;
467 node
= walk_state
->method_node
;
468 obj_desc
= walk_state
->method_desc
;
470 /* There are no arguments for the module-level code case */
472 if (node
== acpi_gbl_root_node
) {
478 ("No method node (Executing subtree for buffer or opregion)\n");
482 if (node
->type
!= ACPI_TYPE_METHOD
) {
483 acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
487 /* Are any arguments actually set? */
489 for (i
= 0; i
< ACPI_METHOD_NUM_ARGS
; i
++) {
490 obj_desc
= walk_state
->arguments
[i
].object
;
497 /* If any are set, only display the ones that are set */
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
);
505 for (i
= 0; i
< ACPI_METHOD_NUM_ARGS
; i
++) {
506 obj_desc
= walk_state
->arguments
[i
].object
;
508 acpi_os_printf(" Arg%u: ", i
);
509 acpi_db_display_internal_object(obj_desc
,
515 ("No Arguments are initialized for method [%4.4s]\n",
516 acpi_ut_get_node_name(node
));