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