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
17ACPI_MODULE_NAME("utdebug")
18
19#ifdef ACPI_DEBUG_OUTPUT
20static acpi_thread_id acpi_gbl_previous_thread_id = (acpi_thread_id) 0xFFFFFFFF;
21static const char *acpi_gbl_function_entry_prefix = "----Entry";
22static 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
36void 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
60void acpi_ut_track_stack_ptr(void)
61{
62	acpi_size current_sp;
63
64	if (&current_sp < acpi_gbl_lowest_stack_pointer) {
65		acpi_gbl_lowest_stack_pointer = &current_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
87static 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
128void ACPI_INTERNAL_VAR_XFACE
129acpi_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			    ("\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("%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("%-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
200ACPI_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 ******************************************************************************/
220void ACPI_INTERNAL_VAR_XFACE
221acpi_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
240ACPI_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 ******************************************************************************/
257void
258acpi_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
276ACPI_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 ******************************************************************************/
294void
295acpi_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
331void
332acpi_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
367void
368acpi_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
402void
403acpi_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
422ACPI_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 ******************************************************************************/
440void
441acpi_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(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(status));
463		}
464	}
465
466	if (acpi_gbl_nesting_level) {
467		acpi_gbl_nesting_level--;
468	}
469}
470
471ACPI_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 ******************************************************************************/
489void
490acpi_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
510ACPI_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 ******************************************************************************/
528void
529acpi_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
565void
566acpi_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
601void
602acpi_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
614ACPI_EXPORT_SYMBOL(acpi_trace_point)
615
616#endif
617