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