1 /* 2 * Copyright (c) 2014, STMicroelectronics International N.V. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #ifndef TEEC_TRACE_H 28 #define TEEC_TRACE_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include <string.h> 35 #include <stdio.h> 36 #include <stdint.h> 37 #ifdef RK_PRINT_TO_LOGCAT 38 #include <log/log.h> 39 #endif 40 41 #ifndef BINARY_PREFIX 42 #error "BINARY_PREFIX not defined" 43 #endif 44 45 /* 46 * Trace levels. 47 * 48 * ERROR is used when some kind of error has happened, this is most likely the 49 * print you will use most of the time when you report some kind of error. 50 * 51 * INFO is used when you want to print some 'normal' text to the user. 52 * This is the default level. 53 * 54 * DEBUG is used to print extra information to enter deeply in the module. 55 * 56 * FLOW is used to print the execution flox, typically the in/out of functions. 57 * 58 * */ 59 60 #define TRACE_ERROR 1 61 #define TRACE_INFO 2 62 #define TRACE_DEBUG 3 63 #define TRACE_FLOW 4 64 65 #if defined(DEBUGLEVEL_0) && !defined(DEBUGLEVEL) 66 #define DEBUGLEVEL TRACE_ERROR 67 #endif 68 69 #if defined(DEBUGLEVEL_1) && !defined(DEBUGLEVEL) 70 #define DEBUGLEVEL TRACE_ERROR 71 #endif 72 73 #if defined(DEBUGLEVEL_2) && !defined(DEBUGLEVEL) 74 #define DEBUGLEVEL TRACE_INFO 75 #endif 76 77 #if defined(DEBUGLEVEL_3) && !defined(DEBUGLEVEL) 78 #define DEBUGLEVEL TRACE_DEBUG 79 #endif 80 81 #if defined(DEBUGLEVEL_4) && !defined(DEBUGLEVEL) 82 #define DEBUGLEVEL TRACE_FLOW 83 #endif 84 85 #ifndef DEBUGLEVEL 86 /* Default debug level. */ 87 #define DEBUGLEVEL TRACE_INFO 88 #endif 89 90 #define TEEC_LOG_TAG "tee_client" 91 92 /* 93 * This define make sure that parameters are checked in the same manner as it 94 * is done in the normal printf function. 95 */ 96 #define __PRINTFLIKE(__fmt, __varargs) __attribute__\ 97 ((__format__(__printf__, __fmt, __varargs))) 98 99 void _dprintf(const char *function, int line, int level, const char *prefix, 100 const char *fmt, ...) __PRINTFLIKE(5, 6); 101 102 #ifdef RK_PRINT_TO_LOGCAT 103 #define dprintf(level, x...) do { \ 104 if ((level) <= DEBUGLEVEL) { \ 105 switch (level) { \ 106 case TRACE_ERROR: \ 107 __android_log_print(ANDROID_LOG_ERROR, TEEC_LOG_TAG, x); \ 108 break; \ 109 case TRACE_INFO: \ 110 __android_log_print(ANDROID_LOG_INFO, TEEC_LOG_TAG, x); \ 111 break; \ 112 case TRACE_DEBUG: \ 113 __android_log_print(ANDROID_LOG_DEBUG, TEEC_LOG_TAG, x); \ 114 break; \ 115 case TRACE_FLOW: \ 116 __android_log_print(ANDROID_LOG_VERBOSE, TEEC_LOG_TAG, x); \ 117 break; \ 118 default: \ 119 break; \ 120 } \ 121 } \ 122 } while (0) 123 #else 124 #define dprintf(level, x...) do { \ 125 if ((level) <= DEBUGLEVEL) { \ 126 _dprintf(__func__, __LINE__, level, \ 127 BINARY_PREFIX, x); \ 128 } \ 129 } while (0) 130 #endif 131 132 #define EMSG(fmt, ...) dprintf(TRACE_ERROR, fmt "\n", ##__VA_ARGS__) 133 #define IMSG(fmt, ...) dprintf(TRACE_INFO, fmt "\n", ##__VA_ARGS__) 134 #define DMSG(fmt, ...) dprintf(TRACE_DEBUG, fmt "\n", ##__VA_ARGS__) 135 #define FMSG(fmt, ...) dprintf(TRACE_FLOW, fmt "\n", ##__VA_ARGS__) 136 137 #define INMSG(fmt, ...) FMSG("> " fmt, ##__VA_ARGS__) 138 #define OUTMSG(fmt, ...) FMSG("< " fmt, ##__VA_ARGS__) 139 #define OUTRMSG(r) \ 140 do { \ 141 if (r) \ 142 EMSG("Function returns with [%d]", r); \ 143 OUTMSG("r=[%d]", r); \ 144 return r; \ 145 } while (0) 146 147 #ifdef RK_PRINT_TO_LOGCAT 148 #define dprintf_raw dprintf 149 #else 150 #define dprintf_raw(level, x...) do { \ 151 if ((level) <= DEBUGLEVEL) \ 152 _dprintf(0, 0, (level), BINARY_PREFIX, x); \ 153 } while (0) 154 #endif 155 156 #define EMSG_RAW(fmt, ...) dprintf_raw(TRACE_ERROR, fmt, ##__VA_ARGS__) 157 #define IMSG_RAW(fmt, ...) dprintf_raw(TRACE_INFO, fmt, ##__VA_ARGS__) 158 #define DMSG_RAW(fmt, ...) dprintf_raw(TRACE_DEBUG, fmt, ##__VA_ARGS__) 159 #define FMSG_RAW(fmt, ...) dprintf_raw(TRACE_FLOW, fmt, ##__VA_ARGS__) 160 161 /* 162 * This function will hex and ascii dump a buffer. 163 * 164 * Note that this function will only print if debug flag 165 * DEBUGLEVEL is INFO or FLOOD. 166 * 167 * @param bname Information string describing the buffer. 168 * @param buffer Pointer to the buffer. 169 * @param blen Length of the buffer. 170 * 171 * @return void 172 */ 173 void dump_buffer(const char *bname, const uint8_t *buffer, size_t blen); 174 175 #ifdef __cplusplus 176 } 177 #endif 178 179 #endif 180