Monday, November 3, 2008

Work Around for data abort on L2 cache enabled PXA320 windows CE 6.0 platforms.

I have developed a BSP for PXA320 based platform running on windows embedded CE 6.0. I have taken the Zylonite windows CE 5.0 BSP. I faced an issue while enabling the PXA320 L2 cache. There are lots of data abort during the booting time from some drivers and application like explorer.exe. I track the call stack and I found the source code causing the data abort. OEMCacheRangeFlush () CACHE_SYNC_DISCARD case is causing the issue.
This case is used when the cache lines or the whole cache will be write-back and invalidate. Data Abort was occurring exactly when invalidating a range of cache lines. The invalidation operation for the whole cache or a range of the cache is decided based on the length and address. If length and address both are zero or the length is greater than the size of the cache, the whole cache will be flushed, otherwise only a particular set of cache lines will be flushed based on the address. Address passed as an argument is used to calculate the starting cache line to flush. L2 Cache is using physical address for cache operations. The cache flushing function is implemented in assembly language. It will convert the Virtual address to physical address through the page table entry. During this conversion sometime it is getting invalid page table data, which causes the data abort. I don’t know the reason for the invalid page table entry. But I have the workaround.
The work around is, use the same function used for flushing the entire cache instead of using the function implemented for flushing the lines.
Replace the function
XScaleFlushDCacheLinesL2((LPVOID) dwNormalizedAddress, dwNormalizedLength, ARMCacheInfo.dwL2DCacheLineSize);
With
XScaleFlushDCacheL2(DCACHE_LINES, ARMCacheInfo.dwL2DCacheLineSize, (DWORD) gpvCacheFlushBaseMemoryAddress);
This will stop the occurrence of data abort during the L2 cache flushing on OEMCacheRangeFlush().

2 comments:

CEUser said...

I would still be interested in flushing particular range and not the entire range. Do you know now why the Data Abort is seen in this case?

Igor Golikov said...

Hi
I am expriencing same problems...

Do you mean replacing in this block:
__try {
XScaleFlushDCacheLinesL2((LPVOID) dwNormalizedAddress, dwNormalizedLength, ARMCacheInfo.dwL1DCacheLineSize);
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
XScaleCleanDCacheL2(DCACHE_LINES, ARMCacheInfo.dwL1DCacheLineSize, (DWORD) gpvCacheFlushBaseMemoryAddress);
}

????

Thanks