[U-Boot] mtest issue
Alexey Goncharov
alexygoncharov at gmail.com
Fri Nov 20 10:44:57 CET 2009
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?
More information about the U-Boot
mailing list