xref: /openbmc/linux/drivers/acpi/acpica/dsdebug.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
20bac4295SLv Zheng /******************************************************************************
30bac4295SLv Zheng  *
40bac4295SLv Zheng  * Module Name: dsdebug - Parser/Interpreter interface - debugging
50bac4295SLv Zheng  *
6*612c2932SBob Moore  * Copyright (C) 2000 - 2023, Intel Corp.
70bac4295SLv Zheng  *
895857638SErik Schmauss  *****************************************************************************/
90bac4295SLv Zheng 
100bac4295SLv Zheng #include <acpi/acpi.h>
110bac4295SLv Zheng #include "accommon.h"
120bac4295SLv Zheng #include "acdispat.h"
130bac4295SLv Zheng #include "acnamesp.h"
140bac4295SLv Zheng #ifdef ACPI_DISASSEMBLER
150bac4295SLv Zheng #include "acdisasm.h"
160bac4295SLv Zheng #endif
17ab6c5733SLv Zheng #include "acinterp.h"
180bac4295SLv Zheng 
190bac4295SLv Zheng #define _COMPONENT          ACPI_DISPATCHER
200bac4295SLv Zheng ACPI_MODULE_NAME("dsdebug")
210bac4295SLv Zheng 
220bac4295SLv Zheng #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
230bac4295SLv Zheng /* Local prototypes */
240bac4295SLv Zheng static void
250bac4295SLv Zheng acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
260bac4295SLv Zheng 			    const char *message);
270bac4295SLv Zheng 
280bac4295SLv Zheng /*******************************************************************************
290bac4295SLv Zheng  *
300bac4295SLv Zheng  * FUNCTION:    acpi_ds_print_node_pathname
310bac4295SLv Zheng  *
320bac4295SLv Zheng  * PARAMETERS:  node            - Object
330bac4295SLv Zheng  *              message         - Prefix message
340bac4295SLv Zheng  *
350bac4295SLv Zheng  * DESCRIPTION: Print an object's full namespace pathname
360bac4295SLv Zheng  *              Manages allocation/freeing of a pathname buffer
370bac4295SLv Zheng  *
380bac4295SLv Zheng  ******************************************************************************/
390bac4295SLv Zheng 
400bac4295SLv Zheng static void
acpi_ds_print_node_pathname(struct acpi_namespace_node * node,const char * message)410bac4295SLv Zheng acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
420bac4295SLv Zheng 			    const char *message)
430bac4295SLv Zheng {
440bac4295SLv Zheng 	struct acpi_buffer buffer;
450bac4295SLv Zheng 	acpi_status status;
460bac4295SLv Zheng 
470bac4295SLv Zheng 	ACPI_FUNCTION_TRACE(ds_print_node_pathname);
480bac4295SLv Zheng 
490bac4295SLv Zheng 	if (!node) {
500bac4295SLv Zheng 		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[NULL NAME]"));
510bac4295SLv Zheng 		return_VOID;
520bac4295SLv Zheng 	}
530bac4295SLv Zheng 
540bac4295SLv Zheng 	/* Convert handle to full pathname and print it (with supplied message) */
550bac4295SLv Zheng 
560bac4295SLv Zheng 	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
570bac4295SLv Zheng 
582e5321cbSLv Zheng 	status = acpi_ns_handle_to_pathname(node, &buffer, TRUE);
590bac4295SLv Zheng 	if (ACPI_SUCCESS(status)) {
600bac4295SLv Zheng 		if (message) {
610bac4295SLv Zheng 			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ",
620bac4295SLv Zheng 					      message));
630bac4295SLv Zheng 		}
640bac4295SLv Zheng 
650bac4295SLv Zheng 		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[%s] (Node %p)",
660bac4295SLv Zheng 				      (char *)buffer.pointer, node));
670bac4295SLv Zheng 		ACPI_FREE(buffer.pointer);
680bac4295SLv Zheng 	}
690bac4295SLv Zheng 
700bac4295SLv Zheng 	return_VOID;
710bac4295SLv Zheng }
720bac4295SLv Zheng 
730bac4295SLv Zheng /*******************************************************************************
740bac4295SLv Zheng  *
750bac4295SLv Zheng  * FUNCTION:    acpi_ds_dump_method_stack
760bac4295SLv Zheng  *
770bac4295SLv Zheng  * PARAMETERS:  status          - Method execution status
780bac4295SLv Zheng  *              walk_state      - Current state of the parse tree walk
790bac4295SLv Zheng  *              op              - Executing parse op
800bac4295SLv Zheng  *
810bac4295SLv Zheng  * RETURN:      None
820bac4295SLv Zheng  *
830bac4295SLv Zheng  * DESCRIPTION: Called when a method has been aborted because of an error.
840bac4295SLv Zheng  *              Dumps the method execution stack.
850bac4295SLv Zheng  *
860bac4295SLv Zheng  ******************************************************************************/
870bac4295SLv Zheng 
880bac4295SLv Zheng void
acpi_ds_dump_method_stack(acpi_status status,struct acpi_walk_state * walk_state,union acpi_parse_object * op)890bac4295SLv Zheng acpi_ds_dump_method_stack(acpi_status status,
900bac4295SLv Zheng 			  struct acpi_walk_state *walk_state,
910bac4295SLv Zheng 			  union acpi_parse_object *op)
920bac4295SLv Zheng {
930bac4295SLv Zheng 	union acpi_parse_object *next;
940bac4295SLv Zheng 	struct acpi_thread_state *thread;
950bac4295SLv Zheng 	struct acpi_walk_state *next_walk_state;
960bac4295SLv Zheng 	struct acpi_namespace_node *previous_method = NULL;
97a616dc2fSLv Zheng 	union acpi_operand_object *method_desc;
980bac4295SLv Zheng 
990bac4295SLv Zheng 	ACPI_FUNCTION_TRACE(ds_dump_method_stack);
1000bac4295SLv Zheng 
1010bac4295SLv Zheng 	/* Ignore control codes, they are not errors */
1020bac4295SLv Zheng 
10325d866c4SMaximilian Luz 	if (ACPI_CNTL_EXCEPTION(status)) {
1040bac4295SLv Zheng 		return_VOID;
1050bac4295SLv Zheng 	}
1060bac4295SLv Zheng 
1070bac4295SLv Zheng 	/* We may be executing a deferred opcode */
1080bac4295SLv Zheng 
1090bac4295SLv Zheng 	if (walk_state->deferred_node) {
1100bac4295SLv Zheng 		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1110bac4295SLv Zheng 				  "Executing subtree for Buffer/Package/Region\n"));
1120bac4295SLv Zheng 		return_VOID;
1130bac4295SLv Zheng 	}
1140bac4295SLv Zheng 
1150bac4295SLv Zheng 	/*
1160bac4295SLv Zheng 	 * If there is no Thread, we are not actually executing a method.
1170bac4295SLv Zheng 	 * This can happen when the iASL compiler calls the interpreter
1180bac4295SLv Zheng 	 * to perform constant folding.
1190bac4295SLv Zheng 	 */
1200bac4295SLv Zheng 	thread = walk_state->thread;
1210bac4295SLv Zheng 	if (!thread) {
1220bac4295SLv Zheng 		return_VOID;
1230bac4295SLv Zheng 	}
1240bac4295SLv Zheng 
1250bac4295SLv Zheng 	/* Display exception and method name */
1260bac4295SLv Zheng 
1270bac4295SLv Zheng 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1280bac4295SLv Zheng 			  "\n**** Exception %s during execution of method ",
1290bac4295SLv Zheng 			  acpi_format_exception(status)));
1301fad8738SBob Moore 
1310bac4295SLv Zheng 	acpi_ds_print_node_pathname(walk_state->method_node, NULL);
1320bac4295SLv Zheng 
1330bac4295SLv Zheng 	/* Display stack of executing methods */
1340bac4295SLv Zheng 
1350bac4295SLv Zheng 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
1360bac4295SLv Zheng 			      "\n\nMethod Execution Stack:\n"));
1370bac4295SLv Zheng 	next_walk_state = thread->walk_state_list;
1380bac4295SLv Zheng 
1390bac4295SLv Zheng 	/* Walk list of linked walk states */
1400bac4295SLv Zheng 
1410bac4295SLv Zheng 	while (next_walk_state) {
142a616dc2fSLv Zheng 		method_desc = next_walk_state->method_desc;
143ab6c5733SLv Zheng 		if (method_desc) {
144ab6c5733SLv Zheng 			acpi_ex_stop_trace_method((struct acpi_namespace_node *)
145ab6c5733SLv Zheng 						  method_desc->method.node,
146ab6c5733SLv Zheng 						  method_desc, walk_state);
147a616dc2fSLv Zheng 		}
148a616dc2fSLv Zheng 
1490bac4295SLv Zheng 		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1500bac4295SLv Zheng 				  "    Method [%4.4s] executing: ",
1510bac4295SLv Zheng 				  acpi_ut_get_node_name(next_walk_state->
1520bac4295SLv Zheng 							method_node)));
1530bac4295SLv Zheng 
1540bac4295SLv Zheng 		/* First method is the currently executing method */
1550bac4295SLv Zheng 
1560bac4295SLv Zheng 		if (next_walk_state == walk_state) {
1570bac4295SLv Zheng 			if (op) {
1580bac4295SLv Zheng 
1590bac4295SLv Zheng 				/* Display currently executing ASL statement */
1600bac4295SLv Zheng 
1610bac4295SLv Zheng 				next = op->common.next;
1620bac4295SLv Zheng 				op->common.next = NULL;
1630bac4295SLv Zheng 
1640bac4295SLv Zheng #ifdef ACPI_DISASSEMBLER
1653877b2ccSBob Moore 				if (walk_state->method_node !=
1663877b2ccSBob Moore 				    acpi_gbl_root_node) {
1673877b2ccSBob Moore 
1683877b2ccSBob Moore 					/* More verbose if not module-level code */
1693877b2ccSBob Moore 
1702cb8c3bbSBob Moore 					acpi_os_printf("Failed at ");
1710bac4295SLv Zheng 					acpi_dm_disassemble(next_walk_state, op,
1720bac4295SLv Zheng 							    ACPI_UINT32_MAX);
1733877b2ccSBob Moore 				}
1740bac4295SLv Zheng #endif
1750bac4295SLv Zheng 				op->common.next = next;
1760bac4295SLv Zheng 			}
1770bac4295SLv Zheng 		} else {
1780bac4295SLv Zheng 			/*
1790bac4295SLv Zheng 			 * This method has called another method
1801fad8738SBob Moore 			 * NOTE: the method call parse subtree is already deleted at
1811fad8738SBob Moore 			 * this point, so we cannot disassemble the method invocation.
1820bac4295SLv Zheng 			 */
1830bac4295SLv Zheng 			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
1840bac4295SLv Zheng 					      "Call to method "));
1850bac4295SLv Zheng 			acpi_ds_print_node_pathname(previous_method, NULL);
1860bac4295SLv Zheng 		}
1870bac4295SLv Zheng 
1880bac4295SLv Zheng 		previous_method = next_walk_state->method_node;
1890bac4295SLv Zheng 		next_walk_state = next_walk_state->next;
1900bac4295SLv Zheng 		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n"));
1910bac4295SLv Zheng 	}
1920bac4295SLv Zheng 
1930bac4295SLv Zheng 	return_VOID;
1940bac4295SLv Zheng }
1950bac4295SLv Zheng 
1960bac4295SLv Zheng #else
1970bac4295SLv Zheng void
1980bac4295SLv Zheng acpi_ds_dump_method_stack(acpi_status status,
1990bac4295SLv Zheng 			  struct acpi_walk_state *walk_state,
2000bac4295SLv Zheng 			  union acpi_parse_object *op)
2010bac4295SLv Zheng {
2020bac4295SLv Zheng 	return;
2030bac4295SLv Zheng }
2040bac4295SLv Zheng 
2050bac4295SLv Zheng #endif
206