Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
Note: File does not exist in v3.5.6.
  1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2/******************************************************************************
  3 *
  4 * Module Name: dsdebug - Parser/Interpreter interface - debugging
  5 *
  6 * Copyright (C) 2000 - 2022, Intel Corp.
  7 *
  8 *****************************************************************************/
  9
 10#include <acpi/acpi.h>
 11#include "accommon.h"
 12#include "acdispat.h"
 13#include "acnamesp.h"
 14#ifdef ACPI_DISASSEMBLER
 15#include "acdisasm.h"
 16#endif
 17#include "acinterp.h"
 18
 19#define _COMPONENT          ACPI_DISPATCHER
 20ACPI_MODULE_NAME("dsdebug")
 21
 22#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 23/* Local prototypes */
 24static void
 25acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
 26			    const char *message);
 27
 28/*******************************************************************************
 29 *
 30 * FUNCTION:    acpi_ds_print_node_pathname
 31 *
 32 * PARAMETERS:  node            - Object
 33 *              message         - Prefix message
 34 *
 35 * DESCRIPTION: Print an object's full namespace pathname
 36 *              Manages allocation/freeing of a pathname buffer
 37 *
 38 ******************************************************************************/
 39
 40static void
 41acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
 42			    const char *message)
 43{
 44	struct acpi_buffer buffer;
 45	acpi_status status;
 46
 47	ACPI_FUNCTION_TRACE(ds_print_node_pathname);
 48
 49	if (!node) {
 50		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[NULL NAME]"));
 51		return_VOID;
 52	}
 53
 54	/* Convert handle to full pathname and print it (with supplied message) */
 55
 56	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 57
 58	status = acpi_ns_handle_to_pathname(node, &buffer, TRUE);
 59	if (ACPI_SUCCESS(status)) {
 60		if (message) {
 61			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ",
 62					      message));
 63		}
 64
 65		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[%s] (Node %p)",
 66				      (char *)buffer.pointer, node));
 67		ACPI_FREE(buffer.pointer);
 68	}
 69
 70	return_VOID;
 71}
 72
 73/*******************************************************************************
 74 *
 75 * FUNCTION:    acpi_ds_dump_method_stack
 76 *
 77 * PARAMETERS:  status          - Method execution status
 78 *              walk_state      - Current state of the parse tree walk
 79 *              op              - Executing parse op
 80 *
 81 * RETURN:      None
 82 *
 83 * DESCRIPTION: Called when a method has been aborted because of an error.
 84 *              Dumps the method execution stack.
 85 *
 86 ******************************************************************************/
 87
 88void
 89acpi_ds_dump_method_stack(acpi_status status,
 90			  struct acpi_walk_state *walk_state,
 91			  union acpi_parse_object *op)
 92{
 93	union acpi_parse_object *next;
 94	struct acpi_thread_state *thread;
 95	struct acpi_walk_state *next_walk_state;
 96	struct acpi_namespace_node *previous_method = NULL;
 97	union acpi_operand_object *method_desc;
 98
 99	ACPI_FUNCTION_TRACE(ds_dump_method_stack);
100
101	/* Ignore control codes, they are not errors */
102
103	if (ACPI_CNTL_EXCEPTION(status)) {
104		return_VOID;
105	}
106
107	/* We may be executing a deferred opcode */
108
109	if (walk_state->deferred_node) {
110		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
111				  "Executing subtree for Buffer/Package/Region\n"));
112		return_VOID;
113	}
114
115	/*
116	 * If there is no Thread, we are not actually executing a method.
117	 * This can happen when the iASL compiler calls the interpreter
118	 * to perform constant folding.
119	 */
120	thread = walk_state->thread;
121	if (!thread) {
122		return_VOID;
123	}
124
125	/* Display exception and method name */
126
127	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
128			  "\n**** Exception %s during execution of method ",
129			  acpi_format_exception(status)));
130
131	acpi_ds_print_node_pathname(walk_state->method_node, NULL);
132
133	/* Display stack of executing methods */
134
135	ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
136			      "\n\nMethod Execution Stack:\n"));
137	next_walk_state = thread->walk_state_list;
138
139	/* Walk list of linked walk states */
140
141	while (next_walk_state) {
142		method_desc = next_walk_state->method_desc;
143		if (method_desc) {
144			acpi_ex_stop_trace_method((struct acpi_namespace_node *)
145						  method_desc->method.node,
146						  method_desc, walk_state);
147		}
148
149		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
150				  "    Method [%4.4s] executing: ",
151				  acpi_ut_get_node_name(next_walk_state->
152							method_node)));
153
154		/* First method is the currently executing method */
155
156		if (next_walk_state == walk_state) {
157			if (op) {
158
159				/* Display currently executing ASL statement */
160
161				next = op->common.next;
162				op->common.next = NULL;
163
164#ifdef ACPI_DISASSEMBLER
165				if (walk_state->method_node !=
166				    acpi_gbl_root_node) {
167
168					/* More verbose if not module-level code */
169
170					acpi_os_printf("Failed at ");
171					acpi_dm_disassemble(next_walk_state, op,
172							    ACPI_UINT32_MAX);
173				}
174#endif
175				op->common.next = next;
176			}
177		} else {
178			/*
179			 * This method has called another method
180			 * NOTE: the method call parse subtree is already deleted at
181			 * this point, so we cannot disassemble the method invocation.
182			 */
183			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
184					      "Call to method "));
185			acpi_ds_print_node_pathname(previous_method, NULL);
186		}
187
188		previous_method = next_walk_state->method_node;
189		next_walk_state = next_walk_state->next;
190		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n"));
191	}
192
193	return_VOID;
194}
195
196#else
197void
198acpi_ds_dump_method_stack(acpi_status status,
199			  struct acpi_walk_state *walk_state,
200			  union acpi_parse_object *op)
201{
202	return;
203}
204
205#endif