[PATCH 1/4] qi-add-memory-testing-routines.patch

Andy Green andy at openmoko.com
Thu Oct 30 08:59:53 CET 2008


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 at openmoko.com>
---

 include/qi.h            |    2 +
 src/cpu/s3c2442/start.S |   14 +++--
 src/cpu/s3c6410/start.S |    9 +++
 src/memory-test.c       |  145 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 165 insertions(+), 5 deletions(-)
 create mode 100644 src/memory-test.c

diff --git a/include/qi.h b/include/qi.h
index a6c5b59..b9970a4 100644
--- a/include/qi.h
+++ b/include/qi.h
@@ -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
 
diff --git a/src/cpu/s3c2442/start.S b/src/cpu/s3c2442/start.S
index 9961d8f..eaab799 100644
--- a/src/cpu/s3c2442/start.S
+++ b/src/cpu/s3c2442/start.S
@@ -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:	
 	/*
diff --git a/src/cpu/s3c6410/start.S b/src/cpu/s3c6410/start.S
index 29a5713..3d63fc7 100644
--- a/src/cpu/s3c6410/start.S
+++ b/src/cpu/s3c6410/start.S
@@ -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
diff --git a/src/memory-test.c b/src/memory-test.c
new file mode 100644
index 0000000..4cdc8cc
--- /dev/null
+++ b/src/memory-test.c
@@ -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);
+}




More information about the openmoko-kernel mailing list