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.

Cache invalidate not working with MSMC

Other Parts Discussed in Thread: SYSBIOS

Hello,

We are working on TCI6670 evm

1. We have a RTOS project where we have declared a buffer of size approx.. 200K ,placed in MSMC.

2. EDMA writes to this buffer and only one Core reads it.

3. L1Dcache is enabled-32K and L2cache is also enabled-256K 

4. We are assuming that MSMC data is not cached in L2cache

Now, Following tasks are performed repeatedly in a sequence-

1. Cache_inv((void*)(buff), sizeof(buff), Cache_Type_L1D, TRUE);

2. DMA writes to this buff.

3. The core reads it

Observation-

Putting a breakpoint after cache invalidate, we see that no data is present in L1D cache(no grey line observed in memory browser).

On moving step by step ahead, after DMA write, correct output is present in MSMc. Now when CPU reads this input buffer,some of the initial bytes at physical memory of this Msmc buffer is being overwritten by previous L1D cache bytes of this buffer(already invalidated).

Moreover ,I have tried both these APIs to invalidate cpu cache data.

1. Cache_inv((void*)(buff), sizeof(buff), Cache_Type_L1D, TRUE);

2. CACHE_invL1d((void*)(buff), sizeof(buff), CACHE_WAIT);

But, the observation is same with both of the above scenarios.

Please assist how to proceed further in this case.

Regards,

Jeanne


 

  • Have you tried writeback invalidate?  

    Best Regards,

    Chad

  • Hi,

    Verify the buffer alignment: the reserved buffer must be aligned to cache line. Its size must be be multiple of cache line also.

  • Hello Chad,

    1. Core is not writing on this buffer. It is always read by core and written by DMA.

    2. This implies that cache lines will never get dirty. So, why we should do writeback ?

    3. Rest the second thing - It's correct that cache invalidate should be fully completed before buffer's first read access by core, BUT ,Is it necessary for cache invalidate to be fully completed before DMA write access?

    4. Moreover, I found a strange thing-

    I have tried both these APIs to invalidate cpu cache data.

        a. Cache_inv((void*)(buff), sizeof(buff), Cache_Type_L1D, TRUE);

            /* This SYSBIOS api works, if i perform cache invalidate quite before DMA write access followed by Core Read. */

        b. CACHE_invL1d((void*)(buff), sizeof(buff), CACHE_WAIT);

            /*This CSL api doesn't work even if i perform cache invalidate quite before DMA write access followed by Core Read.*/

    So, Is there any specific constraint while using CSL cache APIs.? My Project is an RTOS project.

    Please advise.

    Regards,
    Jeanne

     

  • Jeanne,

    I wasn't assuming that you had modified this, but that there was other data in the cache line that was potentially dirty, and if you didn't have the data aligned to the cache line, as Albert suggested, this could result in some initial corruption.

    Have you verified the alignment?

    Also, did you try the InvWb just as a test?

    Regarding the DMA waiting until the invalidation was done, this is necessary but you did have Cache_Wait in the call.

    Best Regards,

    Chad

  • Hi Chad,

    Yes,I have tried CACHE_wbInvL1d but it didnt worked too,like CACHE_invL1d <<initial data corruption persists>> 

    And as even adviced by Albert, I have already taken care of the fact that buffer is cache aligned.

    But,there is one important thing to be known-

    Say,My buffer is unsigned int8 a[128] aligned to 64 byte cache line size. This buffer is mainly accessed(i.e. read by core) by 2 pointers,say, *p,*q

    First,DMA writes in the complete 128 byte buffer

    Now,during first read access, p points to a[0] and q points to a[64] . Everything is perfect till here. And,address index 0 and 64 both are cache aligned.

    I perform then Cache invalidate 

    Then,DMA performs second write to this buffer completely.

    Now,during second read access,It could be possible that p points to a[4] while q points to a[68]. Is it correct? I mean that indexes 4 and 68 will not be cache aligned in this case.

    Can this be an issue??

    Because I am seeing that majorly last few bytes of *p at first read access and first few bytes of *q at second read access were corrupted.

    Please suggest.

    Regards,

    Jeanne

  • Jeanne,

    Those offsets are only used for read/write accesses and not for the Cache Actions (i.e. Invalidates) correct?  If so that shouldn't be a problem.

    However, I'm questioning whether we could be having a Prefetching issue here.  There's an Advisory 33 in the errata  where Prefetching from MSMC under certain circumstances can result in a failure.  The solution was to disable prefetching in MSMC range.

    Best Regards,

    Chad

    EDIT: Sorry, accidentally hit the post button when inserting the link to the Errata.

  • ok,i ll go through this advisory in detail and get back to you.

    But at a first glance, I have another query raised by your above suggestion.

    I have already declared the variable as volatile unsigned int a[128] . Does then also,this prefetching issue can occur?

    Regards,

    Jeanne

  • It being declared as Volatile or not would not have an impact on prefetching.  

    Declaring something as volatile is an indication to the compiler that something can be changed and that it should not be assumed that it would remain the same.  In other words, don't read it once and assume it's always that way unless the compiled code writes to the address itself.

    Compiler optimization may assume things are static if it is not writing to the space and thus it tight loops might generate assembly code such that it reads it once before actually entering the tight loop and always assume the value is the same.  In the case of other IP writing to an address, and the code itself never writes to the address, you'd need to declare it as volatile to ensure it reads it every time.  

    The assembly code generated from the compiler has no knowledge if it was volatile or not, only that it was a read instruction.

    That said, the prefetcher only see the decoded opcodes in the assembly code.  If the address is accessed or it thinks it's going to be accessed based on past history, it'll start to prefetch the data.  

    Best Regards,

    Chad

  • Hello Chad,

    Thanks for such a precise information on volatile and prefetcher.

    It is very helpful.

    Rest after referring to Advisory 33 - "Read Exception and Data Corruption Issue", I tried following in the configuration file -

    var tempVar = xdc.useModule('ti.sysbios.family.c66.Cache');

    tempVar.setMarMeta(0x0C18BEC0, 0x00074140, 0x0);

    where 0x0C18BEC0 => is the base address of MSMC memory region where my buffer was placed 

    .0x00074140 => is the size of the buffer

    0x3 =>that is, following bits are not set:-

    a. Permit caching in external cache = 0

    b. Prefetchable by external engines = 0

    rest everything is same ,i.e. I proceeded with following in code:-

     CACHE_invL1d((void*)(buff), sizeof(buff), CACHE_WAIT);

     DMA write

     core read

    ----------------------------------------------------------------------------------------------------

    The same issue still persists.

    Please suggest if I am going wrong somewhere.

    Regards,

    Jeanne


  • Jeanne,

    Ok, the one interesting thing is that it's working with the BIOS Cache commands and not the CSL cache commands inside BIOS.   I'm thinking there must be some interaction with BIOS here that isn't quite right.  I'm going to move this over to the RTOS forum which supports BIOS to see if we can get some feedback from the BIOS team.

    Best Regards,

    Chad

  • Jeanne,

    jeanne 1989k said:

    On moving step by step ahead, after DMA write, correct output is present in MSMc. Now when CPU reads this input buffer,some of the initial bytes at physical memory of this Msmc buffer is being overwritten by previous L1D cache bytes of this buffer(already invalidated).

     So can you please elaborate on how exactly the corruption of the buffer is happening? Your comment that a buffer read is causing the MSMC contents to get corrupted is not clear.

    Also, does your buffer alignment match the DMA buffer alignment requirement?

    Thanks,

    Moses

  • ok, Chad.

    Hello Moses,

    yes, I will tell you exactly how data corruption is happening.

    Say, My MSMC buffer is unsigned int8 a[128] aligned to 64 byte cache line size. This buffer is accessed(i.e. read by only one core) by 2 pointers ,say, *p,*q

    First, DMA writes in this complete 128 byte buffer Note: ABCNT is 4 bytes ,thus, dma buffer alignment requirement is fulfilled, right?

    Now, during first read access, p points to a[0] and q points to a[64] . Everything is perfect till here. And, address index 0 and 64 both are cache aligned.

    I perform then Cache invalidate: CACHE_invL1d((void*)(buff), sizeof(buff), CACHE_WAIT);

    Then, DMA performs second write to this complete buffer .

    Now, during second read access, It could be possible that p points to a[4] while q points to a[68].

    Here, I am seeing that majorly last few bytes of *p and first few bytes of *q at second read access gets corrupted.

    Note: DMA always writes to this buffer and core always reads from this buffer.

    Hope I could explain my issue precisely.

    Please let me know how to proceed.

    Regards,

    Jeanne

     

  • Jeanne,

    How many bytes of the DMA are you reading at a time? It looks like you're reading four bytes at a time into the same 128 buffer. I don't know the DMA alignment requirement for your device, does the data sheet say the data buffer should be 64 byte aligned?

    Moses

  • Hi Moses,

    yes, I am reading 4 bytes at a time into the same 128 buffer (ABCNT = 4).

    And yes, my buffer is 64-byte aligned. Moreover, the L1D cache line size is 64 bytes. So, this requirement has been already taken care.

    I guess that following could be an issue-

    Please suggest if this could be a possible

    1. My current software performs some cache configurations (like enabling DDR cache)using bios functions by calling setMarMeta in configuration file.

    2. And I am using CSL function to invalidate cache at the required location(mentioned in my previous post) in my software code i.e.  CACHE_invL1d((void*)(buff), sizeof(buff), CACHE_WAIT);

    (I have read somewhere that we cant use or call bios and CSL together for a particular functionality.)

    Can I call bios and CSL APIs together for a particular module(here, cache module) in my software application?

    Regards,

    Jeanne

  • Jeanne,

       So that we can analyze this problem more accurately. I recommend you use the Cache Tag RAM viewer to analyze the cache. Here's a forum post that explains how to do it.

    Regarding the CSL and BIOS APIs, if all you're doing with CSL is to invalidate the cache then it's not a problem.

    Let me know how it goes with the cache viewer.

    Thanks,

    Moses