This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

在TCI6638 K2K上用EDMA搬移数据出错



用的是Linux 3.14.36

在等SHADOW INTR的时候一直出现

[ 1625.087560] INFO: rcu_sched self-detected stall on CPU { 1}  (t=2100 jiffies)
[ 1625.096101] CPU: 1 PID: 984 Comm: test Tainted: G           O 3.14.36-gefefe1
[ 1625.104283] [<c001590c>] (unwind_backtrace) from [<c00125f8>] (show_stack+0x)
[ 1625.107575] INFO: rcu_sched detected stalls on CPUs/tasks: { 1} (detected by)
[ 1625.107578] Task dump for CPU 1:
[ 1625.107588] test            R running      0   984    974 0x00001002
[ 1625.107602] [<c04eaca0>] (__schedule) from [<00000000>] (  (null))
[ 1625.138050] [<c00125f8>] (show_stack) from [<c04e9070>] (dump_stack+0x78/0x9)
[ 1625.145266] [<c04e9070>] (dump_stack) from [<c0072140>] (rcu_check_callbacks)
[ 1625.153436] [<c0072140>] (rcu_check_callbacks) from [<c00320e4>] (update_pro)
[ 1625.162299] [<c00320e4>] (update_process_times) from [<c007ccd0>] (tick_sche)
[ 1625.171678] [<c007ccd0>] (tick_sched_handle.isra.14) from [<c007cd34>] (tick)
[ 1625.180713] [<c007cd34>] (tick_sched_timer) from [<c0046f34>] (__run_hrtimer)
[ 1625.188791] [<c0046f34>] (__run_hrtimer) from [<c0047b8c>] (hrtimer_interrup)
[ 1625.197046] [<c0047b8c>] (hrtimer_interrupt) from [<c03e5120>] (arch_timer_h)
[ 1625.205994] [<c03e5120>] (arch_timer_handler_phys) from [<c006bbbc>] (handle)
[ 1625.215548] [<c006bbbc>] (handle_percpu_devid_irq) from [<c0067fbc>] (generi)
[ 1625.224582] [<c0067fbc>] (generic_handle_irq) from [<c000f69c>] (handle_IRQ+)
[ 1625.232487] [<c000f69c>] (handle_IRQ) from [<c00085a8>] (gic_handle_irq+0x2c)
[ 1625.240043] [<c00085a8>] (gic_handle_irq) from [<c04ee640>] (__irq_svc+0x40/)
[ 1625.247509] Exception stack(0xc2c03e00 to 0xc2c03e48)
[ 1625.252547] 3e00: 00000001 00000000 c2c03ea4 fed00000 c2c03ea4 c2c03e70 00000
[ 1625.260708] 3e20: 00000005 0000ffff 00001000 00000000 fed00000 c2c03e4c fed04
[ 1625.268867] 3e40: 000d0013 ffffffff
[ 1625.272353] [<c04ee640>] (__irq_svc) from [<bf0c2914>] (edma3_get_hw_status+)
[ 1625.281219] [<bf0c2914>] (edma3_get_hw_status [edma_dev]) from [<bf0c2e58>] )
[ 1625.291987] [<bf0c2e58>] (edma_chain_example [edma_dev]) from [<bf0c2024>] ()
[ 1625.301714] [<bf0c2024>] (dma_ioctl [edma_dev]) from [<c010b3a8>] (do_vfs_io)
[ 1625.310139] [<c010b3a8>] (do_vfs_ioctl) from [<c010b59c>] (SyS_ioctl+0x34/0x)
[ 1625.317437] [<c010b59c>] (SyS_ioctl) from [<c000eda0>] (ret_fast_syscall+0x0)

代码是:

void edma_chain_example (void)
{
 edma3_Obj_t *hObj;
 edma3_Obj_t edmaObj;
 Uint16 status;
 edma3_hw_dma_channel_setup_t dmaHwSetup;
 edma3_hw_setup_t hwSetup;
 edma3_cmd_drae_t regionAccess;
 edma3_channel_attr_t chAttr;
 edma3_channel_attr_t chAttr1;
 edma3_channel_obj_t *hChannel;
 edma3_channel_obj_t *hChannel1;
 edma3_channel_obj_t chObj;
 edma3_channel_obj_t chObj1;
 edma3_cc_Param_regs_t *hParamBasic;
 edma3_cc_Param_regs_t *hParamBasic1;
 edma3_cc_Param_regs_t myParamSetup;
 edma3_cc_Param_regs_t myParamSetup1;
 edma3_cmd_intr_t regionIntr;
 edma3_channel_err_t chErrClear;
 int index;
 Uint8 passStatus;
 //int i = 0;

 /* Open Edma3 module */
 hObj = edma3_open (&edmaObj, EDMA3_INS, NULL, &status);
 if (hObj == NULL || status != edma_ok) {
 printk ("EDMA Open failed\n");
 return;
 }

 printk ("Get regs: %x\n", (unsigned int)hObj->regs);

 /* EDMA3 Setup */
 dmaHwSetup.paramNum = 0;
 dmaHwSetup.que = EDMA3_QUE_0;
 hwSetup.dma_chan_setup = &dmaHwSetup;
 hwSetup.qdma_chan_setup = NULL;
 status = edma3_hw_setup (hObj, &hwSetup);
 if (status != edma_ok) {
 printk ("Hardware setup failed\n");
 edma3_close (hObj);
 return;
 }

 /*DRAE enable(Bits 0-15) for the shadow region 5*/
 regionAccess.region = EDMA3_REGION_5;
 regionAccess.drae = 0xFFFF;
 regionAccess.draeh = 0;
 status = edma3_hw_control (hObj, EDMA3_CMD_DMAREGION_ENABLE, \
 &regionAccess);
 if (status != edma_ok) {
 printk("Edma region enable failed\n");
 return;
 }

 /*channel 0 open in context of shadow region 5*/
 chAttr.regionNum = EDMA3_REGION_5;
 chAttr.chaNum = 0;
 hChannel = edma3_channel_open(&chObj, EDMA3_INS, &chAttr, &status);
 if ((hChannel == NULL) || (status != edma_ok)) {
 printk ("Edma channel open failed\n");
 return;
 }

 /*obtain a hanle to parameter set 0*/
 hParamBasic = edma3_get_param_handle(hChannel, 0, &status);
 if (hParamBasic == NULL) {
 printk ("Edma get param handle for param entry 0 failed\n");
 return;
 }

 /*Setup the param set*/
 myParamSetup.opt = EDMA3_OPT_MAKE (EDMA3_ITCCH_DIS, \
 EDMA3_TCCH_EN, \
 EDMA3_ITCINT_DIS, \
 EDMA3_TCINT_EN, \
 8, \
 0, \
 0, \
 EDMA3_STATIC_DIS,\
 EDMA3_SYNC_AB, \
 EDMA3_ADDRMODE_INCR, \
 EDMA3_ADDRMODE_INCR);
 myParamSetup.src = (unsigned long)srcBuf;
 myParamSetup.a_b_cnt = EDMA3_CNT_MAKE (512,2);
 myParamSetup.dst = (unsigned long)dstBuf;
 myParamSetup.src_dst_bidx = EDMA3_BIDX_MAKE (512,512);
 myParamSetup.link_bcntrld = EDMA3_LINKBCNTRLD_MAKE(0xffff, 0);
 myParamSetup.src_dst_cidx = EDMA3_CIDX_MAKE(0,1);
 myParamSetup.ccnt = 1;

 status = edma3_param_setup(hParamBasic, &myParamSetup);
 if (status != edma_ok) {
 printk("Edma parameter entry setup is failed\n");
 return;
 }

 /*Channel 8 open in context of shadow region 5*/
 chAttr1.regionNum = EDMA3_REGION_5;
 chAttr1.chaNum = 8;

 hChannel1 = edma3_channel_open(&chObj1, EDMA3_INS, &chAttr1, &status);
 if (hChannel1 == NULL || status != edma_ok) {
 printk ("Edma Channel open failed\n");
 return;
 }

 hParamBasic1 = edma3_get_param_handle(hChannel1, 8 , &status);

 /* Setup the param set */
 myParamSetup1.opt = EDMA3_OPT_MAKE(EDMA3_ITCCH_DIS, \
 EDMA3_TCCH_EN, \
 EDMA3_ITCINT_DIS, \
 EDMA3_TCINT_EN, \
 1, \
 0, \
 0, \
 1,EDMA3_SYNC_AB, \
 EDMA3_ADDRMODE_INCR, \
 EDMA3_ADDRMODE_INCR);
 myParamSetup1.src = (unsigned long)srcBuf1;
 myParamSetup1.a_b_cnt = EDMA3_CNT_MAKE(512,2); 
 myParamSetup1.dst = (unsigned long)dstBuf1; 
 myParamSetup1.src_dst_bidx = EDMA3_BIDX_MAKE(512,512); 
 myParamSetup1.link_bcntrld = 
 EDMA3_LINKBCNTRLD_MAKE(EDMA3_LINK_NULL,0);
 myParamSetup1.src_dst_cidx = EDMA3_CIDX_MAKE(0,1); 
 myParamSetup1.ccnt = 1;

 status = edma3_param_setup(hParamBasic1, &myParamSetup1);
 if (status != edma_ok) {
 printk ("Edma parameter entry setup is failed\n");
 return;
 }

 /*Enable channel 0*/
 status = edma3_hw_channel_control(hChannel, EDMA3_CMD_CHANNEL_ENABLE, NULL);
 if (status != edma_ok) {
 printk ("Edma_channel enable command for channel 0 failed\n");
 return; 
 }

 /*Enable channel 8*/
 status = edma3_hw_channel_control(hChannel1, EDMA3_CMD_CHANNEL_ENABLE, 
 NULL);
 if (status != edma_ok) {
 printk ("Edma_channel enable command for channel 8 failed\n");
 return;
 }

 for (index = 0; index < 512; index ++) {
 srcBuf [index] = index;
 srcBuf1 [index] = index;
 dstBuf [index] = 0;
 dstBuf1 [index] = 0;
 }

 printk ("pid %x\n", hObj->regs->pid);
 regionIntr.region = EDMA3_REGION_5;
 edma3_get_hw_status (hObj, EDMA3_QUERY_INTRPEND, &regionIntr);
 printk ("-----intrLo:%x, Hi:%x\n", regionIntr.intr,regionIntr.intrh);

 /*Trigger Channel 0*/
 edma3_hw_channel_control(hChannel, EDMA3_CMD_CHANNEL_SET, NULL);

 regionIntr.region = EDMA3_REGION_5;
 mdelay(1);
 do {
 edma3_get_hw_status (hObj, EDMA3_QUERY_INTRPEND, &regionIntr);
 //if ((++i) >= 10000) {
 //printk ("regionIntr.intr %x, %x\n", regionIntr.intr,
 //regionIntr.intrh);
 //break;
 //}
 } while (!(regionIntr.intr & 0x100));

 /*Clear interrupt bit 8*/
 status = edma3_hw_control (hObj, EDMA3_CMD_INTRPEND_CLEAR,\
 &regionIntr);
 if (status != edma_ok) {
 printk ("Edma clear interrupt bit failed\n");
 //return;
 }

 passStatus = 1;
 printk ("dstBuf 512 %d\n", dstBuf [127]);
 printk ("dstBuf1 512 %d\n", dstBuf1 [127]);
 if (Verify_Transfer(512, 1, 1, 0, 0, 0, 0, srcBuf, dstBuf, 1) == 0) {
 passStatus = 0;
 }
 if (Verify_Transfer(512, 1, 1, 0, 0, 0, 0, srcBuf1, dstBuf1, 1) == 0) {
 passStatus = 0;
 }

 if (passStatus == 1) {
 printk ("Edma Chain Transfer passed\n");
 } else {
 printk ("Edma chain Transfer failed\n");
 }

 regionAccess.region = EDMA3_REGION_5;
 regionAccess.drae = 0xffff;
 regionAccess.draeh = 0;
 status = edma3_hw_control (hObj, EDMA3_CMD_DMAREGION_ENABLE, &regionAccess);

 chErrClear.missed = 1;
 chErrClear.secEvt = 1;
 
 edma3_hw_channel_control(hChannel, EDMA3_CMD_CHANNEL_DISABLE, NULL);
 edma3_hw_channel_control(hChannel, EDMA3_CMD_CHANNEL_CLEARERR, &chErrClear); 
 edma3_hw_channel_control(hChannel,EDMA3_CMD_CHANNEL_CLEAR, NULL);

 status = edma3_channel_close (hChannel);
 if (status != edma_ok) {
 printk ("Edma channel close failed\n");
 return;
 }

 status = edma3_close (hObj);
 if (status != edma_ok) {
 printk ("Edma module close failed\n");
 return;
 }

 return;
}