00001 00053 #include "trace.h" 00054 00055 #if NX_TRACE 00056 00057 #include "ipc_shared.h" 00058 #include "hal_machw.h" 00059 00060 /* 00061 * GLOBAL VARIABLES 00062 ****************************************************************************** 00063 */ 00065 static bool trace_initialized = false; 00067 static bool trace_loop = false; 00068 00075 extern uint16_t _trace_start, _trace_end; 00076 00080 uint32_t trace_compo_level[TRACE_COMPO_MAX] __SHAREDRAM; 00081 00082 /* 00083 * DEFINES 00084 ****************************************************************************** 00085 */ 00087 #define TRACE_HEADER_LEN 4 00089 #define TRACE_MAX_PARAM 0xff 00091 #define TRACE_MAX_ID 0xffffff 00093 #define TRACE_LEN(i) (((i) >> 8) + TRACE_HEADER_LEN) 00094 00096 #define TRACE_LAST_ENTRY 0xffff 00098 #define TRACE_READY 0x1234 00100 #define TRACE_LOCKED 0xdead 00101 00102 /* 00103 * FUNCTION DEFINITIONS 00104 ****************************************************************************** 00105 */ 00106 void trace_init(bool force, bool loop) 00107 { 00108 if (trace_initialized && !force) 00109 return; 00110 00111 ipc_shared_env.trace_size = (&_trace_end - &_trace_start); 00112 ipc_shared_env.trace_offset = ((uint32_t)&_trace_start - 00113 (uint32_t)&ipc_shared_env.trace_offset) * CHAR_LEN; 00114 ipc_shared_env.trace_start = 0; 00115 ipc_shared_env.trace_end = ipc_shared_env.trace_size + 1; 00116 ipc_shared_env.trace_pattern = TRACE_READY; 00117 ipc_shared_env.trace_nb_compo = (TRACE_READY << 16) + TRACE_COMPO_MAX; 00118 ipc_shared_env.trace_offset_compo = ((uint32_t)trace_compo_level - 00119 (uint32_t)&ipc_shared_env.trace_offset_compo) * CHAR_LEN; 00120 00121 // set default level here as SHARED RAM is not initialized. 00122 trace_compo_level[TRACE_COMPO_KERNEL] = TRACE_KERNEL_DEFAULT; 00123 trace_compo_level[TRACE_COMPO_LMAC] = TRACE_LMAC_DEFAULT; 00124 trace_compo_level[TRACE_COMPO_CHAN] = TRACE_CHAN_DEFAULT; 00125 trace_compo_level[TRACE_COMPO_STA] = TRACE_STA_DEFAULT; 00126 trace_compo_level[TRACE_COMPO_AP] = TRACE_AP_DEFAULT; 00127 trace_compo_level[TRACE_COMPO_P2P] = TRACE_P2P_DEFAULT; 00128 trace_compo_level[TRACE_COMPO_MESH] = TRACE_MESH_DEFAULT; 00129 trace_compo_level[TRACE_COMPO_RTOS] = TRACE_RTOS_DEFAULT; 00130 trace_compo_level[TRACE_COMPO_APP] = TRACE_APP_DEFAULT; 00131 trace_compo_level[TRACE_COMPO_FHOST] = TRACE_FHOST_DEFAULT; 00132 trace_compo_level[TRACE_COMPO_TDLS] = TRACE_TDLS_DEFAULT; 00133 00134 trace_loop = loop; 00135 trace_initialized = true; 00136 } 00137 00138 00139 void trace(uint32_t id, uint16_t nb_param, uint16_t *param, bool trace_buf) 00140 { 00141 uint32_t end; 00142 uint32_t start; 00143 uint16_t *ptr; 00144 uint32_t ts; 00145 bool loop=0; 00146 00147 /* Needed to be able to trace within IT handler */ 00148 GLOBAL_INT_DISABLE(); 00149 00150 ipc_shared_env.trace_pattern = TRACE_LOCKED; 00151 00152 /* Ensure parameters provided are within expected range */ 00153 if (nb_param > TRACE_MAX_PARAM) 00154 nb_param = TRACE_MAX_PARAM; 00155 id &= TRACE_MAX_ID; 00156 00157 00158 end = ipc_shared_env.trace_end; 00159 start = ipc_shared_env.trace_start; 00160 ts = hal_machw_time(); 00161 ptr = &_trace_start; 00162 00163 if (end > ipc_shared_env.trace_size) 00164 { 00165 /* init case */ 00166 start = 0; 00167 end = 0; 00168 } 00169 else 00170 { 00171 if (end < start) 00172 loop = 1; 00173 00174 /* end is the index of the last trace point, so the next one will be 00175 at end + size of the trace */ 00176 end += TRACE_LEN(ptr[end]); 00177 00178 if (end + TRACE_HEADER_LEN + nb_param >= ipc_shared_env.trace_size) 00179 { 00180 if (!trace_loop) 00181 goto end; 00182 00183 if (end < ipc_shared_env.trace_size) 00184 ptr[end] = TRACE_LAST_ENTRY; 00185 00186 end = 0; 00187 start = TRACE_LEN(ptr[end]); 00188 loop = 1; 00189 } 00190 00191 while(loop && (int16_t)(start - end) < (nb_param + TRACE_HEADER_LEN)) 00192 { 00193 start += TRACE_LEN(ptr[start]); 00194 00195 if ((start >= ipc_shared_env.trace_size) || 00196 (ptr[start] == TRACE_LAST_ENTRY)) { 00197 start = 0; 00198 loop = 0; 00199 } 00200 } 00201 } 00202 00203 /* write trace header */ 00204 ptr += end; 00205 *ptr++ = (nb_param << 8) | (id >> 16); 00206 #ifdef CFG_RWX1 00207 _dsp_asm("nop"); 00208 #endif 00209 00210 *ptr++ = (id & 0xffff); 00211 #ifdef CFG_RWX1 00212 _dsp_asm("nop"); 00213 #endif 00214 00215 *ptr++ = (ts >> 16); 00216 #ifdef CFG_RWX1 00217 _dsp_asm("nop"); 00218 #endif 00219 00220 *ptr++ = (ts & 0xffff); 00221 #ifdef CFG_RWX1 00222 _dsp_asm("nop"); 00223 #endif 00224 00225 if (trace_buf) 00226 { 00227 uint32_t buf; 00228 buf = (param[1]) | (param[2] << 16); 00229 if (param[0] > ((TRACE_MAX_PARAM - 1) * 2)) 00230 //set bit 10 to indicate incomplete buffer 00231 *ptr = ((TRACE_MAX_PARAM - 1) * 2) + (1 << 10); 00232 else 00233 *ptr = param[0]; 00234 param = _PTR_ALIGN(buf); 00235 #ifndef CFG_RWTL 00236 // set bit 9 to indicate unaligned buffer 00237 *ptr |= ((buf & 0x1) << 9); 00238 #endif 00239 ptr++; 00240 nb_param--; 00241 } 00242 00243 for (int i = 0; i < nb_param ; i++) 00244 { 00245 *ptr++ = param[i]; 00246 #ifdef CFG_RWX1 00247 _dsp_asm("nop"); 00248 #endif 00249 } 00250 00251 ipc_shared_env.trace_start = start; 00252 ipc_shared_env.trace_end = end; 00253 00254 end: 00255 GLOBAL_INT_RESTORE(); 00256 ipc_shared_env.trace_pattern = TRACE_READY; 00257 } 00258 00259 00260 void trace_set_filter(unsigned int compo_id, unsigned int level) 00261 { 00262 if (compo_id == TRACE_COMPO_MAX) 00263 { 00264 unsigned int i; 00265 for (i = 0; i < TRACE_COMPO_MAX; i++) 00266 { 00267 trace_compo_level[i] = level; 00268 } 00269 } 00270 else if (compo_id < TRACE_COMPO_MAX) 00271 { 00272 trace_compo_level[compo_id] = level; 00273 } 00274 } 00275 00276 #endif // NX_TRACE 00277 00278 00279
1.6.1