1 /* 2 * Copyright (c) 2013-2020, 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 <stdio.h> 36 37 #include <drivers/console.h> 38 39 /* 40 * Define Log Markers corresponding to each log level which will 41 * be embedded in the format string and is expected by tf_log() to determine 42 * the log level. 43 */ 44 #define LOG_MARKER_ERROR "\xa" /* 10 */ 45 #define LOG_MARKER_NOTICE "\x14" /* 20 */ 46 #define LOG_MARKER_WARNING "\x1e" /* 30 */ 47 #define LOG_MARKER_INFO "\x28" /* 40 */ 48 #define LOG_MARKER_VERBOSE "\x32" /* 50 */ 49 50 /* 51 * If the log output is too low then this macro is used in place of tf_log() 52 * below. The intent is to get the compiler to evaluate the function call for 53 * type checking and format specifier correctness but let it optimize it out. 54 */ 55 #define no_tf_log(fmt, ...) \ 56 do { \ 57 if (false) { \ 58 tf_log(fmt, ##__VA_ARGS__); \ 59 } \ 60 } while (false) 61 62 #if LOG_LEVEL >= LOG_LEVEL_ERROR 63 # define ERROR(...) tf_log(LOG_MARKER_ERROR __VA_ARGS__) 64 # define ERROR_NL() tf_log_newline(LOG_MARKER_ERROR) 65 #else 66 # define ERROR(...) no_tf_log(LOG_MARKER_ERROR __VA_ARGS__) 67 # define ERROR_NL() 68 #endif 69 70 #if LOG_LEVEL >= LOG_LEVEL_NOTICE 71 # define NOTICE(...) tf_log(LOG_MARKER_NOTICE __VA_ARGS__) 72 #else 73 # define NOTICE(...) no_tf_log(LOG_MARKER_NOTICE __VA_ARGS__) 74 #endif 75 76 #if LOG_LEVEL >= LOG_LEVEL_WARNING 77 # define WARN(...) tf_log(LOG_MARKER_WARNING __VA_ARGS__) 78 #else 79 # define WARN(...) no_tf_log(LOG_MARKER_WARNING __VA_ARGS__) 80 #endif 81 82 #if LOG_LEVEL >= LOG_LEVEL_INFO 83 # define INFO(...) tf_log(LOG_MARKER_INFO __VA_ARGS__) 84 #else 85 # define INFO(...) no_tf_log(LOG_MARKER_INFO __VA_ARGS__) 86 #endif 87 88 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 89 # define VERBOSE(...) tf_log(LOG_MARKER_VERBOSE __VA_ARGS__) 90 #else 91 # define VERBOSE(...) no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__) 92 #endif 93 94 #if ENABLE_BACKTRACE 95 void backtrace(const char *cookie); 96 const char *get_el_str(unsigned int el); 97 #else 98 #define backtrace(x) 99 #endif 100 101 void __dead2 do_panic(void); 102 103 #define panic() \ 104 do { \ 105 backtrace(__func__); \ 106 console_flush(); \ 107 do_panic(); \ 108 } while (false) 109 110 /* Function called when stack protection check code detects a corrupted stack */ 111 void __dead2 __stack_chk_fail(void); 112 113 void tf_log(const char *fmt, ...) __printflike(1, 2); 114 void tf_log_newline(const char log_fmt[2]); 115 void tf_log_set_max_level(unsigned int log_level); 116 117 #endif /* __ASSEMBLER__ */ 118 #endif /* DEBUG_H */ 119