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