summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2015-07-23 00:52:46 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-07-23 17:09:06 -0400
commit0bac4295526c67e87ec24b29762140c38de7c86a (patch)
tree7bb435cab7d15dae1b193465c3f5091077a9b6dc
parentd1e7ffe50ba588ddf7de520990815c37f31776d8 (diff)
ACPICA: Dispatcher: Move stack traversal code to dispatcher
ACPICA commit c8275e243b58fd4adfc0362bd704af41ed14bc75 This patch moves parts of acpi_dm_dump_method_info() to the dispatcher component. This patch also makes the new function dependent on ACPI_DEBUG_OUTPUT compile-stage definition so that it can be used by the trace facility. acpi_dm_dump_method_info() traverses method stack when an exception is encountered. Such traversal is needed to support method tracing for the exceptions. When an exception is encountered, the end indications of the aborted methods should be logged in order not to break the user space analysis tool. Lv Zheng. Link: https://github.com/acpica/acpica/commit/c8275e24 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/acpica/Makefile1
-rw-r--r--drivers/acpi/acpica/acdispat.h8
-rw-r--r--drivers/acpi/acpica/dsdebug.c222
-rw-r--r--drivers/acpi/acpica/dsmethod.c7
4 files changed, 235 insertions, 3 deletions
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index c1a963581dc0..9f30ed7b1a07 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -11,6 +11,7 @@ obj-y += acpi.o
11acpi-y := \ 11acpi-y := \
12 dsargs.o \ 12 dsargs.o \
13 dscontrol.o \ 13 dscontrol.o \
14 dsdebug.o \
14 dsfield.o \ 15 dsfield.o \
15 dsinit.o \ 16 dsinit.o \
16 dsmethod.o \ 17 dsmethod.o \
diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h
index 408f04bcaab4..7094dc89eb81 100644
--- a/drivers/acpi/acpica/acdispat.h
+++ b/drivers/acpi/acpica/acdispat.h
@@ -354,4 +354,12 @@ acpi_status
354acpi_ds_result_push(union acpi_operand_object *object, 354acpi_ds_result_push(union acpi_operand_object *object,
355 struct acpi_walk_state *walk_state); 355 struct acpi_walk_state *walk_state);
356 356
357/*
358 * dsdebug - parser debugging routines
359 */
360void
361acpi_ds_dump_method_stack(acpi_status status,
362 struct acpi_walk_state *walk_state,
363 union acpi_parse_object *op);
364
357#endif /* _ACDISPAT_H_ */ 365#endif /* _ACDISPAT_H_ */
diff --git a/drivers/acpi/acpica/dsdebug.c b/drivers/acpi/acpica/dsdebug.c
new file mode 100644
index 000000000000..21c6cefd267e
--- /dev/null
+++ b/drivers/acpi/acpica/dsdebug.c
@@ -0,0 +1,222 @@
1/******************************************************************************
2 *
3 * Module Name: dsdebug - Parser/Interpreter interface - debugging
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acdispat.h"
47#include "acnamesp.h"
48#ifdef ACPI_DISASSEMBLER
49#include "acdisasm.h"
50#endif
51
52#define _COMPONENT ACPI_DISPATCHER
53ACPI_MODULE_NAME("dsdebug")
54
55#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
56/* Local prototypes */
57static void
58acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
59 const char *message);
60
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ds_print_node_pathname
64 *
65 * PARAMETERS: node - Object
66 * message - Prefix message
67 *
68 * DESCRIPTION: Print an object's full namespace pathname
69 * Manages allocation/freeing of a pathname buffer
70 *
71 ******************************************************************************/
72
73static void
74acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
75 const char *message)
76{
77 struct acpi_buffer buffer;
78 acpi_status status;
79
80 ACPI_FUNCTION_TRACE(ds_print_node_pathname);
81
82 if (!node) {
83 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[NULL NAME]"));
84 return_VOID;
85 }
86
87 /* Convert handle to full pathname and print it (with supplied message) */
88
89 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
90
91 status = acpi_ns_handle_to_pathname(node, &buffer, FALSE);
92 if (ACPI_SUCCESS(status)) {
93 if (message) {
94 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ",
95 message));
96 }
97
98 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[%s] (Node %p)",
99 (char *)buffer.pointer, node));
100 ACPI_FREE(buffer.pointer);
101 }
102
103 return_VOID;
104}
105
106/*******************************************************************************
107 *
108 * FUNCTION: acpi_ds_dump_method_stack
109 *
110 * PARAMETERS: status - Method execution status
111 * walk_state - Current state of the parse tree walk
112 * op - Executing parse op
113 *
114 * RETURN: None
115 *
116 * DESCRIPTION: Called when a method has been aborted because of an error.
117 * Dumps the method execution stack.
118 *
119 ******************************************************************************/
120
121void
122acpi_ds_dump_method_stack(acpi_status status,
123 struct acpi_walk_state *walk_state,
124 union acpi_parse_object *op)
125{
126 union acpi_parse_object *next;
127 struct acpi_thread_state *thread;
128 struct acpi_walk_state *next_walk_state;
129 struct acpi_namespace_node *previous_method = NULL;
130
131 ACPI_FUNCTION_TRACE(ds_dump_method_stack);
132
133 /* Ignore control codes, they are not errors */
134
135 if ((status & AE_CODE_MASK) == AE_CODE_CONTROL) {
136 return_VOID;
137 }
138
139 /* We may be executing a deferred opcode */
140
141 if (walk_state->deferred_node) {
142 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
143 "Executing subtree for Buffer/Package/Region\n"));
144 return_VOID;
145 }
146
147 /*
148 * If there is no Thread, we are not actually executing a method.
149 * This can happen when the iASL compiler calls the interpreter
150 * to perform constant folding.
151 */
152 thread = walk_state->thread;
153 if (!thread) {
154 return_VOID;
155 }
156
157 /* Display exception and method name */
158
159 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
160 "\n**** Exception %s during execution of method ",
161 acpi_format_exception(status)));
162 acpi_ds_print_node_pathname(walk_state->method_node, NULL);
163
164 /* Display stack of executing methods */
165
166 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
167 "\n\nMethod Execution Stack:\n"));
168 next_walk_state = thread->walk_state_list;
169
170 /* Walk list of linked walk states */
171
172 while (next_walk_state) {
173 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
174 " Method [%4.4s] executing: ",
175 acpi_ut_get_node_name(next_walk_state->
176 method_node)));
177
178 /* First method is the currently executing method */
179
180 if (next_walk_state == walk_state) {
181 if (op) {
182
183 /* Display currently executing ASL statement */
184
185 next = op->common.next;
186 op->common.next = NULL;
187
188#ifdef ACPI_DISASSEMBLER
189 acpi_dm_disassemble(next_walk_state, op,
190 ACPI_UINT32_MAX);
191#endif
192 op->common.next = next;
193 }
194 } else {
195 /*
196 * This method has called another method
197 * NOTE: the method call parse subtree is already deleted at this
198 * point, so we cannot disassemble the method invocation.
199 */
200 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
201 "Call to method "));
202 acpi_ds_print_node_pathname(previous_method, NULL);
203 }
204
205 previous_method = next_walk_state->method_node;
206 next_walk_state = next_walk_state->next;
207 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n"));
208 }
209
210 return_VOID;
211}
212
213#else
214void
215acpi_ds_dump_method_stack(acpi_status status,
216 struct acpi_walk_state *walk_state,
217 union acpi_parse_object *op)
218{
219 return;
220}
221
222#endif
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
index 4abc2425de4b..e0ae8f4e9b35 100644
--- a/drivers/acpi/acpica/dsmethod.c
+++ b/drivers/acpi/acpica/dsmethod.c
@@ -251,14 +251,15 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state * walk_state)
251 251
252 acpi_ds_clear_implicit_return(walk_state); 252 acpi_ds_clear_implicit_return(walk_state);
253 253
254#ifdef ACPI_DISASSEMBLER
255 if (ACPI_FAILURE(status)) { 254 if (ACPI_FAILURE(status)) {
255 acpi_ds_dump_method_stack(status, walk_state, walk_state->op);
256 256
257 /* Display method locals/args if disassembler is present */ 257 /* Display method locals/args if disassembler is present */
258 258
259 acpi_dm_dump_method_info(status, walk_state, walk_state->op); 259#ifdef ACPI_DISASSEMBLER
260 } 260 acpi_dm_dump_method_info(status, walk_state);
261#endif 261#endif
262 }
262 263
263 return (status); 264 return (status);
264} 265}