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.

C6678/1 EDMA Data Not Transferring to Expected Local Address

I hope that someone can point out my obvious mistake.

I have an C6671 and am using the pciedemo software to initiate a DMA transfer from the DSP to the LINUX GPP.

I see the data transfer from the DSP to the PCIe address space but I don't see the data transfer to the expected address on the LINUX side.

I'm betting that the data is being transferred to LINUX but just not at the expected location.  I think this because the LINUX system will go nuts when I try to transfer a huge chunk of memory (0x100000 bytes).  I suspect that the data is overwriting memory that is being used by the LINUX OS.

I'm using the HAL_readDMA and HAL_writeDMA functions provided in pciedemo.c.

Here is some of my driver's output which dumps some of the registers and virtual addresses:

I fill rDataVirt with 0xBB and I print it out after the DMA takes place.  The DMA takes place between the lines "totalBytes 0" and totalBytes 80".  As you will see the contents of rDataVirt are not overwritten (it's all 0xBBBBBBBB).

Feb 13 17:02:49 localhost kernel: Read binary from DSP ring buffer ...
Feb 13 17:02:49 localhost kernel: totalBytes    0
Feb 13 17:02:49 localhost kernel: wData         56900000
Feb 13 17:02:49 localhost kernel: rData         56F00000
Feb 13 17:02:49 localhost kernel: wDataVirt     ffff880056900000
Feb 13 17:02:49 localhost kernel: rDataVirt     ffff880056f00000
Feb 13 17:02:49 localhost kernel: HAL_readDMA
Feb 13 17:02:49 localhost kernel:       srcAddr 0x0C03002C
Feb 13 17:02:49 localhost kernel:       dstAddr 0x56F00000
Feb 13 17:02:49 localhost kernel:       size    0x00000050
Feb 13 17:02:49 localhost kernel:       flag    0x00000001
Feb 13 17:02:49 localhost kernel:       Setup OB Translation tables
Feb 13 17:02:49 localhost kernel:               pageBase        0x56000000
Feb 13 17:02:49 localhost kernel:               OB_OFFSET_INDEX(0)      0x56000001
Feb 13 17:02:49 localhost kernel:               OB_OFFSET_HI(0)         0x00000000
Feb 13 17:02:49 localhost kernel:               PARAM_0_DST     0x60F00000
Feb 13 17:02:49 localhost kernel:               PARAM_0_A_B_CNT 0x00010050
Feb 13 17:02:49 localhost kernel:               PARAM_0_SRC     0x0C03002C
Feb 13 17:02:49 localhost kernel:       dspAddr 0C03002C
Feb 13 17:02:49 localhost kernel:       bytes   00000050
Feb 13 17:02:49 localhost kernel:               BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB
Feb 13 17:02:49 localhost kernel:               BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB
Feb 13 17:02:49 localhost kernel:               BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB        BBBBBBBB
Feb 13 17:02:49 localhost kernel: totalBytes    80

When I examine memory on the DSP side with the emulator I see the data that I want to transfer from the DSP to the GPP at 0x0c03002c and 0x60f00000.

rDataVirt and rData are returned via a call to dma_alloc_coherent.

This line tells you that HAL_readDMA was called with the given arguments.

HAL_readDMA
       srcAddr 0x0C03002C
       dstAddr 0x56F00000
       size    0x00000050
       flag    0x00000001

Does anyone see what's going wrong?

Thanks,

Chris

  • Hi,

    Hope this helps as a general direction.

    EDMA will transfer data to/from memory based on "Physical" addresses. In your case, you will need to program the EDMA to transfer the data to the 'physical' address of the linux side buffer. The effect of your EDMA transfer is likely modifying(corrupting) some memory that is mapped to some Linux user or kernel space data object.

    Additionally you will also need to ensure that the physical memory that you are doing the transfer to on the linux side is physically contiguous. This means even if you have the start address of your buffer converted from virtual to physical, if the physical memory backing the buffer is not contiguous on Physical memory, and the size of EDMA transfer exceeds the physically contiguous region, you will again corrupt some adjacent memory that does not belong to your virtual address space buffer. Since ordinary virtually contiguous memory does not have to be "physically contiguous", unless you are doing something specific to allocate your linux receive buffer physically contiguously you will have this issue.

    So you do need to take care of both the phys contig allocation on linux side, as well as the ability to do virtual address to physical memory address conversion and pass this to the DSP side. I am not sure what type of middle ware you are using, between DSP and Linux host, but these are the minimum requirements you will need to take into account.

    Murat