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