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.

DSP MMU Error Fault!

Other Parts Discussed in Thread: OMAP3530

Hello.

I am using an OMAP3530 with a c64x+ dsp.  I have successfully been able to run 32-bit FFTs (using code from DSPLIB) on the dsp and read the results from the gpp, largely based on the Readwrite sample application with a few minimal modifications.  I have verified that the output is as expected for various test cases.

What is happening now is that I want to perform FFTs larger than the maximum size allowed by the optimized FFT functions from DSPLIB.  The best way to do this may be worth another whole separate post on its own (feel free to comment) but what I am trying to do for now is just complete the last few steps of an FFT of size 131072 by performinga bunch of FFTs of maximum size and combining them appropriately.  However, when I try to do this I get:

============= Sample Application : DFT ==========
Entered DFT_Create ()
Leaving DFT_Create ()
Entered DFT_Execute ()
DSP MMU Error Fault!  MMU_IRQSTATUS = [0x1]. Virtual DSP addr reference that generated the interrupt = [0xd9ce9940].
Leaving DFT_Execute ()
Entered DFT_Delete ()
Leaving DFT_Delete ()
=======================================================

Note that the Virtual address seems to be very different each time, almost random.

This also happens if i perform a bunch of smaller FFTs in a row (of course a lot more of them, a function of the sum of their sizes):

        for (i = 0; i < 462; ++i) {
            DSP_fft32x32_i (twiddle_array, N, readBuf, writeBuf) ;
        }

Decreasing the number to something like 50 (I forget the exact number) for FFTs of size 32, and it will be fine.

I have also tried calling the HAL_cache functions to refresh the cache in between each call.

What do I have to do in order to perform an unlimited number of operations on the dsp?

Thank you,

John

  • Hi John,

    What I understood from your post is:- You are sharing some buffers between the GPP and DSP so that you can access the results of application in  DSP core from ARM core. So I think, it might be a CMEM related issue. See http://processors.wiki.ti.com/index.php/CMEM_Overview

    May be, you need to change your current memory map configuration as the shared buffers might exceed its size limit.

    See the link:

    http://processors.wiki.ti.com/index.php/Changing_the_DVEVM_memory_map

    Please check if the above links solve your problem?

    Thanks,

    Honey S

  • John, DSP MMU Error Fault! MMU_IRQSTATUS = [0x1] occur when DSP is trying to access memory that has not been mapped into the MMU. This may also occur when DSP is trying to access memory not allocated by CMEM and which is not mapped. Sometimes your application is trying to access a memory not allowed to access or you may need to edit your current CMEM configuration. Please refer link:- http://processors.wiki.ti.com/index.php/DSP_MMU_Faults Thanks, Honey S
  • Hello Honey thank you for your reply.

    I had been creating a couple of buffers on the heap.  I switched their scope from function to file, and the MMU fault disappeared, however... that is only a workaround, not a solution.  This was similar to this (http://e2e.ti.com/support/dsp/omap_applications_processors/f/447/t/41804.aspx) but like I said it's not an appropriate solution in my opinio.

    I have a feeling that the link you sent me (which I have come across before in the past but for a different reason) may be helpful. (http://processors.wiki.ti.com/index.php/Changing_the_DVEVM_memory_map)

    The link here (http://processors.wiki.ti.com/index.php/DSP_MMU_Faults) does not seem like it will contain any answers to the specific problem. (Because as I noted, i was able to perform an FFT one time, but if doing many in a loop, the MMU table fault occured even though memory was being freed. Maybe I should use DSPBIOS MEM_alloc and MEM_free functions instead of malloc() and free()?)

    Would it be helpful to you if I pasted the whole file of my code?

    Right now, I am using DDR2 heap.  Should I allocate a dedicated memory portion for DSP heap?  I also have a feeling it is causing behavior of another problem I am now having.  This new (different) problem is as follows:


    void FFT_main (Int32 * readBuf, Int32 * writeBuf, Uint32 size)
    {
        Uint32 N, i, j, b;
        N = size / 8 ;
        if (N > 16384) {
            /*
             *  Create a new array twice as big as original number of samples
             *   in order to calculate alternating butterflies. (Currently not implemented)
             */
            prepared_data = malloc (size * 2) ;
            /*
             *  Transfer data to heap just for fun
              */
            for (i = 0; i < 16384; i++) {
                prepared_data[i] = readBuf[i] ;
            }
            twiddle_array = (Int32 *) malloc (size) ;
            gen_twiddle_fft32x32 (twiddle_array, 4096, 2147483647.5) ;
            DSP_fft32x32_i (twiddle_array, 4096, prepared_data, prepared_data + 8192) ;
            free(twiddle_array) ;
            for (i = 0; i < N*2; i++) {
                writeBuf[i] = 0 ;
            }
            for (i = 0; i < 4096; i++) {
                writeBuf[i] = prepared_data[i + 8192] ;
            }       
            free (prepared_data) ;
        }
        else {
            twiddle_array = (Int32 *) malloc (size) ;
            gen_twiddle_fft32x32 (twiddle_array, N, 2147483647.5) ;
            DSP_fft32x32_i (twiddle_array, N, readBuf, writeBuf) ;
            free(twiddle_array) ;
        }
    }


    The above red highlited portion...

    The code works fine (desired output) as it is.  BUT if that red segment is moved a to the top of "if" statement or even just a few lines above (before the FFT computation) the output is garbage.  Even though the data that writeBuf points to you wouldn't think gets altered just by looking at the code, and even though the DSP_fft32x32 function isn't using DDR2 (it uses only cache memory unless i'm mistaken).

  • I should note that I am giving DDR2 plenty of heap, from file dsplink-omap3530-base.tci:


    /*  ============================================================================

    *  MEM : Adjust DDR2

    *  ============================================================================

    */

    var DDR2 = prog.module("MEM").instance("DDR2");

    DDR2.base             = RESET_VECTOR.base + RESET_VECTOR.len ;

    DDR2.len              = 0x03FFFF80;

    DDR2.space            = "code/data";

    DDR2.createHeap       = true;

    DDR2.heapSize         = 0x3800000;

    DDR2.comment          = "DDR2";

  • I think I may have answered my own question (the second problem)... I think writeBuf is being overridden by the DDR heap because writeBuf's address is declared statically inside DDR2 space.

    This leaves me two options: create DSP heap somewhere else (how do i do this?) or put readBuf and writeBuf elsewhere instead of loaded into static memory location (by DSPLINK's PROC_write()) but I tried to do this before but was unable after looking at these instructions http://processors.wiki.ti.com/index.php/Changing_DSPLink_Memory_Map wouldn't work.  I will go back and try that again.

    Thank you again... and I will try to limit my questions to those where i seem to have exhausted all my options.

  • When I first started designing this, I ran into same problem as this person: http://e2e.ti.com/support/embedded/bios/f/355/t/95736.aspx.

    I needed to write a bigger file.

    I could not figure out how to reserve new memory (add an entry to CFG_OMAP3530_SHMEM.c).

    So instead, I just increased the size of DDR2 (a.k.a. "CODEMEMORYADDR").  And then I was able to modify the Readwrite sample applicaiton to write bigger files to shared memory.

    But now that memory seems to be overwrrited by the heap which uses part of the same memory space (see post above with excerpt from dsplink-omap3530-base.tci file).

    So now I think I must go back and do what I had tried to do before -- add a new entry to the memory table in order to ensure that data writted using PROC_write() will not be overwritten inadvertently by the DSP.

     

     

  • The page here http://processors.wiki.ti.com/index.php/Changing_DSPLink_Memory_Map says "Update $(DSPLINK)/config/all/CFG_[PLATFORM].c to modify the memory map as per the ARM-DSP split requirements."

    What are the requirements?  Where can I find such requirements?  Where can I find documentation that describes each memory region and why it is reserved / what it is reserved for?

  • So... my second problem... I figured it out.  The DSP's heap was indeed overwriting the data written by PROC_write().  I was able to successfully configure new blocks of memory via the instructions http://processors.wiki.ti.com/index.php/Changing_DSPLink_Memory_Map

    What I had missed before was where it said

    "The last address is 0x8FFFFFFF. So if the last 192MB is for DSP, you need to start DSP & shared memory space at:

    84000000 = 0x90000000 - C000000"

    ^That gave a little hint that there might be unaccounted-for space (and there was!) between 0x8C000000-0x8FFFFFFF.  I am now writing successfully to those regions, and the DSP heap is no longer disturbing my data.

    I would still like to get to the bottom of my first situation with the MMU fault, so I will post an update tomorrow about that.

    Thank you for any help, and thank you (TI in general) for maintaining this great resource to its customers & colleagues.