diff options
-rw-r--r-- | drivers/acpi/acpica/Makefile | 1 | ||||
-rw-r--r-- | drivers/acpi/acpica/acdispat.h | 8 | ||||
-rw-r--r-- | drivers/acpi/acpica/dsdebug.c | 222 | ||||
-rw-r--r-- | drivers/acpi/acpica/dsmethod.c | 7 |
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 | |||
11 | acpi-y := \ | 11 | acpi-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 | |||
354 | acpi_ds_result_push(union acpi_operand_object *object, | 354 | acpi_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 | */ | ||
360 | void | ||
361 | acpi_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 | ||
53 | ACPI_MODULE_NAME("dsdebug") | ||
54 | |||
55 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
56 | /* Local prototypes */ | ||
57 | static void | ||
58 | acpi_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 | |||
73 | static void | ||
74 | acpi_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 | |||
121 | void | ||
122 | acpi_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 | ||
214 | void | ||
215 | acpi_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 | } |