mirror of
git://projects.qi-hardware.com/xburst-tools.git
synced 2024-11-01 12:28:06 +02:00
qi-add-memory-testing-routines.patch
This adds the memory testing code to Qi. It tests the range of memory with several constants and then a 32-bit walking 1 pattern, and repeats forever. The entire main SDRAM can be tested due to the fact this runs out of steppingstone only and does not need to store anything outside of it. It introduces a steppingstone-based stack for use entirely in steppingstone. Signed-off-by: Andy Green <andy@openmoko.com>
This commit is contained in:
parent
cff19a41ce
commit
2e982c433d
@ -106,5 +106,7 @@ unsigned long crc32(unsigned long crc, const unsigned char *buf,
|
||||
unsigned int len);
|
||||
int nand_read_ll(unsigned char *buf, unsigned long start512, int blocks512);
|
||||
|
||||
extern void memory_test(void * start, unsigned int length);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -50,11 +50,6 @@ _start_armboot:
|
||||
_TEXT_BASE:
|
||||
.word TEXT_BASE
|
||||
|
||||
processor_id:
|
||||
.word 0
|
||||
.word 0x41129200 /* s3c2442 ID */
|
||||
.word 0x410fb760 /* s3c6410 ID */
|
||||
|
||||
/*
|
||||
* These are defined in the board-specific linker script.
|
||||
*/
|
||||
@ -65,6 +60,15 @@ _bss_start:
|
||||
.globl _bss_end
|
||||
_bss_end:
|
||||
.word _end
|
||||
/*
|
||||
* we have a stack in steppingstone because we can want to run full memory
|
||||
* memory tests
|
||||
*/
|
||||
|
||||
.fill 128
|
||||
.globl _ss_stack
|
||||
_ss_stack:
|
||||
|
||||
|
||||
start_code:
|
||||
/*
|
||||
|
@ -152,6 +152,15 @@ _bss_start:
|
||||
_bss_end:
|
||||
.word _end
|
||||
|
||||
/*
|
||||
* we have a stack in steppingstone because we can want to run full memory
|
||||
* memory tests
|
||||
*/
|
||||
|
||||
.fill 128
|
||||
.globl _ss_stack
|
||||
_ss_stack:
|
||||
|
||||
start_code:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
|
145
qiboot/src/memory-test.c
Normal file
145
qiboot/src/memory-test.c
Normal file
@ -0,0 +1,145 @@
|
||||
#include <qi.h>
|
||||
#include <string.h>
|
||||
|
||||
int memory_test_const32(void * start, unsigned int length, u32 value)
|
||||
{
|
||||
int errors = 0;
|
||||
u32 * p = (u32 *)start;
|
||||
u32 * pend = (u32 *)(start + length);
|
||||
int count = length >> 2;
|
||||
|
||||
puts(".");
|
||||
|
||||
while (p < pend)
|
||||
*p++ = value;
|
||||
|
||||
p = (u32 *)start;
|
||||
count = length >> 2;
|
||||
|
||||
while (count--)
|
||||
if (*p++ != value) {
|
||||
puts("*** Error ");
|
||||
print32((long)p - 4);
|
||||
errors++;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int memory_test_ads(void * start, unsigned int length, u32 mask)
|
||||
{
|
||||
int errors = 0;
|
||||
u32 * p = (u32 *)start;
|
||||
u32 * pend = (u32 *)(start + length);
|
||||
|
||||
puts(".");
|
||||
|
||||
while (p < pend)
|
||||
if ((u32)p & mask)
|
||||
*p++ = 0xffffffff;
|
||||
else
|
||||
*p++ = 0;
|
||||
|
||||
p = (u32 *)start;
|
||||
|
||||
while (p < pend) {
|
||||
if ((u32)p & mask) {
|
||||
if (*p++ != 0xffffffff) {
|
||||
puts("*** Error ");
|
||||
print32((long)p - 4);
|
||||
errors++;
|
||||
}
|
||||
} else {
|
||||
if (*p++) {
|
||||
puts("*** Error ");
|
||||
print32((long)p - 4);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
int memory_test_walking1(void * start, unsigned int length)
|
||||
{
|
||||
int errors = 0;
|
||||
u32 value = 1;
|
||||
|
||||
while (value) {
|
||||
errors += memory_test_const32(start, length, value);
|
||||
value <<= 1;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/* negative runs == run forever */
|
||||
|
||||
void __memory_test(void * start, unsigned int length)
|
||||
{
|
||||
int errors = 0;
|
||||
int series = 0;
|
||||
int mask;
|
||||
|
||||
puts("\nMemory Testing 0x");
|
||||
print32((u32)start);
|
||||
puts(" length ");
|
||||
printdec(length >> 20);
|
||||
puts(" MB\n");
|
||||
|
||||
while (1) {
|
||||
puts(" Test series ");
|
||||
printdec(series + 1);
|
||||
puts(" ");
|
||||
|
||||
/* these are looking at data issues, they flood the whole
|
||||
* array with the same data
|
||||
*/
|
||||
|
||||
errors += memory_test_const32(start, length, 0x55555555);
|
||||
errors += memory_test_const32(start, length, 0xaaaaaaaa);
|
||||
errors += memory_test_const32(start, length, 0x55aa55aa);
|
||||
errors += memory_test_const32(start, length, 0xaa55aa55);
|
||||
errors += memory_test_const32(start, length, 0x00ff00ff);
|
||||
errors += memory_test_const32(start, length, 0xff00ff00);
|
||||
errors += memory_test_walking1(start, length);
|
||||
|
||||
/* this is looking at addressing issues, it floods only
|
||||
* addresses meeting a walking mask with 0xffffffff (the rest
|
||||
* is zeroed), and makes sure all the bits are only seen where
|
||||
* they were placed
|
||||
*/
|
||||
|
||||
mask = 1;
|
||||
while (! (length & mask)) {
|
||||
errors += memory_test_ads(start, length, mask);
|
||||
mask = mask << 1;
|
||||
}
|
||||
|
||||
puts(" Total errors: ");
|
||||
printdec(errors);
|
||||
puts("\n");
|
||||
|
||||
series++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void memory_test(void * start, unsigned int length)
|
||||
{
|
||||
/* it's a small steppingstone stack from start.S */
|
||||
extern int _ss_stack;
|
||||
|
||||
/*
|
||||
* we won't be coming back from this, so just force our local stack to
|
||||
* steppingstone out of the way of main memory test action
|
||||
*
|
||||
* then jump into the actual test
|
||||
*/
|
||||
asm volatile (
|
||||
"mov sp, %0\n"
|
||||
: : "r" (&_ss_stack)
|
||||
);
|
||||
|
||||
__memory_test(start, length);
|
||||
}
|
Loading…
Reference in New Issue
Block a user