Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

memcpy, altera dma and tests...

Hi,

i'm trying to modify the memcpy function to decrease cpu usage (100% currently), while copying a huge quantity of data.

i'm actually using uClinux (nommu) with a nios2 on an 3c120 FPGA.

so i replace memcpy function in the file :

.../nios2-linux/linux-2.6/arch/nios2/lib/memcpy.c

by my function, using the altera DMA IP.

for now i'm working in "CT_BYTE" to avoid alignements problems, but i managed to make it works with word in a simple application beside.

my source code, with everything include (define from my nios2.h,...) is joined in the memcpy.c.txt

Currently it doesn't work at all, system don't boot at all.

but if i used the same thing in a standalone application to copy a 10Mb buffer to an other, it works !

1.5x faster in CT_BYTE mode and 10x faster in CT_WORD mode than with a "c for" loop...

it's the same speed as with memcpy, but if i use usleep(10) while i'm checking DM_STATUS register :

while ((inl(na_dma_fp+REG_DMA_STATUS) & ST_DONE) != ST_DONE) usleep(10);

cpu usage down to nearly 0%, while memcpy use 100%

any idea of what i'm doing wrong or what i forget to do ?

Thank you in advance,

FP.

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi fp.pasquier,

    Try to flush the cache. However I don't know how to do it under uClinux.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi FP,

    I have tried to do the memcpy by an alt_dma. However even if I flush and clear the cache, the system is very unstable. It freeze after I launch a telnet connection for exemple.

    If a Guru can have a look to my function below, it would be great !!!

    
    void *memcpy_dma(void *dstpp, const void *srcpp, int length)	
    {
    	unsigned int dst = (unsigned int) dstpp;
    	unsigned int src = (unsigned int) srcpp;
    	unsigned int len = (unsigned int) length;
    	
    	flush_dcache_range(src,src+len);
    	outl(CT_RESET,na_dma_memcpy + REG_DMA_CONTROL);
    	outl(CT_RESET,na_dma_memcpy + REG_DMA_CONTROL);
    	
    	outl(src,na_dma_memcpy + REG_DMA_READADDR);
    	outl(dst,na_dma_memcpy + REG_DMA_WRITEADDR);
    	outl(len,na_dma_memcpy + REG_DMA_LENGTH);
    	outl(CT_BYTE+CT_GO+CT_LEEN,na_dma_memcpy + REG_DMA_CONTROL);
    	while ((inl(na_dma_memcpy+REG_DMA_STATUS) & ST_DONE) != ST_DONE) udelay(1);
    	
    	outl(0,na_dma_memcpy + REG_DMA_CONTROL);
    	outl(0,na_dma_memcpy + REG_DMA_STATUS);
    	cache_clear(dst,len);
    	return (dst+len);
    }
    

    Bye !!!!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks for your attention,

    i've almost the same problem...

    Everything works fine in userspace application, but i don't manage to use my code into memcpy.c...

    May be because of parallels calls, i don't really understand in which context memcpy can be called...

    as actris say if someone know what i have to check/do to manage to copy data with the altera DMA in memcpy.c...

    Thank You.