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 #define LOG_LEVEL_NONE 0
27 #define LOG_LEVEL_ERROR 10
28 #define LOG_LEVEL_NOTICE 20
29 #define LOG_LEVEL_WARNING 30
30 #define LOG_LEVEL_INFO 40
31 #define LOG_LEVEL_VERBOSE 50
32
33 /* If the LOG_LEVEL is not defined through the build */
34 #ifndef LOG_LEVEL
35 #ifdef NDEBUG /* Release */
36 #define LOG_LEVEL LOG_LEVEL_NOTICE
37 #else /* Debug */
38 #define LOG_LEVEL LOG_LEVEL_INFO
39 #endif
40 #endif
41
42 #ifndef __ASSEMBLER__
43 /*
44 * If the log output is too low then this macro is used in place of rmm_log()
45 * below. The intent is to get the compiler to evaluate the function call for
46 * type checking and format specifier correctness but let it optimize it out.
47 */
48 #define no_rmm_log(fmt, ...) \
49 do { \
50 if (false) { \
51 rmm_log(fmt, ##__VA_ARGS__); \
52 } \
53 } while (false)
54
55 #if LOG_LEVEL >= LOG_LEVEL_ERROR
56 # define ERROR(...) rmm_log(__VA_ARGS__)
57 #else
58 # define ERROR(...) no_rmm_log(__VA_ARGS__)
59 #endif
60
61 #if LOG_LEVEL >= LOG_LEVEL_NOTICE
62 # define NOTICE(...) rmm_log(__VA_ARGS__)
63 #else
64 # define NOTICE(...) no_rmm_log(__VA_ARGS__)
65 #endif
66
67 #if LOG_LEVEL >= LOG_LEVEL_WARNING
68 # define WARN(...) rmm_log(__VA_ARGS__)
69 #else
70 # define WARN(...) no_rmm_log(__VA_ARGS__)
71 #endif
72
73 #if LOG_LEVEL >= LOG_LEVEL_INFO
74 # define INFO(...) rmm_log(__VA_ARGS__)
75 #else
76 # define INFO(...) no_rmm_log(__VA_ARGS__)
77 #endif
78
79 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
80 # define VERBOSE(...) rmm_log(__VA_ARGS__)
81 #else
82 # define VERBOSE(...) no_rmm_log(__VA_ARGS__)
83 #endif
84
85 /*
86 * FIXME: Fully implement panic() handlers once it is decided how to panic.
87 */
88
89 #define panic() \
90 do { \
91 } while (true)
92
93 __attribute__((__format__(__printf__, 1, 2)))
rmm_log(const char * fmt,...)94 static inline void rmm_log(const char *fmt, ...)
95 {
96 va_list args;
97
98 va_start(args, fmt);
99 (void)vprintf(fmt, args);
100 va_end(args);
101 }
102
103 void backtrace(uintptr_t frame_pointer);
104
105 #endif /* __ASSEMBLER__ */
106 #endif /* DEBUG_H */
107