I am having a problem, where the memory controller / TLB and cache system on an iMx 51 seems to play tricks on me.
The problem can be described by the following pice of code.
volatile EndpointTransferDescriptorStruct* dTDPtr = dTDHandlerPtr->dTD; // 4K apart buffer page pointers U32 currentStartAddress = (U32)(transfer.requestStartAddress + currentOffset); dTDPtr->BufferPointerPage0 = currentStartAddress; dTDPtr->BufferPointerPage1 = dTDPtr->BufferPointerPage0 + 4096; dTDPtr->BufferPointerPage2 = dTDPtr->BufferPointerPage1 + 4096; dTDPtr->BufferPointerPage3 = dTDPtr->BufferPointerPage2 + 4096; dTDPtr->BufferPointerPage4 = dTDPtr->BufferPointerPage3 + 4096; U32 tempPtr = dTDHandlerPtr->dTD->BufferPointerPage0; if (tempPtr) { if (tempPtr dTD); U32 timeout = 100; while (timeout) { U32 tempPtrTwo = dTDHandlerPtr->dTD->BufferPointerPage0; TRACEE("Buffer pointer 0 0x%x, @ %dms\n", tempPtrTwo, GetTimeMs()); if (tempPtrTwo == currentStartAddress) { break; } Wait(1); timeout--; } TRACE( "stop\n" ); TRACE("temp 0x%x, 0x%x, 0x%x", tempPtr, dTDPtr, dTDHandlerPtr->dTD); TRACE("temp 2 0x%x\n", currentStartAddress); ASSERT(0); } }
This piece of code is part of a bigger system, which runs in some time, until the following is printed, and I can break it by my debugger at the "stop" trace.
How could this happens startAddr = 0xaf3e0380, tempPtr 0x4000380, dTDPtr 0xaf32c0e0, dTD 0xaf32c0e0??
Buffer pointer 0 0xaf3e0380, @ 95930ms
The address in startAddr is correct, where tempPtr is not correct. Looking at the structure with BufferPointerPage1-4 its address is not correct, as it uses the 0x4000380 address as value for BufferPointerPage0. When I read BufferPointerPage0 ones more at line 18 the value is correct. Some how either the write seems "lazy" compared to the read. Or the read fails some times before it is refreshed and is correct later.
For fully understanding this, you will need to know, that dTDPtr pointer is pointing to the top of the LPDDR memory, which is setup to be uncached seen from the CPU. The dTRPtr is also declared volatile all places it is used, as it is handed over to hardware later. All in all is there 12 mb of uncached memory, which contains the QH, a pool of dTDs. Just next to this area (starting inside the same 1 mb section of memory), some buffers used by the DMA and USB is located. So looking at the memory, it must control access from CPU, DMA and USB, and still maintain correct data in the memory.
I will like some input to this problem.
解決済! 解決策の投稿を見る。
Hi Grant
The problem was in the hardware. So it is solved by hardware changes.
Have a nice day.
Just the TLB setup of the uncached memory.
TLBEntry sectionTLB;
sectionTLB.value = 0;
sectionTLB.attributes.type01 = 2; // Must be 2 for section TLBs
sectionTLB.attributes.type2 = 0; // Must be 0 for section TLBs
sectionTLB.attributes.AP01 = 3; // Access permissions: full access
sectionTLB.attributes.AP2 = 0; // Access permissions: full access
sectionTLB.attributes.nG = 0; // Make it global
sectionTLB.attributes.NS = 0; // Make it secure
uncachedRam.value = sectionTLB.value;
uncachedRam.attributes.B = 0; // Inner: non-cachable
uncachedRam.attributes.C = 0; //
uncachedRam.attributes.TEX = 1; // Outer: non-cachable
uncachedRam.attributes.S = 1; // Shareable
uncachedRam.attributes.XN = 0; // Execute OK
uncachedRam.attributes.nG = 0; // NotGlobal = 1 (i.e. it is not process specific)
uncachedRam.attributes.NS = 0; // Secure, can translate in both secure and non secure space
Hi Claus,
I was looking through some of the older issues in the community and came across this one. Are you still having this issue? If so, do you have an update as to your progress in solving it?
Thanks,
Grant
Hi Grant
The problem was in the hardware. So it is solved by hardware changes.
Have a nice day.
Hi Claus,
Glad you were able to identify and fix this issue.
Regards,
Grant