xref: /arm-trusted-firmware/include/common/debug.h (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #ifndef DEBUG_H
8*91f16700Schasinglulu #define DEBUG_H
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <lib/utils_def.h>
11*91f16700Schasinglulu 
12*91f16700Schasinglulu /*
13*91f16700Schasinglulu  * The log output macros print output to the console. These macros produce
14*91f16700Schasinglulu  * compiled log output only if the LOG_LEVEL defined in the makefile (or the
15*91f16700Schasinglulu  * make command line) is greater or equal than the level required for that
16*91f16700Schasinglulu  * type of log output.
17*91f16700Schasinglulu  *
18*91f16700Schasinglulu  * The format expected is the same as for printf(). For example:
19*91f16700Schasinglulu  * INFO("Info %s.\n", "message")    -> INFO:    Info message.
20*91f16700Schasinglulu  * WARN("Warning %s.\n", "message") -> WARNING: Warning message.
21*91f16700Schasinglulu  */
22*91f16700Schasinglulu 
23*91f16700Schasinglulu #define LOG_LEVEL_NONE			U(0)
24*91f16700Schasinglulu #define LOG_LEVEL_ERROR			U(10)
25*91f16700Schasinglulu #define LOG_LEVEL_NOTICE		U(20)
26*91f16700Schasinglulu #define LOG_LEVEL_WARNING		U(30)
27*91f16700Schasinglulu #define LOG_LEVEL_INFO			U(40)
28*91f16700Schasinglulu #define LOG_LEVEL_VERBOSE		U(50)
29*91f16700Schasinglulu 
30*91f16700Schasinglulu #ifndef __ASSEMBLER__
31*91f16700Schasinglulu 
32*91f16700Schasinglulu #include <cdefs.h>
33*91f16700Schasinglulu #include <stdarg.h>
34*91f16700Schasinglulu #include <stdbool.h>
35*91f16700Schasinglulu #include <stdio.h>
36*91f16700Schasinglulu 
37*91f16700Schasinglulu #include <drivers/console.h>
38*91f16700Schasinglulu 
39*91f16700Schasinglulu /*
40*91f16700Schasinglulu  * Define Log Markers corresponding to each log level which will
41*91f16700Schasinglulu  * be embedded in the format string and is expected by tf_log() to determine
42*91f16700Schasinglulu  * the log level.
43*91f16700Schasinglulu  */
44*91f16700Schasinglulu #define LOG_MARKER_ERROR		"\xa"	/* 10 */
45*91f16700Schasinglulu #define LOG_MARKER_NOTICE		"\x14"	/* 20 */
46*91f16700Schasinglulu #define LOG_MARKER_WARNING		"\x1e"	/* 30 */
47*91f16700Schasinglulu #define LOG_MARKER_INFO			"\x28"	/* 40 */
48*91f16700Schasinglulu #define LOG_MARKER_VERBOSE		"\x32"	/* 50 */
49*91f16700Schasinglulu 
50*91f16700Schasinglulu /*
51*91f16700Schasinglulu  * If the log output is too low then this macro is used in place of tf_log()
52*91f16700Schasinglulu  * below. The intent is to get the compiler to evaluate the function call for
53*91f16700Schasinglulu  * type checking and format specifier correctness but let it optimize it out.
54*91f16700Schasinglulu  */
55*91f16700Schasinglulu #define no_tf_log(fmt, ...)				\
56*91f16700Schasinglulu 	do {						\
57*91f16700Schasinglulu 		if (false) {				\
58*91f16700Schasinglulu 			tf_log(fmt, ##__VA_ARGS__);	\
59*91f16700Schasinglulu 		}					\
60*91f16700Schasinglulu 	} while (false)
61*91f16700Schasinglulu 
62*91f16700Schasinglulu #if LOG_LEVEL >= LOG_LEVEL_ERROR
63*91f16700Schasinglulu # define ERROR(...)	tf_log(LOG_MARKER_ERROR __VA_ARGS__)
64*91f16700Schasinglulu # define ERROR_NL()	tf_log_newline(LOG_MARKER_ERROR)
65*91f16700Schasinglulu #else
66*91f16700Schasinglulu # define ERROR(...)	no_tf_log(LOG_MARKER_ERROR __VA_ARGS__)
67*91f16700Schasinglulu # define ERROR_NL()
68*91f16700Schasinglulu #endif
69*91f16700Schasinglulu 
70*91f16700Schasinglulu #if LOG_LEVEL >= LOG_LEVEL_NOTICE
71*91f16700Schasinglulu # define NOTICE(...)	tf_log(LOG_MARKER_NOTICE __VA_ARGS__)
72*91f16700Schasinglulu #else
73*91f16700Schasinglulu # define NOTICE(...)	no_tf_log(LOG_MARKER_NOTICE __VA_ARGS__)
74*91f16700Schasinglulu #endif
75*91f16700Schasinglulu 
76*91f16700Schasinglulu #if LOG_LEVEL >= LOG_LEVEL_WARNING
77*91f16700Schasinglulu # define WARN(...)	tf_log(LOG_MARKER_WARNING __VA_ARGS__)
78*91f16700Schasinglulu #else
79*91f16700Schasinglulu # define WARN(...)	no_tf_log(LOG_MARKER_WARNING __VA_ARGS__)
80*91f16700Schasinglulu #endif
81*91f16700Schasinglulu 
82*91f16700Schasinglulu #if LOG_LEVEL >= LOG_LEVEL_INFO
83*91f16700Schasinglulu # define INFO(...)	tf_log(LOG_MARKER_INFO __VA_ARGS__)
84*91f16700Schasinglulu #else
85*91f16700Schasinglulu # define INFO(...)	no_tf_log(LOG_MARKER_INFO __VA_ARGS__)
86*91f16700Schasinglulu #endif
87*91f16700Schasinglulu 
88*91f16700Schasinglulu #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
89*91f16700Schasinglulu # define VERBOSE(...)	tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
90*91f16700Schasinglulu #else
91*91f16700Schasinglulu # define VERBOSE(...)	no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
92*91f16700Schasinglulu #endif
93*91f16700Schasinglulu 
94*91f16700Schasinglulu const char *get_el_str(unsigned int el);
95*91f16700Schasinglulu 
96*91f16700Schasinglulu #if ENABLE_BACKTRACE
97*91f16700Schasinglulu void backtrace(const char *cookie);
98*91f16700Schasinglulu #else
99*91f16700Schasinglulu #define backtrace(x)
100*91f16700Schasinglulu #endif
101*91f16700Schasinglulu 
102*91f16700Schasinglulu void __dead2 el3_panic(void);
103*91f16700Schasinglulu void __dead2 elx_panic(void);
104*91f16700Schasinglulu 
105*91f16700Schasinglulu #define panic()				\
106*91f16700Schasinglulu 	do {				\
107*91f16700Schasinglulu 		backtrace(__func__);	\
108*91f16700Schasinglulu 		console_flush();	\
109*91f16700Schasinglulu 		el3_panic();		\
110*91f16700Schasinglulu 	} while (false)
111*91f16700Schasinglulu 
112*91f16700Schasinglulu #if CRASH_REPORTING
113*91f16700Schasinglulu /* --------------------------------------------------------------------
114*91f16700Schasinglulu  * do_lower_el_panic assumes it's called due to a panic from a lower EL
115*91f16700Schasinglulu  * This call will not return.
116*91f16700Schasinglulu  * --------------------------------------------------------------------
117*91f16700Schasinglulu  */
118*91f16700Schasinglulu #define	lower_el_panic()		\
119*91f16700Schasinglulu 	do {				\
120*91f16700Schasinglulu 		console_flush();	\
121*91f16700Schasinglulu 		elx_panic();		\
122*91f16700Schasinglulu 	} while (false)
123*91f16700Schasinglulu #else
124*91f16700Schasinglulu #define	lower_el_panic()
125*91f16700Schasinglulu #endif
126*91f16700Schasinglulu 
127*91f16700Schasinglulu /* Function called when stack protection check code detects a corrupted stack */
128*91f16700Schasinglulu void __dead2 __stack_chk_fail(void);
129*91f16700Schasinglulu 
130*91f16700Schasinglulu void tf_log(const char *fmt, ...) __printflike(1, 2);
131*91f16700Schasinglulu void tf_log_newline(const char log_fmt[2]);
132*91f16700Schasinglulu void tf_log_set_max_level(unsigned int log_level);
133*91f16700Schasinglulu 
134*91f16700Schasinglulu #endif /* __ASSEMBLER__ */
135*91f16700Schasinglulu #endif /* DEBUG_H */
136