- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/modules/dbg/src/dbg.c

Go to the documentation of this file.

    00001
    00020 /*
    00021  * INCLUDE FILES
    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  * GLOBAL VARIABLES
    00043  ****************************************************************************************
    00044  */
    00046 struct debug_env_tag dbg_env;
    00047
    00048
    00049 /*
    00050  * FUNCTION DEFINITIONS
    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     // Fill-in the debug information structure
    00064     rxl_current_desc_get(&rhd, &rbd);
    00065
    00066     // Dump RX header descriptors
    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         // Push the DMA descriptor in the DMA engine
    00081         dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
    00082
    00083         // Poll for the DMA to be finished
    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     // Dump RX buffer descriptors
    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         // Push the DMA descriptor in the DMA engine
    00108         dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
    00109
    00110         // Poll for the DMA to be finished
    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         // Dump TX header descriptors
    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             // Push the DMA descriptor in the DMA engine
    00151             dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
    00152
    00153             // Poll for the DMA to be finished
    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             // Check if we have to upload the policy table too
    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                 // Push the DMA descriptor in the DMA engine
    00170                 dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
    00171
    00172                 // Poll for the DMA to be finished
    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             // Upload the TX payload descriptors
    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                 // Push the DMA descriptor in the DMA engine
    00191                 dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
    00192
    00193                 // Poll for the DMA to be finished
    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                 // Go to next TBD
    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     // Fill-in the debug information structure
    00242     dbg_info->error_type = type;
    00243     dbg_info->hw_diag = nxmac_debug_port_sel_get();
    00244
    00245     // Fill-in LA configuration
    00246     la_get_conf(&dbg_info->la_conf);
    00247
    00248     // Fill-in error message
    00249     co_pack8p(CPU2HW(dbg_info->error),(uint8_t *) msg, DBG_ERROR_TRACE_SIZE);
    00250
    00251     // Fill-in PHY channel information
    00252     phy_get_channel(&dbg_info->chan_info, PHY_PRIM);
    00253
    00254     // Profiling configuration information
    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     // Disable interrupts as we will poll
    00274     GLOBAL_INT_DISABLE();
    00275
    00276     // Only one DMA transfer will be needed to send the complete MSG.
    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     // Push the DMA descriptor in the DMA engine
    00284     dma_push(dma_desc, dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
    00285
    00286     // Poll for the DMA to be finished
    00287     dma_lli_poll(IPC_DMA_LLI_DBG_DUMP + DMA_LLI_IRQ_LSB);
    00288
    00289     // Reenable interrupts
    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     // Dump the embedded logic analyzer trace
    00296     la_dump_trace(dbg_dump);
    00297
    00298     // Dump the RX descriptors
    00299     dbg_dump_rx_desc(dbg_dump);
    00300
    00301     // Dump the TX descriptors
    00302     dbg_dump_tx_desc(dbg_dump);
    00303
    00304     // Dump the Key RAM content
    00305     dbg_dump_key_ram();
    00306
    00307     // Dump other debug information (HW and SW diags,
    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     // Reset the statistics
    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     // Restart the statistic measurement timer
    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     // Reset the environment
    00329     memset(&dbg_env, 0, sizeof(dbg_env));
    00330
    00331     #if NX_PRINT == NX_PRINT_IPC
    00332     // Init print
    00333     dbg_env.print_mutex = 0;
    00334     #endif
    00335
    00336     // Enable only warnings and more critical per default
    00337     dbg_env.filter_module = DBG_MOD_ALL;
    00338     dbg_env.filter_severity = DBG_SEV_IDX_ERR;
    00339
    00340     // Link error in case too many SW profiling diags are defined
    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  * FUNCTION DEFINITIONS
    00350  ****************************************************************************************
    00351  */
    00352 #if NX_DEBUG_DUMP
    00353 void dbg_error_save(const char *error)
    00354 {
    00355     // Fill-in error message
    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     // Dump the LA traces
    00365     if (dbg_dump != NULL)
    00366     {
    00367         // Dump all the debug information about the error
    00368         dbg_dump_error(HW2CPU(dbg_dump), msg, type);
    00369
    00370         // Disable the interrupts
    00371         GLOBAL_INT_DISABLE();
    00372
    00373         // Indicate the debug dump to the host
    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         // Poll for the DMA to be finished
    00381         dma_lli_poll(IPC_DMA_LLI_MSG + DMA_LLI_IRQ_LSB);
    00382
    00383         // Call the IPC message DMA handler
    00384         ipc_emb_msg_dma_int_handler();
    00385
    00386         // Restore the interrupts
    00387         GLOBAL_INT_RESTORE();
    00388     }
    00389     else
    00390     {
    00391         dbg(D_CRT "%s", msg);
    00392     }
    00393
    00394     // Restart the LA
    00395     la_start();
    00396 }
    00397 #endif
    00398
    00399
    00401