00001
00020
00021
00022
00023
00024 #include "dbg.h"
00025 #include "dbg_profiling.h"
00026 #include "dbg_task.h"
00027 #include "la.h"
00028 #include "mm.h"
00029 #include "ipc_emb.h"
00030 #include "rxl_hwdesc.h"
00031 #include "txl_cntrl.h"
00032 #include "reg_mac_core.h"
00033 #include "ke_timer.h"
00034 #include "co_utils.h"
00035 #if NX_FULLY_HOSTED
00036 #include "fhost_ipc.h"
00037 #endif
00038
00039
00040
00041
00042
00043
00044
00046 struct debug_env_tag dbg_env;
00047
00048
00049
00050
00051
00052
00053 #if NX_DEBUG_DUMP
00054 static void dbg_dump_rx_desc(struct dbg_debug_dump_tag *dbg_dump)
00055 {
00056 uint32_t dst;
00057 uint32_t available;
00058 struct dma_desc *dma_desc = (struct dma_desc *) &(debug_info.dma_desc);
00059 struct dbg_debug_info_tag *dbg_info = &(debug_info.dbg_info);
00060 struct rx_hd *rhd;
00061 struct rx_pbd *rbd;
00062
00063
00064 rxl_current_desc_get(&rhd, &rbd);
00065
00066
00067 dbg_info->rhd_len = 0;
00068 dbg_info->rhd = CPU2HW(rhd);
00069 dst = CPU2HW(&dbg_dump->rhd_mem);
00070 available = DBG_RHD_MEM_LEN;
00071 dma_desc->length = sizeof_b(*rhd);
00072 dma_desc->ctrl = IPC_DMA_LLI_IRQ_EN |
00073 (IPC_DMA_LLI_DBG_DUMP << IPC_DMA_LLI_IRQ_POS);
00074 while ((rhd != NULL) && (available >= sizeof_b(*rhd)))
00075 {
00076 CHK_SHRAM_PTR(rhd);
00077 dma_desc->src = CPU2HW(rhd);
00078 dma_desc->dest = dst;
00079
00080
00081 dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
00082
00083
00084 dma_lli_poll(IPC_DMA_LLI_DBG_DUMP + DMA_LLI_IRQ_LSB);
00085
00086 dst += dma_desc->length;
00087 available -= dma_desc->length;
00088 dbg_info->rhd_len += dma_desc->length;
00089
00090 rhd = HW2CPU(rhd->next);
00091 }
00092
00093
00094 dbg_info->rbd_len = 0;
00095 dbg_info->rbd = CPU2HW(rbd);
00096 dst = CPU2HW(&dbg_dump->rbd_mem);
00097 available = DBG_RHD_MEM_LEN;
00098 dma_desc->length = sizeof_b(*rbd);
00099 dma_desc->ctrl = IPC_DMA_LLI_IRQ_EN |
00100 (IPC_DMA_LLI_DBG_DUMP << IPC_DMA_LLI_IRQ_POS);
00101 while ((rbd != NULL) && (available >= sizeof_b(*rbd)))
00102 {
00103 CHK_SHRAM_PTR(rbd);
00104 dma_desc->src = CPU2HW(rbd);
00105 dma_desc->dest = dst;
00106
00107
00108 dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
00109
00110
00111 dma_lli_poll(IPC_DMA_LLI_DBG_DUMP + DMA_LLI_IRQ_LSB);
00112
00113 dst += dma_desc->length;
00114 available -= dma_desc->length;
00115 dbg_info->rbd_len += dma_desc->length;
00116
00117 rbd = HW2CPU(rbd->next);
00118 }
00119 }
00120
00121
00122 static void dbg_dump_tx_desc(struct dbg_debug_dump_tag *dbg_dump)
00123 {
00124 uint32_t dst;
00125 uint32_t available;
00126 struct dma_desc *dma_desc = (struct dma_desc *) &(debug_info.dma_desc);
00127 struct dbg_debug_info_tag *dbg_info = &(debug_info.dbg_info);
00128 struct tx_hd *thd;
00129 struct tx_pbd *tbd;
00130 int i;
00131
00132 for (i = 0; i < NX_TXQ_CNT; i++)
00133 {
00134 txl_current_desc_get(i, &thd);
00135 dbg_info->thd[i] = CPU2HW(thd);
00136
00137
00138 dbg_info->thd_len[i] = 0;
00139 dst = CPU2HW(&dbg_dump->thd_mem[i]);
00140 available = DBG_THD_MEM_LEN;
00141 dma_desc->ctrl = IPC_DMA_LLI_IRQ_EN |
00142 (IPC_DMA_LLI_DBG_DUMP << IPC_DMA_LLI_IRQ_POS);
00143 while ((thd != NULL) && (available >= (sizeof_b(*thd) + sizeof_b(struct tx_policy_tbl))))
00144 {
00145 CHK_SHRAM_PTR(thd);
00146 dma_desc->src = CPU2HW(thd);
00147 dma_desc->dest = dst;
00148 dma_desc->length = sizeof_b(*thd);
00149
00150
00151 dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
00152
00153
00154 dma_lli_poll(IPC_DMA_LLI_DBG_DUMP + DMA_LLI_IRQ_LSB);
00155
00156 dst += dma_desc->length;
00157 available -= dma_desc->length;
00158 dbg_info->thd_len[i] += dma_desc->length;
00159
00160
00161 if (!((thd->macctrlinfo2 & 0x00200000) &&
00162 (thd->macctrlinfo2 & 0x00180000)))
00163 {
00164 CHK_SHRAM_PTR(HW2CPU(thd->policyentryaddr));
00165 dma_desc->src = thd->policyentryaddr;
00166 dma_desc->dest = dst;
00167 dma_desc->length = sizeof_b(struct tx_policy_tbl);
00168
00169
00170 dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
00171
00172
00173 dma_lli_poll(IPC_DMA_LLI_DBG_DUMP + DMA_LLI_IRQ_LSB);
00174
00175 dst += dma_desc->length;
00176 available -= dma_desc->length;
00177 dbg_info->thd_len[i] += dma_desc->length;
00178 }
00179
00180
00181 tbd = HW2CPU(thd->first_pbd_ptr);
00182 while ((tbd != NULL) && (available >= sizeof_b(*tbd)))
00183 {
00184 if (TST_SHRAM_PTR(tbd))
00185 break;
00186 dma_desc->src = CPU2HW(tbd);
00187 dma_desc->dest = dst;
00188 dma_desc->length = sizeof_b(*tbd);
00189
00190
00191 dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
00192
00193
00194 dma_lli_poll(IPC_DMA_LLI_DBG_DUMP + DMA_LLI_IRQ_LSB);
00195
00196 dst += dma_desc->length;
00197 available -= dma_desc->length;
00198 dbg_info->thd_len[i] += dma_desc->length;
00199
00200
00201 tbd = HW2CPU(tbd->next);
00202 }
00203
00204 if (thd->nextmpdudesc_ptr)
00205 thd = HW2CPU(thd->nextmpdudesc_ptr);
00206 else
00207 thd = HW2CPU(thd->nextfrmexseq_ptr);
00208 }
00209 }
00210 }
00211
00212 static void dbg_dump_key_ram(void)
00213 {
00214 #if NX_DEBUG_DUMP_KEY
00215 TRACE("Key RAM content:")
00216 for (int i = 0; i < MM_SEC_MAX_KEY_NBR; i++)
00217 {
00218 nxmac_encr_cntrl_pack(1, 0, 0, 0, i, 0, 0, 0, 0, 0);
00219 while(nxmac_new_read_getf());
00220
00221 TRACE("IDX: %d, CNTRL: %08lx, MAC=%pM", i, TR_32(nxmac_encr_cntrl_get()),
00222 TR_MAC(NXMAC_ENCR_MAC_ADDR_LOW_ADDR));
00223 TRACE_BUF("KEY: %pB16", 16, NXMAC_ENCR_KEY_0_ADDR);
00224 }
00225 #endif
00226 }
00227
00228 static void dbg_dump_info(struct dbg_debug_dump_tag *dbg_dump, char *msg, uint32_t type)
00229 {
00230 uint32_t dst = CPU2HW(&dbg_dump->dbg_info);
00231 struct dma_desc *dma_desc = (struct dma_desc *) &(debug_info.dma_desc);
00232 struct dbg_debug_info_tag *dbg_info = &(debug_info.dbg_info);
00233 uint32_t sw_diag_len = 0;
00234 #if NX_PROFILING_ON
00235 uint32_t sw_diag_addr = CPU2HW(dbg_info->sw_diag);
00236 #endif
00237 #if NX_PROFILING_ON
00238 int i;
00239 #endif
00240
00241
00242 dbg_info->error_type = type;
00243 dbg_info->hw_diag = nxmac_debug_port_sel_get();
00244
00245
00246 la_get_conf(&dbg_info->la_conf);
00247
00248
00249 co_pack8p(CPU2HW(dbg_info->error),(uint8_t *) msg, DBG_ERROR_TRACE_SIZE);
00250
00251
00252 phy_get_channel(&dbg_info->chan_info, PHY_PRIM);
00253
00254
00255 #if NX_PROFILING_ON
00256 for (i = 0; i < DBG_PROF_MAX; i++)
00257 {
00258 char tmp[64];
00259
00260 uint32_t len = dbg_snprintf(tmp,
00261 co_min(64, DBG_SW_DIAG_MAX_LEN - sw_diag_len),
00262 "%s\n", dbg_prof_conf[i]);
00263 if (len >= co_min(64, DBG_SW_DIAG_MAX_LEN - sw_diag_len))
00264 len = co_min(64, DBG_SW_DIAG_MAX_LEN - sw_diag_len) - 1;
00265 co_pack8p(sw_diag_addr, (uint8_t *)tmp, len);
00266 sw_diag_len += len;
00267 sw_diag_addr += len;
00268 }
00269 #endif
00270
00271 dbg_info->sw_diag_len = sw_diag_len;
00272
00273
00274 GLOBAL_INT_DISABLE();
00275
00276
00277 dma_desc->dest = dst;
00278 dma_desc->src = CPU2HW(dbg_info);
00279 dma_desc->length = sizeof_b(*dbg_info);
00280 dma_desc->ctrl = IPC_DMA_LLI_IRQ_EN |
00281 (IPC_DMA_LLI_DBG_DUMP << IPC_DMA_LLI_IRQ_POS);
00282
00283
00284 dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
00285
00286
00287 dma_lli_poll(IPC_DMA_LLI_DBG_DUMP + DMA_LLI_IRQ_LSB);
00288
00289
00290 GLOBAL_INT_RESTORE();
00291 }
00292
00293 void dbg_dump_error(struct dbg_debug_dump_tag *dbg_dump, char *msg, uint32_t type)
00294 {
00295
00296 la_dump_trace(dbg_dump);
00297
00298
00299 dbg_dump_rx_desc(dbg_dump);
00300
00301
00302 dbg_dump_tx_desc(dbg_dump);
00303
00304
00305 dbg_dump_key_ram();
00306
00307
00308 dbg_dump_info(dbg_dump, msg, type);
00309 }
00310 #endif
00311
00312 #if NX_SYS_STAT
00313 void dbg_sys_stat_reset(void)
00314 {
00315
00316 dbg_env.sys_stats.doze_time = 0;
00317 dbg_env.sys_stats.cpu_sleep_time = 0;
00318 dbg_env.sys_stats.stats_time = 0;
00319 dbg_env.sys_stats.start_time = dbg_sys_stats_time();
00320
00321
00322 ke_timer_set(DBG_SYS_STAT_TIMER, TASK_DBG, DBG_SYS_STAT_TIMEOUT);
00323 }
00324 #endif
00325
00326 void dbg_init(void)
00327 {
00328
00329 memset(&dbg_env, 0, sizeof(dbg_env));
00330
00331 #if NX_PRINT == NX_PRINT_IPC
00332
00333 dbg_env.print_mutex = 0;
00334 #endif
00335
00336
00337 dbg_env.filter_module = DBG_MOD_ALL;
00338 dbg_env.filter_severity = DBG_SEV_IDX_ERR;
00339
00340
00341 if (DBG_PROF_MAX > 32)
00342 {
00343 extern void too_many_sw_profiling_diags_are_defined(void);
00344 too_many_sw_profiling_diags_are_defined();
00345 }
00346 }
00347
00348
00349
00350
00351
00352 #if NX_DEBUG_DUMP
00353 void dbg_error_save(const char *error)
00354 {
00355
00356 memcpy(dbg_env.error, error, DBG_ERROR_TRACE_SIZE);
00357 }
00358
00359 void dbg_error_ind(char *msg, uint32_t type)
00360 {
00361 struct dbg_debug_dump_tag *dbg_dump =
00362 (struct dbg_debug_dump_tag *)ipc_emb_hostdbgdumpbuf_get();
00363
00364
00365 if (dbg_dump != NULL)
00366 {
00367
00368 dbg_dump_error(HW2CPU(dbg_dump), msg, type);
00369
00370
00371 GLOBAL_INT_DISABLE();
00372
00373
00374 #if NX_FULLY_HOSTED
00375 fhost_ipc_error_ind();
00376 #else
00377 ke_msg_send_basic(DBG_ERROR_IND, TASK_API, TASK_DBG);
00378 #endif
00379
00380
00381 dma_lli_poll(IPC_DMA_LLI_MSG + DMA_LLI_IRQ_LSB);
00382
00383
00384 ipc_emb_msg_dma_int_handler();
00385
00386
00387 GLOBAL_INT_RESTORE();
00388 }
00389 else
00390 {
00391 dbg(D_CRT "%s", msg);
00392 }
00393
00394
00395 la_start();
00396 }
00397 #endif
00398
00399
00401