Hello,
we designed a custom board with two C6678. Image data is sent from a FPGA to the two DSPs with SRIO. A doorbell is is signalling the end of the transmission and after that I am invalidating the image buffer. Today I found out that the invalidation does not work correct.
Last year I wroted a few functions for cache invalidation / writeback / writeback-and-invalidation. This functions should take care of Silicon Errata, advisory 7 and 22. Here is an example of Cache Invalidation I was using:
void Cache_Invalidate(void* blockPtr, Uint32 byteCnt) { unsigned int key; byteCnt = (byteCnt + 127) & 0xFFFFFF80; // byteCnt must be multiple of 128 key = _disable_interrupts(); CSL_XMC_invalidatePrefetchBuffer(); // Cleanup the prefetch buffer also. ASM_16X_NOP(); CACHE_invL1d(blockPtr, byteCnt, CACHE_FENCE_WAIT); ASM_16X_NOP(); CACHE_invL2(blockPtr, byteCnt, CACHE_FENCE_WAIT); ASM_16X_NOP(); _restore_interrupts(key); }
Maybe there are a few unnecessary NOPs (the macro ASM_16X_NOP() is performing 16 times asm(" NOP ");). I verified that code in the past, however I was using Silicon Revision 1.0.
Today I am using Silicon Revision 2.0 and I see old image data in the buffer, because cache invalidation didn't work correctly. So I had a look into Silicon Errata again and found advisory 27. Since I am using mfence I modified my code to:
void Cache_Invalidate(void* blockPtr, Uint32 byteCnt) { unsigned int key; byteCnt = (byteCnt + 127) & 0xFFFFFF80; // byteCnt must be multiple of 128 key = _disable_interrupts(); CSL_XMC_invalidatePrefetchBuffer(); // Cleanup the prefetch buffer also. ASM_16X_NOP(); CACHE_invL1d(blockPtr, byteCnt, CACHE_FENCE_WAIT); _mfence(); ASM_16X_NOP(); CACHE_invL2(blockPtr, byteCnt, CACHE_FENCE_WAIT); _mfence(); ASM_16X_NOP(); _restore_interrupts(key); }
But Cache Invalidation is still not working. Finally I was able to fix the problem by using my own Cache_WriteBackInvalidate(). It even works without taking care of advisory 27. Here is the function Cache_WriteBackInvalidate() I am using now:
void Cache_WriteBackInvalidate(void* blockPtr, Uint32 byteCnt) { unsigned int key; byteCnt = (byteCnt + 127) & 0xFFFFFF80; // byteCnt must be multiple of 128 key = _disable_interrupts(); CACHE_wbInvL1d(blockPtr, byteCnt, CACHE_FENCE_WAIT); ASM_16X_NOP(); CACHE_wbInvL2(blockPtr, byteCnt, CACHE_FENCE_WAIT); ASM_16X_NOP(); _restore_interrupts(key); }
It should be harmful to use this function, because I am writing no data in this buffer, it is only used for reading. So the writeback portion has no effect. However I want to know why it behaves different from my Cache_Invalidate().
Am I still doing something wrong?
One post which helped a lot was:
http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/253690
Thanks in advance
Benny