[U-Boot] mtest issue

Alexey Goncharov
2009-11-20T09:44:57Z

Hello Jerry!

>> I have a LPC2468 board and currently play with u-boot. U-boot version
>> is 1.1.6 from Embedded Artists. I've already made u-boot loading and
>
> 1.1.6 is really old.

I'll keep this in mind and will update as soon as fix this issue.

>> Pattern 00000000 ?Writing... ?Reading...
>> Mem error @ 0xA075AB74: found A0780000, expected 001D6ADD
>
> What does the value A0780000 mean to your system? ?That looks like a magic
> memory address. ?Who would store that into memory? ?That may be a clue for
> finding the culprit.

Sorry i didn't provide you with the information at all. System has 8
Mbyte SDRAM and adresses from 0xA0780000 (7,5 Mbyte) to 0xA0800000 (8
MByte) are reserved for u-boot image and data. 0xA0780000 - is a
TEXT_BASE (CFG_MEMTEST_END) in target system. I spent all the day
yesterday navigating through the source code tree and found following
excerpt from u-boot/cpu/arm720t/start.S:

ldr r0, _TEXT_BASE ? ? ? ? ? ? ? ?/* upper 128 KiB: relocated uboot ? */
sub r0, r0, #CFG_MALLOC_LEN ? ? ? ? ? ? ? /* malloc area ? ?*/
sub r0, r0, #CFG_GBL_DATA_SIZE ? ? ? ? ? /* bdinfo ? ?*/
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack ? ?*/

This means that we have a memory map illustrated below:

1. Stack (grows "back" from higher adresses to lower addresses)
2. 12 bytes for abort-stack
3. FIQ Stack (grows "back" from higher adresses to lower addresses)
4. IRQ stack ?(grows "back" from higher adresses to lower addresses)
5. Global data
6. Heap
--TEXT_BASE = 0xA0780000
7. Uboot image

After calculating all the segment's adresses, i figured out that
addresses which give an error are from Stack segment (for example,
0xA075AB74). Here we come to the question: how can the memory segment
be checked if it's already occupied as a stack segment? My guess is
the mtest fails because of it "doesn't want" to corrupt the fragile
data in stack. I don't have a clear view why does u-boot keep stack in
adresses below TEXT_BASE. Addresses from TEXT_BASE to
PHYS_SDRAM_1_SIZE are not supposed to be checked by mtest and it might
be better to keep fragile data in that segment.

> If you specify a smaller, known unused, area to the mtest command (help
> mtest), does it work? ?Work your way through your "unused" memory map and
> find where it breaks.

I also used the mtest to check memory segments right after "the broken
cell" and would say that everything is fine. It's only a range about
20 bytes and some addresses within this range give a mtest-error.

>> In case with CFG_ALT_MEMTEST defined mtest also fails with error:
>>
>> Testing a0000000 ... a0780000:
>> Iteration: ? ? ?1
>> FAILURE (read/write) @ 0xa075ab68: expected 0x001d6adb, actual 0xffe29525)
>
> Note that the expected and actual are inverses:
> ?~0x001d6adb == 0xffe29525
> IIRC, the memory test stores the pattern, checks it, stores the ~pattern,
> and then checks that. ?This is smelling of a memory timing issue again.

I also used a very simple low-level test, written by co-worker, to
check the SDRAM before u-boot becomes loaded. Here is the source of
it:

?unsigned int testSDRAM_32(void)
?{
? ?unsigned int i,j;
? ?for ( i = 0,j=0; i < (1024*1024*8); i+=sizeof(unsigned int),j++)
? ?{
? ? ?*(unsigned int*)((unsigned int)(SDRAM_BASE_ADDR+i)) = (unsigned int)j;
? ?}
? ?for ( i = 0,j=0; i < (1024*1024*8); i+=sizeof(unsigned int),j++)
? ?{
? ? ?if (*(unsigned int*)((unsigned int)(SDRAM_BASE_ADDR+i)) !=
(unsigned int)j) return(FALSE);
? ?}
? ?return(TRUE);
?}

?{
?static const unsigned char test_mem_BAD[] = "\r\nTest SDRAM Failed!\r\n";
?unsigned char *pMsg;
?unsigned int i;
? ?if(testSDRAM_32() == TRUE)
? ?{
? ? ?static const unsigned char test_mem_OK[] = "\r\nTest SDRAM OK.\r\n";
? ? ?pMsg = (unsigned char *)test_mem_OK - (unsigned char *)TEXT_BASE;
? ? ?for(i=0; i<(sizeof(test_mem_OK)-1); i++)
? ? ?{
? ? ? ?while((U0LSR & (1<<5)) == 0); /* Wait for empty U0THR */
? ? ? ?U0THR = *pMsg++;
? ? ?}
? ?}
? ?else
? ?{
? ? ?static const unsigned char test_mem_BAD[] = "\r\nTest SDRAM Failed!\r\n";
? ? ?pMsg = (unsigned char *)test_mem_BAD - (unsigned char *)TEXT_BASE;
? ? ?for(i=0; i<(sizeof(test_mem_BAD)-1); i++)
? ? ?{
? ? ? ?while((U0LSR & (1<<5)) == 0); /* Wait for empty U0THR */
? ? ? ?U0THR = *pMsg++;
? ? ?}
? ?}
?}

And i would say that there is no errors in common, and timing issues
in particular.

So.. let's try to gather all the questions in one list:

1. Am I right saying that TEXT_BASE and CFG_MEMTEST_END is the same?
Can i decrease the CFG_MEMTEST_END to avoid the overlaying of mtest
check-segment and stack (or whatever)? I mean i've already decreased
CFG_MEMTEST_END to 0xa0750000. Mtest passes, but, obviously, addresses
from 0xa0750000 to 0xa0800000 are not being checked. is it ok?
2. Is the memory map i "illustrated" above right?
3. What is abort-stack (12 bytes)? (please, don't laugh)
4. What does memory segment from TEXT_BASE to PHYS_SDRAM_1_SIZE
contain? Only u-boot image (copy from flash) or u-boot image and
u-boot data?