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.

DSPLink MSGQ errant message problem

Other Parts Discussed in Thread: OMAP3530

I have a multiple threaded server app running on omap3530 dsp.  Its based off one of the sample programs. I forget which at this point.  Both Arm and DSP are cache enabled.

Initialization of both sides seems to be AOK.  I have a very simple test command to send a ping to the dsp and get the message looped back to the arm.

It will work sometimes once and then crash, sometimes several iterations and then crash. The crash is an abort exception in LIST_putTail() from inside LDRV_PutMsg().

I can see the message created correctly in POOLMEM section where I would expect it.  It comes back as expected.  When all is good, LDRV does it thing and ny handler MSGQ_get() is activated and I handle the message.  When it goes bad, the same happen except before my MSGQ-get() wakes up, the LDRV is processing another message. This one is apparently in the DSPLINKMEM section and has nonsense for contents. I have seen the MsgId field as both 0xff00 and 0xFb00.   PoolId is 0.  Transport?

I have commented all but one thread to simplify things.   I am stumped.  I will post shots of the message contents tomorrow.

thanks

Dave

  • Dave,

    Which version of DSPLink are you on

    Deepali

  • Hi Deepali,

    Its 1.61.03

    I did not get a chance to post details of the message contents.  Will do so in the AM.

    How are the sizes of the DSPLINKMEM and POOLMEM sections on the DSP side related to the allocation of the pools on the ARM side?

     

  • Dave

    The configuration of the memory sizes of DSPLINKMEM (memory for DSPLink internal data structures) and POOLMEM (memory for POOL allocated buffers) is present in the config file at $DSPLINK/config/all/CFG_<Platform>.c

    The configuration/sizes on DSP should match that.

    Deepali

     

  • Hi Deepali

    I have checked the memory sections against the file you mentioned and they are correct in the dsp side.  I verified the dynamic pool creation (code below) and it looks right to me and we are not exceeding the 0xD0000 range. NUM_POOLS == 9

         LINKCFG_config.dspConfigs [processorId]->linkDrvObjects [0].numPools =
                                                                         NUM_POOLS ;
     
         /* Copy the default pool configuration  */
         for ( i = 0;  i < NUM_POOLS;  i++) {
             memcpy (&LINKCFG_messageMultiPoolTables[0][i],
                      LINKCFG_config.dspConfigs [processorId]->poolTables[0],
                      sizeof (LINKCFG_Pool) );
              LINKCFG_messageMultiPoolTables[0][i].poolSize = 0x3000u ;
         }
         
         /* Audio Client Memory Pool size */
         //the '2' below should be the Audio AppNum
         LINKCFG_messageMultiPoolTables[0][2].poolSize = 0xAF000u ;
     
         LINKCFG_config.dspConfigs [processorId]->poolTables = (LINKCFG_Pool **)
                LINKCFG_messageMultiPoolTables ;

     

    The crash point is at the LIST_PutTail() in LDRV_MSGQ_Put().   I have also seen the procId variable get corrupted by the statement in blue.

        msg->dstId  = (MSGQ_Id) msgqQueue ;
        procId      = msgqQueue >> 16 ;
       
        if (IS_GPPID (procId)) {
            irqFlags = SYNC_SpinLockStartEx (LDRV_MSGQ_StateObj.lock) ;
            /* Place the message on the message list */
            msgqHandle = LDRV_MSGQ_StateObj.msgqHandles [(MSGQ_Id) msgqQueue] ;

            /* Check if the message queue exists to ensure that an asynchronous
             * late message arrival from the DSP does not crash the GPP.
             */
            if(testchunk != procId) SET_FAILURE_REASON;
           
            if ((msgqHandle != NULL) && (msgqHandle != (LDRV_MSGQ_Handle) TRUE)) {
                status = LIST_PutTail (msgqHandle->queue, (ListElement *) msg) ;
                SYNC_SpinLockEndEx (LDRV_MSGQ_StateObj.lock, irqFlags) ;

    stopping the code in LDRV_MSGQ_put() the msg parameter is as below for the response from the DSP. This is from the ISR before the application MSGQ_get() is activated.

    This one does not crash at the LIST_PutTail() call.  PoolId is 1 as expected. and the msg address is in the beginning of the second pool (pool 1) as we have configured the pools with 0x3000 length.

    After adding above to the queue and before leaving the calling function of LDRV_MSGQ_Put(),  this breakpoint is triggered again and msg now has the following.

    This messages location is in the shared memory section not the Pool.  On other occasions I have seen different contents. Previously the PoolId was  0 and message id was 0xfb00.  this message crashes the LIST_PutTail( ) call.

     

     

     

  • Some more info.

    Universally disabling caching on the Arm side of this app makes it work.

    Renabling cache makes it break on the second transaction. as in above post.

    msg in LDRV is as follows.  I notice the srcProcId is different

  • Some more info:

    in the routine:  ZCPYMQT_dpc (IN Pvoid refData)
    There are the following lines of code:

        if ((zcpyMqtState == NULL) || (zcpyMqtState->ctrlPtr == NULL)) {
            status = DSP_EINVALIDARG ;
            SET_FAILURE_REASON ;
        }

        while (   (DSP_SUCCEEDED (status))
               && (LDRV_MPLIST_isEmpty (dspId, (List *) &(ctrlPtr->fmDspList)) ==
                   FALSE)) {
            LDRV_MPCS_enter ((MPCS_ShObj *) &(ctrlPtr->csFmDspList)) ;
            LDRV_MPLIST_getHead  (dspId,
                                  ((List *) &(ctrlPtr->fmDspList)),
                                  (ListElement **) ((Pvoid) &recvMsg))
    ;
            LDRV_MPCS_leave ((MPCS_ShObj *) &(ctrlPtr->csFmDspList)) ;

            if (recvMsg != NULL) {
                /* Adjust the message size using the DSP MADU size */
                recvMsg->size = recvMsg->size * zcpyMqtState->dspMaduSize ;
                /* Adjust the pool Id */
                recvMsg->poolId = POOL_makePoolId (zcpyMqtState->dspId,
                                                   recvMsg->poolId) ;

    I have found that with caching enabled on the Arm side, If I put a breakpoint on the blue line (or earlier in the chain of ips/zcpy calls), I do not get the extra garbage message processing.  If I move the breakpoint to the red line, it fails consistently.

    If I disable data caching on the Arm it works consistenly without any breakpoints.

     

  •  

    Still more info

    I added cache invalidation in the critical region in entry above.  see red in code below. This fixes my abort exception.  Not sure why, since I thought DSPLink was not requiring any caching calls on the arm side.  Removing the cache_InvalDCache() call makes it break again reliably.

    I have read and been told several times now "

    DSPLink does no cache coherency on ARM side. There are no cache calls on ARM code. The memory is mapped as uncached.

    "

    What am I missing?

     

     

        while (   (DSP_SUCCEEDED (status))
               && (LDRV_MPLIST_isEmpty (dspId, (List *) &(ctrlPtr->fmDspList)) ==
                   FALSE)) {
            LDRV_MPCS_enter ((MPCS_ShObj *) &(ctrlPtr->csFmDspList)) ;
            //addded to solve Abort Exception in LDRV_MSSGQ_Put()
            cache_InvalDCache ();

            LDRV_MPLIST_getHead  (dspId,
                                  ((List *) &(ctrlPtr->fmDspList)),
                                  (ListElement **) ((Pvoid) &recvMsg)) ;
            LDRV_MPCS_leave ((MPCS_ShObj *) &(ctrlPtr->csFmDspList)) ;

            if (recvMsg != NULL) {

  • Dave,

    Are you using the correct mem=<> parameter in bootargs to reserve the shared memory for all the shared memory regions (e.g. DSPLINKMEM, DSPLINKMEM1, POOLMEM), as well as the DSP code/data regions (RESETCTRL, DDR2) away from Linux?

    http://processors.wiki.ti.com/index.php/Troubleshooting_DSPLink_configuration_issues#Problem:_I_see_a_crash_as_soon_as_I_run_a_DSPLink_sample.

    See here for details on the mem=<> parameter to be specified to bootargs.

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

    If Linux also somehow uses the memory that we've mapped as shared for DSPLink, it could go and corrupt it during its cache operations.

    Regards,

    Mugdha

  • Dave

    I apologize for the delay.

    I have seen that debugging especially with breakpoints for cache related issues do not give a correct view of the problem. Putting breakpoints do force cache and memory to get consistent and make original problem go away.

    The function in the blue line actually gets the message. The usage of the breakpoint seems to be refreshing the memory and allowing the message processing to go throw correctly.

    When the breakpoint is at the red line, there is no breakpoint which is forcing the message at blue line to get consistent with memory, so it is failing.

    Deepali

  • Hi Mugdah   not using linux

     

    Deepali,

    OK, so everything I guessed is correct.  BUT,  from your other posts and documentation Ive been pointed to,  the MSGQ operates with uncached memory and I should not have to worry about any caching statements. 

    So why is this required?    If it is required?  why did "I"  have to add it to the code? 

     

    thanks

    Dave

  • Dave,

    Which OS are you on?

    On Linux, there are two parts on this

    1) Reserving memory from OS for DSP use. This is done in Linux using the mem= bootargs option which reserves the memory such that Linux cannot use it.

    2) Re-mapping the memory reserved for DSP in step 1 as un-cached and using it. This is done in Linux by mapping the memory as un-cached by using the ioremap_nocache API.

    The steps are done differently on different OS. I have shown Linux as a reference.

    The problem that you are seeing seems like something incorrect in step 1 or step 2 in the OS in which you are on.

    Deepali

  • Deepali,

    We are on Threadex.  I dont know how, where or even if what you mention is being done, although searching the sources for 'uncached' shows it being used in the MEM module.IIRC.

    As I mentioned on my other thread about the Errant MSGQ message, the addition of the InvalDCache() call fixed things.   Looking for some feedback from TI on that.

  • Dave,

    The HLOS code of DSPLink completely lacks cache coherence calls. Just adding one API InvalDCache in MSGQ will not add cache coherency support on HLOS. Lack of the cache coherence API means that there will be bugs hidden in the code which need cache coherence and will fail in scenarios where the API's are missing, This code is not production quality and cannot be put in a system. I would not advise you to go with this code in your system.

    The correct solution would be find out why you need a cache coherence call at all?

    Deepali

  • Thats kind of disturbing news.  Which modules exactly are you warning me to now use?  I thought DSPLink was touted as production ready to be used in customer solutions.

    I am rather confused now.  I thought you had mentioned earlier that the Arm side of DSPLink uses uncached memory and therefore requires no caching calls. 

    Perhaps I am reading your above post incorrectly.  Can you please clarify.

    Does enabling caching in the application that utilizes DSPLink break DSPLink?  I have certainly seen no warnings about this.

    Our application does in fact enable caching in both the Arm and DSP side, but that occurs after the DSPLink initialization and PROC_Load, etc.

    IIRC, not enabling caching also fixed this particular problem,  but it is not a solution in the large picture.

    The DSPLINKMEM and DSPLINKMEM1 sections are in a space that is cached in the DSP side.  But except for the addresses and sizes this is consistent with instructions in

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

     

    Here is my mapping inCFG_OMAP3530_SHMEM.c

    I notice now that my RESETCTRL and DDR sections are also shared.    Is this wrong?  Bad?

     

    #define  RSTENTRYID         0u
    #define  RESETCTRLADDR      0x87E00000u
    #define  RESETCTRLSIZE      0x80u

    /** ============================================================================
     *  @name   CODEMEMORYADDR/CODEMEMORYSIZE
     *
     *  @desc   Indicates startaddress/size for dsplink code region.
     *  ============================================================================
     */
    #define  CODEENTRYID        1u
    #define  CODEMEMORYADDR     (RESETCTRLADDR + RESETCTRLSIZE)
    #define  CODEMEMORYSIZE     0xFFF80u

    /** ============================================================================
     *  @name   SHAREDENTRYID/SHAREDMEMORYADDR/SHAREDMEMORYSIZE
     *
     *  @desc   Indicates startaddress/size for dsplink shared memory region.
     *  ============================================================================
     */
    #define  SHAREDENTRYID0     2u
    #define  SHAREDMEMORYADDR0  (CODEMEMORYADDR + CODEMEMORYSIZE)
    #define  SHAREDMEMORYSIZE0  0x5000u

    /** ============================================================================
     *  @name   SHAREDENTRYID/SHAREDMEMORYADDR/SHAREDMEMORYSIZE
     *
     *  @desc   Indicates startaddress/size for dsplink shared memory region.
     *  ============================================================================
     */
    #define  SHAREDENTRYID1     3u
    #define  SHAREDMEMORYADDR1  (SHAREDMEMORYADDR0 + SHAREDMEMORYSIZE0)
    #define  SHAREDMEMORYSIZE1  0x2B000u

    /** ============================================================================
     *  @name   POOLMEMORYADDR/POOLMEMORYSIZE
     *
     *  @desc   Indicates startaddress/size for dsplink POOL memory region.
     *  ============================================================================
     */
    #define  POOLENTRYID        4u
    #define  POOLMEMORYADDR     (SHAREDMEMORYADDR1 + SHAREDMEMORYSIZE1)
    #define  POOLMEMORYSIZE     0x000D0000u

    STATIC LINKCFG_MemEntry  LINKCFG_memTable_00 [] =
    {
        {
            RSTENTRYID,                        /* ENTRY          : Entry number */
            "RESETCTRL",                       /* NAME           : Name of the memory region */
            RESETCTRLADDR,                     /* ADDRPHYS       : Physical address */
            RESETCTRLADDR,                     /* ADDRDSPVIRT    : DSP virtual address */
            (Uint32) -1u,                      /* ADDRGPPVIRT    : GPP virtual address (if known) */
            RESETCTRLSIZE,                     /* SIZE           : Size of the memory region */
            TRUE,                              /* SHARED         : Shared access memory? */
            FALSE,                             /* SYNCD          : Synchornized? */
        },
        {
            CODEENTRYID,                       /* ENTRY          : Entry number */
            "DDR2",                            /* NAME           : Name of the memory region */
            CODEMEMORYADDR,                    /* ADDRPHYS       : Physical address */
            CODEMEMORYADDR,                    /* ADDRDSPVIRT    : DSP virtual address */
            (Uint32) -1u,                      /* ADDRGPPVIRT    : GPP virtual address (if known) */
            CODEMEMORYSIZE,                    /* SIZE           : Size of the memory region */
            TRUE,                              /* SHARED         : Shared access memory? */
            FALSE,                             /* SYNCD          : Synchornized? */
        },
        {
            SHAREDENTRYID0,                   /* ENTRY          : Entry number */
            "DSPLINKMEM",                     /* NAME           : Name of the memory region */
            SHAREDMEMORYADDR0,                /* ADDRPHYS       : Physical address */
            SHAREDMEMORYADDR0,                /* ADDRDSPVIRT    : DSP virtual address */
           (Uint32) -1u,                      /* ADDRGPPVIRT    : GPP virtual address (if known) */
            SHAREDMEMORYSIZE0,                /* SIZE           : Size of the memory region */
            TRUE,                             /* SHARED         : Shared access memory? */
            FALSE,                            /* SYNCD          : Synchornized? */
        },
        {
            SHAREDENTRYID1,                   /* ENTRY          : Entry number */
            "DSPLINKMEM1",                    /* NAME           : Name of the memory region */
            SHAREDMEMORYADDR1,                /* ADDRPHYS       : Physical address */
            SHAREDMEMORYADDR1,                /* ADDRDSPVIRT    : DSP virtual address */
            (Uint32) -1u,                     /* ADDRGPPVIRT    : GPP virtual address (if known) */
            SHAREDMEMORYSIZE1,                /* SIZE           : Size of the memory region */
            TRUE,                             /* SHARED         : Shared access memory? */
            FALSE,                            /* SYNCD          : Synchornized? */
        },
        {
            POOLENTRYID,                       /* ENTRY          : Entry number */
            "POOLMEM",                         /* NAME           : Name of the memory region */
            POOLMEMORYADDR,                    /* ADDRPHYS       : Physical address */
            POOLMEMORYADDR,                    /* ADDRDSPVIRT    : DSP virtual address */
            (Uint32) -1u,                      /* ADDRGPPVIRT    : GPP virtual address (if known) */
            POOLMEMORYSIZE,                    /* SIZE           : Size of the memory region */
            TRUE,                              /* SHARED         : Shared access memory? Logically */
            FALSE,                             /* SYNCD          : Synchornized? */
        },
        {
            5,                     /* ENTRY          : Entry number */
            "DSPIRAM",             /* NAME           : Name of the memory region */
            0x5c7f8000,            /* ADDRPHYS       : Physical address */
            0x107f8000,            /* ADDRDSPVIRT    : DSP virtual address */
            (Uint32) -1,           /* ADDRGPPVIRT    : GPP virtual address (if known) */
            0x00018000,            /* SIZE           : Size of the memory region */
            TRUE,                  /* SHARED         : Shared access memory? */
            FALSE                  /* SYNCD          : Synchornized? */
        },
        {
            6,                     /* ENTRY          : Entry number */
            "DSPL1PRAM",           /* NAME           : Name of the memory region */
            0x5cE00000,            /* ADDRPHYS       : Physical address */
            0x10E00000,            /* ADDRDSPVIRT    : DSP virtual address */
            (Uint32) -1,           /* ADDRGPPVIRT    : GPP virtual address (if known) */
            0x00008000,            /* SIZE           : Size of the memory region */
            TRUE,                  /* SHARED         : Shared access memory? */
            FALSE                  /* SYNCD          : Synchornized? */
        },
        {
            7,                     /* ENTRY          : Entry number */
            "DSPL1DRAM",           /* NAME           : Name of the memory region */
            0x5cF04000,            /* ADDRPHYS       : Physical address */
            0x10F04000,            /* ADDRDSPVIRT    : DSP virtual address */
            (Uint32) -1,           /* ADDRGPPVIRT    : GPP virtual address (if known) */
            0x00014000,            /* SIZE           : Size of the memory region */
            TRUE,                  /* SHARED         : Shared access memory? */
            FALSE                  /* SYNCD          : Synchornized? */
        },
        {
            8,                     /* ENTRY          : Entry number */
            "L4_CORE",             /* NAME           : Name of the memory region */
            0x48000000,            /* ADDRPHYS       : Physical address */
            0x48000000,            /* ADDRDSPVIRT    : DSP virtual address */
            (Uint32) -1,           /* ADDRGPPVIRT    : GPP virtual address (if known) */
            0x01000000,            /* SIZE           : Size of the memory region */
            FALSE,                 /* SHARED         : Shared access memory? */
            FALSE                  /* SYNCD          : Synchornized? */
        },
        {
            9,                     /* ENTRY          : Entry number */
            "L4_PER",              /* NAME           : Name of the memory region */
            0x49000000,            /* ADDRPHYS       : Physical address */
            0x49000000,            /* ADDRDSPVIRT    : DSP virtual address */
            (Uint32) -1,           /* ADDRGPPVIRT    : GPP virtual address (if known) */
            0x00100000,            /* SIZE           : Size of the memory region */
            FALSE,                 /* SHARED         : Shared access memory? */
            FALSE                  /* SYNCD          : Synchornized? */
        }
    } ;

     

  • Dave,

    DSPLink requires the following memory regions to be in non-cached memory on the HLOS-side:

    DSPLINKMEM, DSPLINKMEM1, POOLMEM, DDR2, RESETCTRL.

    Usually, the DSPLink port for a particular OS ensures that these are in non-cached area on the
    ARM-side. On the DSP side, these same regions are cacheable.

    On Linux, these regions are ensured to be non-cacheable by removing them from the OS using mem=<> bootargs and then using ioremap_nocache internally to map them into non-cacheable memory. There must be a similar mechanism being used on ThreadX too, however the way that this configuration is done may be different. I suggest that you look into the ThreadX DSPLink documentation to find out how to remove these memory regions from ThreadX OS usage or make them non-cacheable. It appears that you might be missing some configuration that is specific to ThreadX, to ensure that these regions are made non-cacheable on ARM-side.

    In the DSPLink porting guide: dsplink/doc/port/LNK_017_PRT.pdf section 5.2, we give clear guidelines regarding this aspect to those doing OS ports of DSPLink to a different OS. You may want to go through that section, since it explains some of the above things.

    Since disabling cache as well as adding cache coherence calls on Linux-side seemed to resolve the issue, it definitely appears to me that the OS seems to think that these regions are cacheable. DSPLink does not support making these regions cacheable on ARM-side, so you should not use any workaround of disabling ARM-side cache (will significantly impact performance) or doing cache invalidate/writeback for some MSGQ buffers (will not be sufficient, since the entire DSPLink on ARM-side assumes these to be in non-cached area).

    Regards,

    Mugdha

  • Mugdha

    thanks. those are great clues we will look into that immediately.   However  my dsplink install has no such path or file for that LNK_017_PRT.pdf

     

  • Dave,

    You could download some recent DSPLink release from here:

    http://software-dl.ti.com/dsps/dsps_public_sw/DSPLink/index.html

    DSPLink release is in two packages, one is a Linux package (does not have the porting guide). The other is a porting kit package, which has the porting guide in the package I referred you to. You could look at the porting kit from any recent release. It should have the information I pointed you to. It appears that the ThreadX port may have been done using the Linux code as a base.

    Regards,

    Mugdha

  • Mugdha

    found the file. thanks

    I found in a file ind_crt0.c  the following code, which I am guessing is where I need a change, but am out of my element.  Any insights?

    //;============================================================================================================
    //;                                  Modified Page Table
    //;============================================================================================================
        //;{0x00000000, 1024, 0x402, RWRW, cb, 0x00000000, &sysPageTable},  0xDE2 - GPMC and Boot ROM
            //;{0x40200000, 1024, 0x001, RWRW, cb, 0x40200000, &sysPageTable},  0xDE2 - SRAM
           //;{0x40300000, 1024, 0x07D, RWRW, cb, 0x40300000, &sysPageTable},  0xDE2 - Not Accessible
            //;{0x48000000, 1024, 0x080, RWRW, cb, 0x48000000, &sysPageTable},  0xDE2 - L4-Interconnect
            //;{0x50000000, 1024, 0x300, RWRW, cb, 0x48000000, &sysPageTable},  0xDE2 - SGX, IVA, L3-Intercon.
            //;{0x80000000, 1024, 0x080, RWRW, CB, 0x80000000, &sysPageTable},  0xDEA - SDRC ==> 128MB
            //;{0x88000000, 1024, 0x77F, RWRW, cb, 0x88000000, &sysPageTable}   0xDE2 - Reserved

    //;******************************************Reserved***********************************************
        __asm__ __volatile__ ("LDR     r1, =0xFFF");//                  ; loop counter for the Entire Memory Map

        __asm__ __volatile__ ("LDR     r5, =0x87F");//                  ; Counter to Fill the Attribute In Page table
        __asm__ __volatile__ ("LDR     r2, =0xDE2");//                  ; Attributes to be set
    __asm__ __volatile__ ("init_ttb_1_0");//
            __asm__ __volatile__ ("ORR     r3, r2, r1, LSL#20");//          ; r3 now contains full level1 descriptor to write
            __asm__ __volatile__ ("STR     r3, [r0, r1, LSL#2]");//         ; str table entry at TTB base + loopcount*4
            __asm__ __volatile__ ("SUBS    r1, r1, #1");//                  ; decrement loop counter
        __asm__ __volatile__ ("CMP     r5, r1");//
        __asm__ __volatile__ ("BLT     init_ttb_1_0");//


    //;Configure the SDRAM address Space as Cacheable [Write Through & Bufferable]
        __asm__ __volatile__ ("ldr     r2, =0xDEA");//                  ; Attributes to be set
        __asm__ __volatile__ ("ldr     r5, =0x7FF");//                  ; Counter to Fill the Attribute In Page table
    __asm__ __volatile__ ("init_ttb_1_1");//
            __asm__ __volatile__ ("ORR     r3, r2, r1, LSL#20");//          ; r3 now contains full level1 descriptor to write
            __asm__ __volatile__ ("STR     r3, [r0, r1, LSL#2]");//         ; str table entry at TTB base + loopcount*4
            __asm__ __volatile__ ("SUBS    r1, r1, #1");//                  ; decrement loop counter
        __asm__ __volatile__ ("CMP     r5, r1");//
        __asm__ __volatile__ ("BLT     init_ttb_1_1");//


    //;Configure the L3 and L4 Interface as Non-Cacheable and Non-Bufferable
        __asm__ __volatile__ ("ldr     r2, =0xDE2");//                  ; Attributes to be set
        __asm__ __volatile__ ("ldr     r5, =0x3FF");//                  ; Counter to Fill the Attribute In Page table
    __asm__ __volatile__ ("init_ttb_1_2");//
            __asm__ __volatile__ ("ORR     r3, r2, r1, LSL#20");//          ; r3 now contains full level1 descriptor to write
            __asm__ __volatile__ ("STR     r3, [r0, r1, LSL#2]");//         ; str table entry at TTB base + loopcount*4
            __asm__ __volatile__ ("SUBS    r1, r1, #1");//                  ; decrement loop counter
        __asm__ __volatile__ ("CMP     r5, r1");//
        __asm__ __volatile__ ("BLT     init_ttb_1_2");//

       
    //;Configure the GPMC Addresss Space as Bufferable
        __asm__ __volatile__ ("ldr     r2, =0xDE2");//                  ; Attributes to be set
    __asm__ __volatile__ ("init_ttb_1_3");//
            __asm__ __volatile__ ("ORR     r3, r2, r1, LSL#20 ");//         ; r3 now contains full level1 descriptor to write
            __asm__ __volatile__ ("STR     r3, [r0, r1, LSL#2]");//         ; str table entry at TTB base + loopcount*4
            __asm__ __volatile__ ("SUBS    r1, r1, #1");//                  ; decrement loop counter
        __asm__ __volatile__ ("BPL     init_ttb_1_3");//
       

        __asm__ __volatile__ ("ORR     r3,r3,(#0xC0)");//               ; Set CB bits
        __asm__ __volatile__ ("ORR     r3,r3,(#0x1000)");//             ; Set TEX bits
            __asm__ __volatile__ ("STR     r3,[r0]");//

  • Dave,

    This does look like the right place, and at least from the contents of this file, it doesn't look like the memory from 0x87E00000 to 0x88000000 is marked as non-cacheable, which is what we need. Isn't there any document in the ThreadX DSPLink port that you got which gives information on how this file is to be updated to make this region as non-cacheable? I'd think that the port to ThreadX should include this information (since we provide this kind of documentation for the OSes that we support in-house).

    I really cannot comment on how to make the region as non-cacheable ... I'm not a ThreadX expert ... Do you have any contact with ThreadX who might be able to give you this information?

    Regards,
    Mugdha

  • I know this thread is old, but I needed a speed increase and didn't find any solution to the DspLink uncacheable shared memory issue. So, I modified DspLink to make it cacheable on the ARM-side. It worked well for me and dropped my DspLink communication time by 12 ms (was 14ms, now 2ms) per video frame (600x492x2) one direction (presumably you would save another 12 ms in the return communication, but since I am sending meta data back from the DSP to the ARM I didn't measure the image transfer in reverse direction).

    This is what I did (line numbers will of course depend on your version of DspLink):

    In DspLink/dsplink_linux_1_65_02_09/dsplink/gpp/src/arch/OMAP3530/omap3530.c, change line 525 from:

    mapInfo.memAttrs = MEM_UNCACHED ;

    to

    mapInfo.memAttrs = MEM_CACHED ;

    In DspLink/dsplink_linux_1_65_02_09/dsplink/gpp/src/arch/OMAP3530/shmem/Linux/omap3530_phy_shmem.c, change line 134 from:

    mapInfo.memAttrs = MEM_UNCACHED ;

    to

     mapInfo.memAttrs = MEM_CACHED ;

    In DspLink/dsplink_linux_1_65_02_09/dsplink/gpp/src/pmgr/Linux/2.6.18/drv_pmgr.c changed line 521 from

    vma->vm_page_prot = pgprot_noncached (vma->vm_page_prot) ;

    to

    vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot) ;

    Bryce

  • I forgot to mention that I also had to call the function described here after releasing my POOL buffer to go to the DSP.

    http://minghuasweblog.wordpress.com/2013/03/29/arm-cache-flush-on-mmapd-buffers-with-clear-cache/

    Bryce