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