Cache problems on TI C6416 DSP

Started by gie78 November 3, 2006
Hi all,

I am using the C6416 fixpoint dsp from TI. My currently usecase is as
follow. The SDRAM is connected to EMIFA CE0. A Blockram is connected on
EMIFA CE1. The L2 memory is configured is 256K Cache, that means Cache
for CE0-Space is enabled.
Now my application works with a buffer which is situated in the SDRAM.
This buffer is served by a qdma transfer from the Blockram. To
guarantee the coherency between cache and SDRAM you have to call the
CacheL2inv or CacheL2wbIinv-function. My buffers are aligned to a
cachline size. Despite the CacheL2inv function call the data is
corrupted.
If I put the buffer into the internal memory everything works fine.
Has anyone an idea  what the problem could be.

Here a code snippet:

CACHE_wbInvL1d((void*)pDst, numTransferUnits*sizeof(uint16_t),
CACHE_WAIT);
CACHE_wbInvL2((void*)pDst, numTransferUnits*sizeof(uint16_t),
CACHE_WAIT);
EDMA_qdmaConfigArgs{ PRI_HIGH | ESIZE_16BIT | 1DS | SUM_INC | 1DD |
DUM_INC | TCC_CH1,
           EMIFSTARTADDRESS,
           numTransferUnits,
           (int) pDST, 
           0x00000000
          };

gie78 wrote:
> Hi all, > > I am using the C6416 fixpoint dsp from TI. My currently usecase is as > follow. The SDRAM is connected to EMIFA CE0. A Blockram is connected on > EMIFA CE1. The L2 memory is configured is 256K Cache, that means Cache > for CE0-Space is enabled. > Now my application works with a buffer which is situated in the SDRAM. > This buffer is served by a qdma transfer from the Blockram. To > guarantee the coherency between cache and SDRAM you have to call the > CacheL2inv or CacheL2wbIinv-function. My buffers are aligned to a > cachline size. Despite the CacheL2inv function call the data is > corrupted. > If I put the buffer into the internal memory everything works fine. > Has anyone an idea what the problem could be. > > Here a code snippet: > > CACHE_wbInvL1d((void*)pDst, numTransferUnits*sizeof(uint16_t), > CACHE_WAIT); > CACHE_wbInvL2((void*)pDst, numTransferUnits*sizeof(uint16_t), > CACHE_WAIT); > EDMA_qdmaConfigArgs{ PRI_HIGH | ESIZE_16BIT | 1DS | SUM_INC | 1DD | > DUM_INC | TCC_CH1, > EMIFSTARTADDRESS, > numTransferUnits, > (int) pDST, > 0x00000000 > }; >
Is it possible that the source data is also cached? Check the corresponding MAR bit to double-check if it is cacheable. If so, you need to do a writeback of the source before the QDMA transfer. For the destination you only need to do an invalidate, not a writeback-invalidate. There's no point in consuming the EMIF to writeback a bunch of data only to blow it away with a QDMA transfer moments later. Are you perhaps stepping through this with a memory window open? If so watch out for caching induced by the memory window. A read through the memory window is like a read from the CPU and so you could still see cache issues. If you want to see what's at address 0x80000000 then you should open a memory window to address 0x88000000. That seems odd at first, but because there aren't that many address lines you end up reading address 0x80000000 and because the corresponding MAR bit is not set you see what's in the physical memory and not what's in the cache. Brad
Brad Griffis wrote:
> gie78 wrote: >> Hi all, >> >> I am using the C6416 fixpoint dsp from TI. My currently usecase is as >> follow. The SDRAM is connected to EMIFA CE0. A Blockram is connected on >> EMIFA CE1. The L2 memory is configured is 256K Cache, that means Cache >> for CE0-Space is enabled. >> Now my application works with a buffer which is situated in the SDRAM. >> This buffer is served by a qdma transfer from the Blockram. To >> guarantee the coherency between cache and SDRAM you have to call the >> CacheL2inv or CacheL2wbIinv-function. My buffers are aligned to a >> cachline size. Despite the CacheL2inv function call the data is >> corrupted. >> If I put the buffer into the internal memory everything works fine. >> Has anyone an idea what the problem could be. >> >> Here a code snippet: >> >> CACHE_wbInvL1d((void*)pDst, numTransferUnits*sizeof(uint16_t), >> CACHE_WAIT); >> CACHE_wbInvL2((void*)pDst, numTransferUnits*sizeof(uint16_t), >> CACHE_WAIT); >> EDMA_qdmaConfigArgs{ PRI_HIGH | ESIZE_16BIT | 1DS | SUM_INC | 1DD | >> DUM_INC | TCC_CH1, >> EMIFSTARTADDRESS, >> numTransferUnits, >> (int) pDST, 0x00000000 >> }; >> > > Is it possible that the source data is also cached? Check the > corresponding MAR bit to double-check if it is cacheable. If so, you > need to do a writeback of the source before the QDMA transfer. > > For the destination you only need to do an invalidate, not a > writeback-invalidate. There's no point in consuming the EMIF to > writeback a bunch of data only to blow it away with a QDMA transfer > moments later.
Whoops, just realized that "invalidate" isn't an option, at least not on this processor. By the way, you don't need to do the writeback invalidate on L1D. Because this is an inclusive cache architecture the writeback invalidate of L2 will also writeback-invalidate L1.
> Are you perhaps stepping through this with a memory window open? If so > watch out for caching induced by the memory window. A read through the > memory window is like a read from the CPU and so you could still see > cache issues. If you want to see what's at address 0x80000000 then you > should open a memory window to address 0x88000000. That seems odd at > first, but because there aren't that many address lines you end up > reading address 0x80000000 and because the corresponding MAR bit is not > set you see what's in the physical memory and not what's in the cache. > > Brad
Brad Griffis wrote:
> gie78 wrote: >> Hi all, >> >> I am using the C6416 fixpoint dsp from TI. My currently usecase is as >> follow. The SDRAM is connected to EMIFA CE0. A Blockram is connected on >> EMIFA CE1. The L2 memory is configured is 256K Cache, that means Cache >> for CE0-Space is enabled. >> Now my application works with a buffer which is situated in the SDRAM. >> This buffer is served by a qdma transfer from the Blockram. To >> guarantee the coherency between cache and SDRAM you have to call the >> CacheL2inv or CacheL2wbIinv-function. My buffers are aligned to a >> cachline size. Despite the CacheL2inv function call the data is >> corrupted. >> If I put the buffer into the internal memory everything works fine. >> Has anyone an idea what the problem could be. >> >> Here a code snippet: >> >> CACHE_wbInvL1d((void*)pDst, numTransferUnits*sizeof(uint16_t), >> CACHE_WAIT); >> CACHE_wbInvL2((void*)pDst, numTransferUnits*sizeof(uint16_t), >> CACHE_WAIT); >> EDMA_qdmaConfigArgs{ PRI_HIGH | ESIZE_16BIT | 1DS | SUM_INC | 1DD | >> DUM_INC | TCC_CH1, >> EMIFSTARTADDRESS, >> numTransferUnits, >> (int) pDST, 0x00000000 >> }; >> > > Is it possible that the source data is also cached? Check the > corresponding MAR bit to double-check if it is cacheable. If so, you > need to do a writeback of the source before the QDMA transfer. > > For the destination you only need to do an invalidate, not a > writeback-invalidate. There's no point in consuming the EMIF to > writeback a bunch of data only to blow it away with a QDMA transfer > moments later.
Whoops, just realized that "invalidate" isn't an option, at least not on this processor. By the way, you don't need to do the writeback invalidate on L1D. Because this is an inclusive cache architecture the writeback invalidate of L2 will also writeback-invalidate L1.
> Are you perhaps stepping through this with a memory window open? If so > watch out for caching induced by the memory window. A read through the > memory window is like a read from the CPU and so you could still see > cache issues. If you want to see what's at address 0x80000000 then you > should open a memory window to address 0x88000000. That seems odd at > first, but because there aren't that many address lines you end up > reading address 0x80000000 and because the corresponding MAR bit is not > set you see what's in the physical memory and not what's in the cache. > > Brad
gie78 wrote:
> Hi all, > > I am using the C6416 fixpoint dsp from TI. My currently usecase is as > follow. The SDRAM is connected to EMIFA CE0. A Blockram is connected on > EMIFA CE1. The L2 memory is configured is 256K Cache, that means Cache > for CE0-Space is enabled. > Now my application works with a buffer which is situated in the SDRAM. > This buffer is served by a qdma transfer from the Blockram. To > guarantee the coherency between cache and SDRAM you have to call the > CacheL2inv or CacheL2wbIinv-function. My buffers are aligned to a > cachline size. Despite the CacheL2inv function call the data is > corrupted. > If I put the buffer into the internal memory everything works fine. > Has anyone an idea what the problem could be. > > Here a code snippet: > > CACHE_wbInvL1d((void*)pDst, numTransferUnits*sizeof(uint16_t), > CACHE_WAIT); > CACHE_wbInvL2((void*)pDst, numTransferUnits*sizeof(uint16_t), > CACHE_WAIT); > EDMA_qdmaConfigArgs{ PRI_HIGH | ESIZE_16BIT | 1DS | SUM_INC | 1DD | > DUM_INC | TCC_CH1, > EMIFSTARTADDRESS, > numTransferUnits, > (int) pDST, > 0x00000000 > }; >
Is it possible that the source data is also cached? Check the corresponding MAR bit to double-check if it is cacheable. If so, you need to do a writeback of the source before the QDMA transfer. For the destination you only need to do an invalidate, not a writeback-invalidate. There's no point in consuming the EMIF to writeback a bunch of data only to blow it away with a QDMA transfer moments later. Are you perhaps stepping through this with a memory window open? If so watch out for caching induced by the memory window. A read through the memory window is like a read from the CPU and so you could still see cache issues. If you want to see what's at address 0x80000000 then you should open a memory window to address 0x88000000. That seems odd at first, but because there aren't that many address lines you end up reading address 0x80000000 and because the corresponding MAR bit is not set you see what's in the physical memory and not what's in the cache. Brad
Hi all,

I am using the C6416 fixpoint dsp from TI. My currently usecase is as
follow. The SDRAM is connected to EMIFA CE0. A Blockram is connected on
EMIFA CE1. The L2 memory is configured is 256K Cache, that means Cache
for CE0-Space is enabled.
Now my application works with a buffer which is situated in the SDRAM.
This buffer is served by a qdma transfer from the Blockram. To
guarantee the coherency between cache and SDRAM you have to call the
CacheL2inv or CacheL2wbIinv-function. My buffers are aligned to a
cachline size. Despite the CacheL2inv function call the data is
corrupted.
If I put the buffer into the internal memory everything works fine.
Has anyone an idea  what the problem could be.

Here a code snippet:

CACHE_wbInvL1d((void*)pDst, numTransferUnits*sizeof(uint16_t),
CACHE_WAIT);
CACHE_wbInvL2((void*)pDst, numTransferUnits*sizeof(uint16_t),
CACHE_WAIT);
EDMA_qdmaConfigArgs{ PRI_HIGH | ESIZE_16BIT | 1DS | SUM_INC | 1DD |
DUM_INC | TCC_CH1,
           EMIFSTARTADDRESS,
           numTransferUnits,
           (int) pDST, 
           0x00000000
          };