1*4de4bebcSJens Wiklander /* 2*4de4bebcSJens Wiklander * Copyright (c) 2014, STMicroelectronics International N.V. 3*4de4bebcSJens Wiklander * All rights reserved. 4*4de4bebcSJens Wiklander * 5*4de4bebcSJens Wiklander * Redistribution and use in source and binary forms, with or without 6*4de4bebcSJens Wiklander * modification, are permitted provided that the following conditions are met: 7*4de4bebcSJens Wiklander * 8*4de4bebcSJens Wiklander * 1. Redistributions of source code must retain the above copyright notice, 9*4de4bebcSJens Wiklander * this list of conditions and the following disclaimer. 10*4de4bebcSJens Wiklander * 11*4de4bebcSJens Wiklander * 2. Redistributions in binary form must reproduce the above copyright notice, 12*4de4bebcSJens Wiklander * this list of conditions and the following disclaimer in the documentation 13*4de4bebcSJens Wiklander * and/or other materials provided with the distribution. 14*4de4bebcSJens Wiklander * 15*4de4bebcSJens Wiklander * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16*4de4bebcSJens Wiklander * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*4de4bebcSJens Wiklander * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*4de4bebcSJens Wiklander * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19*4de4bebcSJens Wiklander * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20*4de4bebcSJens Wiklander * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21*4de4bebcSJens Wiklander * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22*4de4bebcSJens Wiklander * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23*4de4bebcSJens Wiklander * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24*4de4bebcSJens Wiklander * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25*4de4bebcSJens Wiklander * POSSIBILITY OF SUCH DAMAGE. 26*4de4bebcSJens Wiklander */ 27*4de4bebcSJens Wiklander #ifndef TRACE_H 28*4de4bebcSJens Wiklander #define TRACE_H 29*4de4bebcSJens Wiklander 30*4de4bebcSJens Wiklander #include <stdbool.h> 31*4de4bebcSJens Wiklander #include <stddef.h> 32*4de4bebcSJens Wiklander #include <compiler.h> 33*4de4bebcSJens Wiklander #include <trace_levels.h> 34*4de4bebcSJens Wiklander 35*4de4bebcSJens Wiklander #define MAX_PRINT_SIZE 256 36*4de4bebcSJens Wiklander #define MAX_FUNC_PRINT_SIZE 32 37*4de4bebcSJens Wiklander 38*4de4bebcSJens Wiklander #ifndef CFG_TRACE_LEVEL 39*4de4bebcSJens Wiklander #define CFG_TRACE_LEVEL TRACE_MAX 40*4de4bebcSJens Wiklander #endif 41*4de4bebcSJens Wiklander 42*4de4bebcSJens Wiklander /* 43*4de4bebcSJens Wiklander * Symbols provided by the entity that uses this API. 44*4de4bebcSJens Wiklander */ 45*4de4bebcSJens Wiklander extern const char trace_ext_prefix[]; 46*4de4bebcSJens Wiklander void trace_ext_puts(bool sync, const char *str); 47*4de4bebcSJens Wiklander int trace_ext_get_thread_id(void); 48*4de4bebcSJens Wiklander 49*4de4bebcSJens Wiklander /* Internal functions used by the macros below */ 50*4de4bebcSJens Wiklander void trace_printf(const char *func, int line, int level, bool sync, 51*4de4bebcSJens Wiklander const char *fmt, ...) __printf(5, 6); 52*4de4bebcSJens Wiklander 53*4de4bebcSJens Wiklander #define trace_printf_helper(level, ...) \ 54*4de4bebcSJens Wiklander trace_printf(__func__, __LINE__, (level), false, __VA_ARGS__) 55*4de4bebcSJens Wiklander 56*4de4bebcSJens Wiklander /* Formatted trace tagged with TRACE_ERROR level */ 57*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL < TRACE_ERROR) 58*4de4bebcSJens Wiklander #define EMSG(...) (void)0 59*4de4bebcSJens Wiklander #else 60*4de4bebcSJens Wiklander #define EMSG(...) trace_printf_helper(TRACE_ERROR, __VA_ARGS__) 61*4de4bebcSJens Wiklander #endif 62*4de4bebcSJens Wiklander 63*4de4bebcSJens Wiklander /* Formatted trace tagged with TRACE_INFO level */ 64*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL < TRACE_INFO) 65*4de4bebcSJens Wiklander #define IMSG(...) (void)0 66*4de4bebcSJens Wiklander #else 67*4de4bebcSJens Wiklander #define IMSG(...) trace_printf_helper(TRACE_INFO, __VA_ARGS__) 68*4de4bebcSJens Wiklander #endif 69*4de4bebcSJens Wiklander 70*4de4bebcSJens Wiklander /* Formatted trace tagged with TRACE_DEBUG level */ 71*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL < TRACE_DEBUG) 72*4de4bebcSJens Wiklander #define DMSG(...) (void)0 73*4de4bebcSJens Wiklander #else 74*4de4bebcSJens Wiklander #define DMSG(...) trace_printf_helper(TRACE_DEBUG, __VA_ARGS__) 75*4de4bebcSJens Wiklander #endif 76*4de4bebcSJens Wiklander 77*4de4bebcSJens Wiklander /* Formatted trace tagged with TRACE_FLOW level */ 78*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL < TRACE_FLOW) 79*4de4bebcSJens Wiklander #define FMSG(...) (void)0 80*4de4bebcSJens Wiklander #else 81*4de4bebcSJens Wiklander #define FMSG(...) trace_printf_helper(TRACE_FLOW, __VA_ARGS__) 82*4de4bebcSJens Wiklander #endif 83*4de4bebcSJens Wiklander 84*4de4bebcSJens Wiklander /* Formatted trace tagged with TRACE_FLOW level and prefix with '> ' */ 85*4de4bebcSJens Wiklander #define INMSG(...) FMSG("> " __VA_ARGS__) 86*4de4bebcSJens Wiklander /* Formatted trace tagged with TRACE_FLOW level and prefix with '< ' */ 87*4de4bebcSJens Wiklander #define OUTMSG(...) FMSG("< " __VA_ARGS__) 88*4de4bebcSJens Wiklander /* Formatted trace tagged with TRACE_FLOW level and prefix with '< ' and print 89*4de4bebcSJens Wiklander * an error message if r != 0 */ 90*4de4bebcSJens Wiklander #define OUTRMSG(r) \ 91*4de4bebcSJens Wiklander do { \ 92*4de4bebcSJens Wiklander OUTMSG("r=[%x]", r); \ 93*4de4bebcSJens Wiklander return r; \ 94*4de4bebcSJens Wiklander } while (0) 95*4de4bebcSJens Wiklander 96*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL < TRACE_DEBUG) 97*4de4bebcSJens Wiklander #define DHEXDUMP(buf, len) (void)0 98*4de4bebcSJens Wiklander #else 99*4de4bebcSJens Wiklander #define DHEXDUMP(buf, len) dhex_dump(__func__, __LINE__, TRACE_DEBUG, \ 100*4de4bebcSJens Wiklander buf, len) 101*4de4bebcSJens Wiklander void dhex_dump(const char *function, int line, int level, 102*4de4bebcSJens Wiklander const void *buf, int len); 103*4de4bebcSJens Wiklander #endif 104*4de4bebcSJens Wiklander 105*4de4bebcSJens Wiklander /*****************************************************************************/ 106*4de4bebcSJens Wiklander /* Trace api without trace formatting */ 107*4de4bebcSJens Wiklander 108*4de4bebcSJens Wiklander /* No formatted trace tagged with TRACE_ERROR level */ 109*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL < TRACE_ERROR) 110*4de4bebcSJens Wiklander #define EMSG_RAW(...) (void)0 111*4de4bebcSJens Wiklander #else 112*4de4bebcSJens Wiklander #define EMSG_RAW(...) trace_printf(NULL, 0, TRACE_ERROR, false, __VA_ARGS__) 113*4de4bebcSJens Wiklander #endif 114*4de4bebcSJens Wiklander 115*4de4bebcSJens Wiklander /* No formatted trace tagged with TRACE_INFO level */ 116*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL < TRACE_INFO) 117*4de4bebcSJens Wiklander #define IMSG_RAW(...) (void)0 118*4de4bebcSJens Wiklander #else 119*4de4bebcSJens Wiklander #define IMSG_RAW(...) trace_printf(NULL, 0, TRACE_INFO, false, __VA_ARGS__) 120*4de4bebcSJens Wiklander #endif 121*4de4bebcSJens Wiklander 122*4de4bebcSJens Wiklander /* No formatted trace tagged with TRACE_DEBUG level */ 123*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL < TRACE_DEBUG) 124*4de4bebcSJens Wiklander #define DMSG_RAW(...) (void)0 125*4de4bebcSJens Wiklander #else 126*4de4bebcSJens Wiklander #define DMSG_RAW(...) trace_printf(NULL, 0, TRACE_DEBUG, false, __VA_ARGS__) 127*4de4bebcSJens Wiklander #endif 128*4de4bebcSJens Wiklander 129*4de4bebcSJens Wiklander /* No formatted trace tagged with TRACE_FLOW level */ 130*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL < TRACE_FLOW) 131*4de4bebcSJens Wiklander #define FMSG_RAW(...) (void)0 132*4de4bebcSJens Wiklander #else 133*4de4bebcSJens Wiklander #define FMSG_RAW(...) trace_printf(NULL, 0, TRACE_FLOW, false, __VA_ARGS__) 134*4de4bebcSJens Wiklander #endif 135*4de4bebcSJens Wiklander 136*4de4bebcSJens Wiklander #if (CFG_TRACE_LEVEL == 0) 137*4de4bebcSJens Wiklander #define SMSG(...) (void)0 138*4de4bebcSJens Wiklander static inline void trace_set_level(int level __unused) 139*4de4bebcSJens Wiklander { 140*4de4bebcSJens Wiklander } 141*4de4bebcSJens Wiklander 142*4de4bebcSJens Wiklander static inline int trace_get_level(void) 143*4de4bebcSJens Wiklander { 144*4de4bebcSJens Wiklander return 0; 145*4de4bebcSJens Wiklander } 146*4de4bebcSJens Wiklander #else 147*4de4bebcSJens Wiklander /* 148*4de4bebcSJens Wiklander * Synchronised flushed trace, an Always message straight to HW trace IP. 149*4de4bebcSJens Wiklander * Current only supported inside OP-TEE kernel, will be just like an EMSG() 150*4de4bebcSJens Wiklander * in another context. 151*4de4bebcSJens Wiklander */ 152*4de4bebcSJens Wiklander #define SMSG(...) \ 153*4de4bebcSJens Wiklander trace_printf(__func__, __LINE__, TRACE_ERROR, true, __VA_ARGS__) 154*4de4bebcSJens Wiklander 155*4de4bebcSJens Wiklander /* Accessors */ 156*4de4bebcSJens Wiklander void trace_set_level(int level); 157*4de4bebcSJens Wiklander int trace_get_level(void); 158*4de4bebcSJens Wiklander 159*4de4bebcSJens Wiklander #endif /* CFG_TRACE_LEVEL */ 160*4de4bebcSJens Wiklander 161*4de4bebcSJens Wiklander #endif /* TRACE_H */ 162