1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 |
2 | /****************************************************************************** |
3 | * |
4 | * Module Name: utdebug - Debug print/trace routines |
5 | * |
6 | * Copyright (C) 2000 - 2023, Intel Corp. |
7 | * |
8 | *****************************************************************************/ |
9 | |
10 | #define EXPORT_ACPI_INTERFACES |
11 | |
12 | #include <acpi/acpi.h> |
13 | #include "accommon.h" |
14 | #include "acinterp.h" |
15 | |
16 | #define _COMPONENT ACPI_UTILITIES |
17 | ACPI_MODULE_NAME("utdebug" ) |
18 | |
19 | #ifdef ACPI_DEBUG_OUTPUT |
20 | static acpi_thread_id acpi_gbl_previous_thread_id = (acpi_thread_id) 0xFFFFFFFF; |
21 | static const char *acpi_gbl_function_entry_prefix = "----Entry" ; |
22 | static const char *acpi_gbl_function_exit_prefix = "----Exit-" ; |
23 | |
24 | /******************************************************************************* |
25 | * |
26 | * FUNCTION: acpi_ut_init_stack_ptr_trace |
27 | * |
28 | * PARAMETERS: None |
29 | * |
30 | * RETURN: None |
31 | * |
32 | * DESCRIPTION: Save the current CPU stack pointer at subsystem startup |
33 | * |
34 | ******************************************************************************/ |
35 | |
36 | void acpi_ut_init_stack_ptr_trace(void) |
37 | { |
38 | acpi_size current_sp; |
39 | |
40 | #pragma GCC diagnostic push |
41 | #if defined(__GNUC__) && __GNUC__ >= 12 |
42 | #pragma GCC diagnostic ignored "-Wdangling-pointer=" |
43 | #endif |
44 | acpi_gbl_entry_stack_pointer = ¤t_sp; |
45 | #pragma GCC diagnostic pop |
46 | } |
47 | |
48 | /******************************************************************************* |
49 | * |
50 | * FUNCTION: acpi_ut_track_stack_ptr |
51 | * |
52 | * PARAMETERS: None |
53 | * |
54 | * RETURN: None |
55 | * |
56 | * DESCRIPTION: Save the current CPU stack pointer |
57 | * |
58 | ******************************************************************************/ |
59 | |
60 | void acpi_ut_track_stack_ptr(void) |
61 | { |
62 | acpi_size current_sp; |
63 | |
64 | if (¤t_sp < acpi_gbl_lowest_stack_pointer) { |
65 | acpi_gbl_lowest_stack_pointer = ¤t_sp; |
66 | } |
67 | |
68 | if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) { |
69 | acpi_gbl_deepest_nesting = acpi_gbl_nesting_level; |
70 | } |
71 | } |
72 | |
73 | /******************************************************************************* |
74 | * |
75 | * FUNCTION: acpi_ut_trim_function_name |
76 | * |
77 | * PARAMETERS: function_name - Ascii string containing a procedure name |
78 | * |
79 | * RETURN: Updated pointer to the function name |
80 | * |
81 | * DESCRIPTION: Remove the "Acpi" prefix from the function name, if present. |
82 | * This allows compiler macros such as __func__ to be used |
83 | * with no change to the debug output. |
84 | * |
85 | ******************************************************************************/ |
86 | |
87 | static const char *acpi_ut_trim_function_name(const char *function_name) |
88 | { |
89 | |
90 | /* All Function names are longer than 4 chars, check is safe */ |
91 | |
92 | if (*(ACPI_CAST_PTR(u32, function_name)) == ACPI_PREFIX_MIXED) { |
93 | |
94 | /* This is the case where the original source has not been modified */ |
95 | |
96 | return (function_name + 4); |
97 | } |
98 | |
99 | if (*(ACPI_CAST_PTR(u32, function_name)) == ACPI_PREFIX_LOWER) { |
100 | |
101 | /* This is the case where the source has been 'linuxized' */ |
102 | |
103 | return (function_name + 5); |
104 | } |
105 | |
106 | return (function_name); |
107 | } |
108 | |
109 | /******************************************************************************* |
110 | * |
111 | * FUNCTION: acpi_debug_print |
112 | * |
113 | * PARAMETERS: requested_debug_level - Requested debug print level |
114 | * line_number - Caller's line number (for error output) |
115 | * function_name - Caller's procedure name |
116 | * module_name - Caller's module name |
117 | * component_id - Caller's component ID |
118 | * format - Printf format field |
119 | * ... - Optional printf arguments |
120 | * |
121 | * RETURN: None |
122 | * |
123 | * DESCRIPTION: Print error message with prefix consisting of the module name, |
124 | * line number, and component ID. |
125 | * |
126 | ******************************************************************************/ |
127 | |
128 | void ACPI_INTERNAL_VAR_XFACE |
129 | acpi_debug_print(u32 requested_debug_level, |
130 | u32 line_number, |
131 | const char *function_name, |
132 | const char *module_name, |
133 | u32 component_id, const char *format, ...) |
134 | { |
135 | acpi_thread_id thread_id; |
136 | va_list args; |
137 | #ifdef ACPI_APPLICATION |
138 | int fill_count; |
139 | #endif |
140 | |
141 | /* Check if debug output enabled */ |
142 | |
143 | if (!ACPI_IS_DEBUG_ENABLED(requested_debug_level, component_id)) { |
144 | return; |
145 | } |
146 | |
147 | /* |
148 | * Thread tracking and context switch notification |
149 | */ |
150 | thread_id = acpi_os_get_thread_id(); |
151 | if (thread_id != acpi_gbl_previous_thread_id) { |
152 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
153 | acpi_os_printf |
154 | (format: "\n**** Context Switch from TID %u to TID %u ****\n\n" , |
155 | (u32)acpi_gbl_previous_thread_id, (u32)thread_id); |
156 | } |
157 | |
158 | acpi_gbl_previous_thread_id = thread_id; |
159 | acpi_gbl_nesting_level = 0; |
160 | } |
161 | |
162 | /* |
163 | * Display the module name, current line number, thread ID (if requested), |
164 | * current procedure nesting level, and the current procedure name |
165 | */ |
166 | acpi_os_printf(format: "%9s-%04d " , module_name, line_number); |
167 | |
168 | #ifdef ACPI_APPLICATION |
169 | /* |
170 | * For acpi_exec/iASL only, emit the thread ID and nesting level. |
171 | * Note: nesting level is really only useful during a single-thread |
172 | * execution. Otherwise, multiple threads will keep resetting the |
173 | * level. |
174 | */ |
175 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
176 | acpi_os_printf("[%u] " , (u32)thread_id); |
177 | } |
178 | |
179 | fill_count = 48 - acpi_gbl_nesting_level - |
180 | strlen(acpi_ut_trim_function_name(function_name)); |
181 | if (fill_count < 0) { |
182 | fill_count = 0; |
183 | } |
184 | |
185 | acpi_os_printf("[%02d] %*s" , |
186 | acpi_gbl_nesting_level, acpi_gbl_nesting_level + 1, " " ); |
187 | acpi_os_printf("%s%*s: " , |
188 | acpi_ut_trim_function_name(function_name), fill_count, |
189 | " " ); |
190 | |
191 | #else |
192 | acpi_os_printf(format: "%-22.22s: " , acpi_ut_trim_function_name(function_name)); |
193 | #endif |
194 | |
195 | va_start(args, format); |
196 | acpi_os_vprintf(format, args); |
197 | va_end(args); |
198 | } |
199 | |
200 | ACPI_EXPORT_SYMBOL(acpi_debug_print) |
201 | |
202 | /******************************************************************************* |
203 | * |
204 | * FUNCTION: acpi_debug_print_raw |
205 | * |
206 | * PARAMETERS: requested_debug_level - Requested debug print level |
207 | * line_number - Caller's line number |
208 | * function_name - Caller's procedure name |
209 | * module_name - Caller's module name |
210 | * component_id - Caller's component ID |
211 | * format - Printf format field |
212 | * ... - Optional printf arguments |
213 | * |
214 | * RETURN: None |
215 | * |
216 | * DESCRIPTION: Print message with no headers. Has same interface as |
217 | * debug_print so that the same macros can be used. |
218 | * |
219 | ******************************************************************************/ |
220 | void ACPI_INTERNAL_VAR_XFACE |
221 | acpi_debug_print_raw(u32 requested_debug_level, |
222 | u32 line_number, |
223 | const char *function_name, |
224 | const char *module_name, |
225 | u32 component_id, const char *format, ...) |
226 | { |
227 | va_list args; |
228 | |
229 | /* Check if debug output enabled */ |
230 | |
231 | if (!ACPI_IS_DEBUG_ENABLED(requested_debug_level, component_id)) { |
232 | return; |
233 | } |
234 | |
235 | va_start(args, format); |
236 | acpi_os_vprintf(format, args); |
237 | va_end(args); |
238 | } |
239 | |
240 | ACPI_EXPORT_SYMBOL(acpi_debug_print_raw) |
241 | |
242 | /******************************************************************************* |
243 | * |
244 | * FUNCTION: acpi_ut_trace |
245 | * |
246 | * PARAMETERS: line_number - Caller's line number |
247 | * function_name - Caller's procedure name |
248 | * module_name - Caller's module name |
249 | * component_id - Caller's component ID |
250 | * |
251 | * RETURN: None |
252 | * |
253 | * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is |
254 | * set in debug_level |
255 | * |
256 | ******************************************************************************/ |
257 | void |
258 | acpi_ut_trace(u32 line_number, |
259 | const char *function_name, |
260 | const char *module_name, u32 component_id) |
261 | { |
262 | |
263 | acpi_gbl_nesting_level++; |
264 | acpi_ut_track_stack_ptr(); |
265 | |
266 | /* Check if enabled up-front for performance */ |
267 | |
268 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { |
269 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
270 | line_number, function_name, module_name, |
271 | component_id, "%s\n" , |
272 | acpi_gbl_function_entry_prefix); |
273 | } |
274 | } |
275 | |
276 | ACPI_EXPORT_SYMBOL(acpi_ut_trace) |
277 | |
278 | /******************************************************************************* |
279 | * |
280 | * FUNCTION: acpi_ut_trace_ptr |
281 | * |
282 | * PARAMETERS: line_number - Caller's line number |
283 | * function_name - Caller's procedure name |
284 | * module_name - Caller's module name |
285 | * component_id - Caller's component ID |
286 | * pointer - Pointer to display |
287 | * |
288 | * RETURN: None |
289 | * |
290 | * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is |
291 | * set in debug_level |
292 | * |
293 | ******************************************************************************/ |
294 | void |
295 | acpi_ut_trace_ptr(u32 line_number, |
296 | const char *function_name, |
297 | const char *module_name, |
298 | u32 component_id, const void *pointer) |
299 | { |
300 | |
301 | acpi_gbl_nesting_level++; |
302 | acpi_ut_track_stack_ptr(); |
303 | |
304 | /* Check if enabled up-front for performance */ |
305 | |
306 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { |
307 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
308 | line_number, function_name, module_name, |
309 | component_id, "%s %p\n" , |
310 | acpi_gbl_function_entry_prefix, pointer); |
311 | } |
312 | } |
313 | |
314 | /******************************************************************************* |
315 | * |
316 | * FUNCTION: acpi_ut_trace_str |
317 | * |
318 | * PARAMETERS: line_number - Caller's line number |
319 | * function_name - Caller's procedure name |
320 | * module_name - Caller's module name |
321 | * component_id - Caller's component ID |
322 | * string - Additional string to display |
323 | * |
324 | * RETURN: None |
325 | * |
326 | * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is |
327 | * set in debug_level |
328 | * |
329 | ******************************************************************************/ |
330 | |
331 | void |
332 | acpi_ut_trace_str(u32 line_number, |
333 | const char *function_name, |
334 | const char *module_name, u32 component_id, const char *string) |
335 | { |
336 | |
337 | acpi_gbl_nesting_level++; |
338 | acpi_ut_track_stack_ptr(); |
339 | |
340 | /* Check if enabled up-front for performance */ |
341 | |
342 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { |
343 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
344 | line_number, function_name, module_name, |
345 | component_id, "%s %s\n" , |
346 | acpi_gbl_function_entry_prefix, string); |
347 | } |
348 | } |
349 | |
350 | /******************************************************************************* |
351 | * |
352 | * FUNCTION: acpi_ut_trace_u32 |
353 | * |
354 | * PARAMETERS: line_number - Caller's line number |
355 | * function_name - Caller's procedure name |
356 | * module_name - Caller's module name |
357 | * component_id - Caller's component ID |
358 | * integer - Integer to display |
359 | * |
360 | * RETURN: None |
361 | * |
362 | * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is |
363 | * set in debug_level |
364 | * |
365 | ******************************************************************************/ |
366 | |
367 | void |
368 | acpi_ut_trace_u32(u32 line_number, |
369 | const char *function_name, |
370 | const char *module_name, u32 component_id, u32 integer) |
371 | { |
372 | |
373 | acpi_gbl_nesting_level++; |
374 | acpi_ut_track_stack_ptr(); |
375 | |
376 | /* Check if enabled up-front for performance */ |
377 | |
378 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { |
379 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
380 | line_number, function_name, module_name, |
381 | component_id, "%s %08X\n" , |
382 | acpi_gbl_function_entry_prefix, integer); |
383 | } |
384 | } |
385 | |
386 | /******************************************************************************* |
387 | * |
388 | * FUNCTION: acpi_ut_exit |
389 | * |
390 | * PARAMETERS: line_number - Caller's line number |
391 | * function_name - Caller's procedure name |
392 | * module_name - Caller's module name |
393 | * component_id - Caller's component ID |
394 | * |
395 | * RETURN: None |
396 | * |
397 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is |
398 | * set in debug_level |
399 | * |
400 | ******************************************************************************/ |
401 | |
402 | void |
403 | acpi_ut_exit(u32 line_number, |
404 | const char *function_name, |
405 | const char *module_name, u32 component_id) |
406 | { |
407 | |
408 | /* Check if enabled up-front for performance */ |
409 | |
410 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { |
411 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
412 | line_number, function_name, module_name, |
413 | component_id, "%s\n" , |
414 | acpi_gbl_function_exit_prefix); |
415 | } |
416 | |
417 | if (acpi_gbl_nesting_level) { |
418 | acpi_gbl_nesting_level--; |
419 | } |
420 | } |
421 | |
422 | ACPI_EXPORT_SYMBOL(acpi_ut_exit) |
423 | |
424 | /******************************************************************************* |
425 | * |
426 | * FUNCTION: acpi_ut_status_exit |
427 | * |
428 | * PARAMETERS: line_number - Caller's line number |
429 | * function_name - Caller's procedure name |
430 | * module_name - Caller's module name |
431 | * component_id - Caller's component ID |
432 | * status - Exit status code |
433 | * |
434 | * RETURN: None |
435 | * |
436 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is |
437 | * set in debug_level. Prints exit status also. |
438 | * |
439 | ******************************************************************************/ |
440 | void |
441 | acpi_ut_status_exit(u32 line_number, |
442 | const char *function_name, |
443 | const char *module_name, |
444 | u32 component_id, acpi_status status) |
445 | { |
446 | |
447 | /* Check if enabled up-front for performance */ |
448 | |
449 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { |
450 | if (ACPI_SUCCESS(status)) { |
451 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
452 | line_number, function_name, |
453 | module_name, component_id, "%s %s\n" , |
454 | acpi_gbl_function_exit_prefix, |
455 | acpi_format_exception(exception: status)); |
456 | } else { |
457 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
458 | line_number, function_name, |
459 | module_name, component_id, |
460 | "%s ****Exception****: %s\n" , |
461 | acpi_gbl_function_exit_prefix, |
462 | acpi_format_exception(exception: status)); |
463 | } |
464 | } |
465 | |
466 | if (acpi_gbl_nesting_level) { |
467 | acpi_gbl_nesting_level--; |
468 | } |
469 | } |
470 | |
471 | ACPI_EXPORT_SYMBOL(acpi_ut_status_exit) |
472 | |
473 | /******************************************************************************* |
474 | * |
475 | * FUNCTION: acpi_ut_value_exit |
476 | * |
477 | * PARAMETERS: line_number - Caller's line number |
478 | * function_name - Caller's procedure name |
479 | * module_name - Caller's module name |
480 | * component_id - Caller's component ID |
481 | * value - Value to be printed with exit msg |
482 | * |
483 | * RETURN: None |
484 | * |
485 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is |
486 | * set in debug_level. Prints exit value also. |
487 | * |
488 | ******************************************************************************/ |
489 | void |
490 | acpi_ut_value_exit(u32 line_number, |
491 | const char *function_name, |
492 | const char *module_name, u32 component_id, u64 value) |
493 | { |
494 | |
495 | /* Check if enabled up-front for performance */ |
496 | |
497 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { |
498 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
499 | line_number, function_name, module_name, |
500 | component_id, "%s %8.8X%8.8X\n" , |
501 | acpi_gbl_function_exit_prefix, |
502 | ACPI_FORMAT_UINT64(value)); |
503 | } |
504 | |
505 | if (acpi_gbl_nesting_level) { |
506 | acpi_gbl_nesting_level--; |
507 | } |
508 | } |
509 | |
510 | ACPI_EXPORT_SYMBOL(acpi_ut_value_exit) |
511 | |
512 | /******************************************************************************* |
513 | * |
514 | * FUNCTION: acpi_ut_ptr_exit |
515 | * |
516 | * PARAMETERS: line_number - Caller's line number |
517 | * function_name - Caller's procedure name |
518 | * module_name - Caller's module name |
519 | * component_id - Caller's component ID |
520 | * ptr - Pointer to display |
521 | * |
522 | * RETURN: None |
523 | * |
524 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is |
525 | * set in debug_level. Prints exit value also. |
526 | * |
527 | ******************************************************************************/ |
528 | void |
529 | acpi_ut_ptr_exit(u32 line_number, |
530 | const char *function_name, |
531 | const char *module_name, u32 component_id, u8 *ptr) |
532 | { |
533 | |
534 | /* Check if enabled up-front for performance */ |
535 | |
536 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { |
537 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
538 | line_number, function_name, module_name, |
539 | component_id, "%s %p\n" , |
540 | acpi_gbl_function_exit_prefix, ptr); |
541 | } |
542 | |
543 | if (acpi_gbl_nesting_level) { |
544 | acpi_gbl_nesting_level--; |
545 | } |
546 | } |
547 | |
548 | /******************************************************************************* |
549 | * |
550 | * FUNCTION: acpi_ut_str_exit |
551 | * |
552 | * PARAMETERS: line_number - Caller's line number |
553 | * function_name - Caller's procedure name |
554 | * module_name - Caller's module name |
555 | * component_id - Caller's component ID |
556 | * string - String to display |
557 | * |
558 | * RETURN: None |
559 | * |
560 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is |
561 | * set in debug_level. Prints exit value also. |
562 | * |
563 | ******************************************************************************/ |
564 | |
565 | void |
566 | acpi_ut_str_exit(u32 line_number, |
567 | const char *function_name, |
568 | const char *module_name, u32 component_id, const char *string) |
569 | { |
570 | |
571 | /* Check if enabled up-front for performance */ |
572 | |
573 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { |
574 | acpi_debug_print(ACPI_LV_FUNCTIONS, |
575 | line_number, function_name, module_name, |
576 | component_id, "%s %s\n" , |
577 | acpi_gbl_function_exit_prefix, string); |
578 | } |
579 | |
580 | if (acpi_gbl_nesting_level) { |
581 | acpi_gbl_nesting_level--; |
582 | } |
583 | } |
584 | |
585 | /******************************************************************************* |
586 | * |
587 | * FUNCTION: acpi_trace_point |
588 | * |
589 | * PARAMETERS: type - Trace event type |
590 | * begin - TRUE if before execution |
591 | * aml - Executed AML address |
592 | * pathname - Object path |
593 | * pointer - Pointer to the related object |
594 | * |
595 | * RETURN: None |
596 | * |
597 | * DESCRIPTION: Interpreter execution trace. |
598 | * |
599 | ******************************************************************************/ |
600 | |
601 | void |
602 | acpi_trace_point(acpi_trace_event_type type, u8 begin, u8 *aml, char *pathname) |
603 | { |
604 | |
605 | ACPI_FUNCTION_ENTRY(); |
606 | |
607 | acpi_ex_trace_point(type, begin, aml, pathname); |
608 | |
609 | #ifdef ACPI_USE_SYSTEM_TRACER |
610 | acpi_os_trace_point(type, begin, aml, pathname); |
611 | #endif |
612 | } |
613 | |
614 | ACPI_EXPORT_SYMBOL(acpi_trace_point) |
615 | |
616 | #endif |
617 | |