1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4  */
5 
6 #ifndef DEBUG_H
7 #define DEBUG_H
8 
9 #ifndef __ASSEMBLER__
10 #include <stdarg.h>
11 #include <stdbool.h>
12 #include <stdio.h>
13 #endif
14 #include <utils_def.h>
15 
16 /*
17  * The log output macros print output to the console. These macros produce
18  * compiled log output only if the LOG_LEVEL defined in the makefile (or the
19  * make command line) is greater or equal than the level required for that
20  * type of log output.
21  *
22  * The format expected is the same as for printf(). For example:
23  * INFO("Info %s.\n", "message")    -> INFO:    Info message.
24  * WARN("Warning %s.\n", "message") -> WARNING: Warning message.
25  */
26 
27 #define LOG_LEVEL_NONE			U(0)
28 #define LOG_LEVEL_ERROR			U(10)
29 #define LOG_LEVEL_NOTICE		U(20)
30 #define LOG_LEVEL_WARNING		U(30)
31 #define LOG_LEVEL_INFO			U(40)
32 #define LOG_LEVEL_VERBOSE		U(50)
33 
34 #ifndef LOG_LEVEL
35 #define LOG_LEVEL	LOG_LEVEL_VERBOSE
36 #endif
37 
38 #ifndef __ASSEMBLER__
39 /*
40  * If the log output is too low then this macro is used in place of rmm_log()
41  * below. The intent is to get the compiler to evaluate the function call for
42  * type checking and format specifier correctness but let it optimize it out.
43  */
44 #define no_rmm_log(fmt, ...)				\
45 	do {						\
46 		if (false) {				\
47 			rmm_log(fmt, ##__VA_ARGS__);	\
48 		}					\
49 	} while (false)
50 
51 #if LOG_LEVEL >= LOG_LEVEL_ERROR
52 # define ERROR(...)	rmm_log(__VA_ARGS__)
53 #else
54 # define ERROR(...)	no_rmm_log(__VA_ARGS__)
55 #endif
56 
57 #if LOG_LEVEL >= LOG_LEVEL_NOTICE
58 # define NOTICE(...)	rmm_log(__VA_ARGS__)
59 #else
60 # define NOTICE(...)	no_rmm_log(__VA_ARGS__)
61 #endif
62 
63 #if LOG_LEVEL >= LOG_LEVEL_WARNING
64 # define WARN(...)	rmm_log(__VA_ARGS__)
65 #else
66 # define WARN(...)	no_rmm_log(__VA_ARGS__)
67 #endif
68 
69 #if LOG_LEVEL >= LOG_LEVEL_INFO
70 # define INFO(...)	rmm_log(__VA_ARGS__)
71 #else
72 # define INFO(...)	no_rmm_log(__VA_ARGS__)
73 #endif
74 
75 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
76 # define VERBOSE(...)	rmm_log(__VA_ARGS__)
77 #else
78 # define VERBOSE(...)	no_rmm_log(__VA_ARGS__)
79 #endif
80 
81 /*
82  * FIXME: Fully implement panic() handlers once it is decided how to panic.
83  */
84 
85 #define panic()				\
86 	do {				\
87 	} while (true)
88 
89 __attribute__((__format__(__printf__, 1, 2)))
rmm_log(const char * fmt,...)90 static inline void rmm_log(const char *fmt, ...)
91 {
92 	va_list args;
93 
94 	va_start(args, fmt);
95 	(void)vprintf(fmt, args);
96 	va_end(args);
97 }
98 
99 #endif /* __ASSEMBLER__ */
100 #endif /* DEBUG_H */
101