14ecca339SDan Handley /* 2ae770fedSYann Gautier * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved. 34ecca339SDan Handley * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 54ecca339SDan Handley */ 64ecca339SDan Handley 7870ce3ddSAntonio Nino Diaz #ifndef DEBUG_H 8870ce3ddSAntonio Nino Diaz #define DEBUG_H 94ecca339SDan Handley 1009d40e0eSAntonio Nino Diaz #include <lib/utils_def.h> 115a22e461SAntonio Nino Diaz 12cf24229eSSandrine Bailleux /* 13cf24229eSSandrine Bailleux * The log output macros print output to the console. These macros produce 14289c28a8SDan Handley * compiled log output only if the LOG_LEVEL defined in the makefile (or the 15289c28a8SDan Handley * make command line) is greater or equal than the level required for that 16289c28a8SDan Handley * type of log output. 17cf24229eSSandrine Bailleux * 18289c28a8SDan Handley * The format expected is the same as for printf(). For example: 194ecca339SDan Handley * INFO("Info %s.\n", "message") -> INFO: Info message. 20289c28a8SDan Handley * WARN("Warning %s.\n", "message") -> WARNING: Warning message. 214ecca339SDan Handley */ 22289c28a8SDan Handley 235a22e461SAntonio Nino Diaz #define LOG_LEVEL_NONE U(0) 245a22e461SAntonio Nino Diaz #define LOG_LEVEL_ERROR U(10) 255a22e461SAntonio Nino Diaz #define LOG_LEVEL_NOTICE U(20) 265a22e461SAntonio Nino Diaz #define LOG_LEVEL_WARNING U(30) 275a22e461SAntonio Nino Diaz #define LOG_LEVEL_INFO U(40) 285a22e461SAntonio Nino Diaz #define LOG_LEVEL_VERBOSE U(50) 29289c28a8SDan Handley 30d5dfdeb6SJulius Werner #ifndef __ASSEMBLER__ 3109d40e0eSAntonio Nino Diaz 3293c78ed2SAntonio Nino Diaz #include <cdefs.h> 332d7e8282SSoby Mathew #include <stdarg.h> 343e530d8eSAntonio Nino Diaz #include <stdbool.h> 35*f3ecd836SMaheedhar Bollapalli #include <stdint.h> 361319e7b1SSoby Mathew #include <stdio.h> 37289c28a8SDan Handley 3809d40e0eSAntonio Nino Diaz #include <drivers/console.h> 3909d40e0eSAntonio Nino Diaz 407f56e9a3SSoby Mathew /* 417f56e9a3SSoby Mathew * Define Log Markers corresponding to each log level which will 427f56e9a3SSoby Mathew * be embedded in the format string and is expected by tf_log() to determine 437f56e9a3SSoby Mathew * the log level. 447f56e9a3SSoby Mathew */ 457f56e9a3SSoby Mathew #define LOG_MARKER_ERROR "\xa" /* 10 */ 467f56e9a3SSoby Mathew #define LOG_MARKER_NOTICE "\x14" /* 20 */ 477f56e9a3SSoby Mathew #define LOG_MARKER_WARNING "\x1e" /* 30 */ 487f56e9a3SSoby Mathew #define LOG_MARKER_INFO "\x28" /* 40 */ 497f56e9a3SSoby Mathew #define LOG_MARKER_VERBOSE "\x32" /* 50 */ 507f56e9a3SSoby Mathew 51cf24229eSSandrine Bailleux /* 52cf24229eSSandrine Bailleux * If the log output is too low then this macro is used in place of tf_log() 53cf24229eSSandrine Bailleux * below. The intent is to get the compiler to evaluate the function call for 54cf24229eSSandrine Bailleux * type checking and format specifier correctness but let it optimize it out. 55cf24229eSSandrine Bailleux */ 56cf24229eSSandrine Bailleux #define no_tf_log(fmt, ...) \ 57cf24229eSSandrine Bailleux do { \ 585a22e461SAntonio Nino Diaz if (false) { \ 59cf24229eSSandrine Bailleux tf_log(fmt, ##__VA_ARGS__); \ 60cf24229eSSandrine Bailleux } \ 615a22e461SAntonio Nino Diaz } while (false) 62cf24229eSSandrine Bailleux 63289c28a8SDan Handley #if LOG_LEVEL >= LOG_LEVEL_ERROR 647f56e9a3SSoby Mathew # define ERROR(...) tf_log(LOG_MARKER_ERROR __VA_ARGS__) 65fd1360a3SPali Rohár # define ERROR_NL() tf_log_newline(LOG_MARKER_ERROR) 66289c28a8SDan Handley #else 67cf24229eSSandrine Bailleux # define ERROR(...) no_tf_log(LOG_MARKER_ERROR __VA_ARGS__) 68fd1360a3SPali Rohár # define ERROR_NL() 69289c28a8SDan Handley #endif 70289c28a8SDan Handley 71701b498cSJohn Tsichritzis #if LOG_LEVEL >= LOG_LEVEL_NOTICE 72701b498cSJohn Tsichritzis # define NOTICE(...) tf_log(LOG_MARKER_NOTICE __VA_ARGS__) 73701b498cSJohn Tsichritzis #else 74701b498cSJohn Tsichritzis # define NOTICE(...) no_tf_log(LOG_MARKER_NOTICE __VA_ARGS__) 75701b498cSJohn Tsichritzis #endif 76701b498cSJohn Tsichritzis 77289c28a8SDan Handley #if LOG_LEVEL >= LOG_LEVEL_WARNING 787f56e9a3SSoby Mathew # define WARN(...) tf_log(LOG_MARKER_WARNING __VA_ARGS__) 79289c28a8SDan Handley #else 80cf24229eSSandrine Bailleux # define WARN(...) no_tf_log(LOG_MARKER_WARNING __VA_ARGS__) 814ecca339SDan Handley #endif 824ecca339SDan Handley 83289c28a8SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 847f56e9a3SSoby Mathew # define INFO(...) tf_log(LOG_MARKER_INFO __VA_ARGS__) 85289c28a8SDan Handley #else 86cf24229eSSandrine Bailleux # define INFO(...) no_tf_log(LOG_MARKER_INFO __VA_ARGS__) 87289c28a8SDan Handley #endif 88289c28a8SDan Handley 89289c28a8SDan Handley #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 907f56e9a3SSoby Mathew # define VERBOSE(...) tf_log(LOG_MARKER_VERBOSE __VA_ARGS__) 91289c28a8SDan Handley #else 92cf24229eSSandrine Bailleux # define VERBOSE(...) no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__) 93289c28a8SDan Handley #endif 94289c28a8SDan Handley 95ae770fedSYann Gautier #if EARLY_CONSOLE 96ae770fedSYann Gautier #define EARLY_ERROR(...) ERROR(__VA_ARGS__) 97ae770fedSYann Gautier #else /* !EARLY_CONSOLE */ 98ae770fedSYann Gautier #define EARLY_ERROR(...) no_tf_log(LOG_MARKER_ERROR __VA_ARGS__) 99ae770fedSYann Gautier #endif /* EARLY_CONSOLE */ 100ae770fedSYann Gautier 1010ae4a3a3SManish Pandey const char *get_el_str(unsigned int el); 1020ae4a3a3SManish Pandey 1030c62883fSDouglas Raillard #if ENABLE_BACKTRACE 1040c62883fSDouglas Raillard void backtrace(const char *cookie); 1050c62883fSDouglas Raillard #else 1060c62883fSDouglas Raillard #define backtrace(x) 1070c62883fSDouglas Raillard #endif 1080c62883fSDouglas Raillard 109bd62ce98SGovindraj Raja void __dead2 el3_panic(void); 11017d07a55SGovindraj Raja void __dead2 elx_panic(void); 1113e530d8eSAntonio Nino Diaz 1123e530d8eSAntonio Nino Diaz #define panic() \ 1133e530d8eSAntonio Nino Diaz do { \ 1143e530d8eSAntonio Nino Diaz backtrace(__func__); \ 115831b0e98SJimmy Brisson console_flush(); \ 116bd62ce98SGovindraj Raja el3_panic(); \ 1173e530d8eSAntonio Nino Diaz } while (false) 118a43d431bSSoby Mathew 1197e619eccSGovindraj Raja #if CRASH_REPORTING 1207e619eccSGovindraj Raja /* -------------------------------------------------------------------- 1217e619eccSGovindraj Raja * do_lower_el_panic assumes it's called due to a panic from a lower EL 1227e619eccSGovindraj Raja * This call will not return. 1237e619eccSGovindraj Raja * -------------------------------------------------------------------- 1247e619eccSGovindraj Raja */ 1257e619eccSGovindraj Raja #define lower_el_panic() \ 1267e619eccSGovindraj Raja do { \ 1277e619eccSGovindraj Raja console_flush(); \ 12817d07a55SGovindraj Raja elx_panic(); \ 1297e619eccSGovindraj Raja } while (false) 1307e619eccSGovindraj Raja #else 1317e619eccSGovindraj Raja #define lower_el_panic() 1327e619eccSGovindraj Raja #endif 1337e619eccSGovindraj Raja 13451faada7SDouglas Raillard /* Function called when stack protection check code detects a corrupted stack */ 13551faada7SDouglas Raillard void __dead2 __stack_chk_fail(void); 13651faada7SDouglas Raillard 1377f56e9a3SSoby Mathew void tf_log(const char *fmt, ...) __printflike(1, 2); 138fd1360a3SPali Rohár void tf_log_newline(const char log_fmt[2]); 139*f3ecd836SMaheedhar Bollapalli void tf_log_set_max_level(uint32_t log_level); 140b79af934SSoby Mathew 141d5dfdeb6SJulius Werner #endif /* __ASSEMBLER__ */ 142870ce3ddSAntonio Nino Diaz #endif /* DEBUG_H */ 143