u-boot.lists.denx.de archive mirror
 help / color / mirror / Atom feed
From: York Sun <yorksun@freescale.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 2/7] Expand POST memory test to support arch-depended implementation.
Date: Fri, 27 Aug 2010 16:25:51 -0500	[thread overview]
Message-ID: <1282944356-4020-2-git-send-email-yorksun@freescale.com> (raw)
In-Reply-To: <1282944356-4020-1-git-send-email-yorksun@freescale.com>

Add progress indicator for slow test. It is useful when the testing
takes too longer to finish. The indicator is reused from flash
programming.

Hwconfig is used to turn on slow test when not enabled by flag.

Signed-off-by: York Sun <yorksun@freescale.com>
---
 post/drivers/memory.c |  211 +++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 171 insertions(+), 40 deletions(-)

diff --git a/post/drivers/memory.c b/post/drivers/memory.c
index 0062360..4020fc2 100644
--- a/post/drivers/memory.c
+++ b/post/drivers/memory.c
@@ -22,7 +22,7 @@
  */
 
 #include <common.h>
-
+#include <hwconfig.h>
 /* Memory test
  *
  * General observations:
@@ -172,6 +172,21 @@ DECLARE_GLOBAL_DATA_PTR;
 #warning "Injecting address line errors for testing purposes"
 #endif
 
+#define TOTAL_PROGRESS_DOTS 45
+#define TOTAL_PROGRESS_NUMBERS 9
+#define PROGRESS_DOTS_PER_NUMBER (TOTAL_PROGRESS_DOTS/TOTAL_PROGRESS_NUMBERS)
+#define TEST_SHOW_PROGRESS(scale, dots, digit, dots_sub) \
+{ \
+	dots -= (dots_sub); \
+	if ((scale > 0) && (dots <= 0)) { \
+		if ((digit % PROGRESS_DOTS_PER_NUMBER) == 0) \
+			printf("%d", digit / PROGRESS_DOTS_PER_NUMBER); \
+		else \
+			putc('.'); \
+		digit--; \
+		dots += (scale); \
+	} \
+}
 
 /*
  * This function performs a double word move from the data at
@@ -291,21 +306,34 @@ static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size)
 	return ret;
 }
 
-static int memory_post_test1 (unsigned long start,
+static int memory_post_test1(unsigned long start,
 			      unsigned long size,
-			      unsigned long val)
+			      unsigned long val,
+			      int fast)
 {
 	unsigned long i;
 	ulong *mem = (ulong *) start;
 	ulong readback;
 	int ret = 0;
+	int digit, dots;
+	int scale;
+
+	scale = (int)(((size >> 22) + TOTAL_PROGRESS_DOTS - 1) /
+		TOTAL_PROGRESS_DOTS);
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
 
 	for (i = 0; i < size / sizeof (ulong); i++) {
 		mem[i] = val;
 		if (i % 1024 == 0)
 			WATCHDOG_RESET ();
+		if (!fast && (i & 0xFFFFF) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
 	}
-
+	if (!fast)
+		printf("Filled with 0x%lx\n", val);
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
 	for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
 		readback = mem[i];
 		if (readback != val) {
@@ -318,24 +346,45 @@ static int memory_post_test1 (unsigned long start,
 		}
 		if (i % 1024 == 0)
 			WATCHDOG_RESET ();
+		if (!fast && (i & 0xFFFFF) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
+	}
+	if (!fast) {
+		if (ret == 0)
+			puts("Verified OK.\n\n");
+		else
+			puts("\nFailed!\n\n");
 	}
-
 	return ret;
 }
 
-static int memory_post_test2 (unsigned long start, unsigned long size)
+static int memory_post_test2(unsigned long start, unsigned long size, int fast)
 {
 	unsigned long i;
 	ulong *mem = (ulong *) start;
 	ulong readback;
 	int ret = 0;
+	int digit, dots;
+	int scale;
+
+	scale = (int)(((size >> 22) + TOTAL_PROGRESS_DOTS - 1) /
+		TOTAL_PROGRESS_DOTS);
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
 
 	for (i = 0; i < size / sizeof (ulong); i++) {
 		mem[i] = 1 << (i % 32);
 		if (i % 1024 == 0)
 			WATCHDOG_RESET ();
+		if (!fast && (i & 0xFFFFF) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
 	}
 
+	if (!fast)
+		printf("Filled with bit-flip pattern\n");
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
+
 	for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
 		readback = mem[i];
 		if (readback != (1 << (i % 32))) {
@@ -348,24 +397,45 @@ static int memory_post_test2 (unsigned long start, unsigned long size)
 		}
 		if (i % 1024 == 0)
 			WATCHDOG_RESET ();
+		if (!fast && (i & 0xFFFFF) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
+	}
+	if (!fast) {
+		if (ret == 0)
+			puts("Verified OK.\n\n");
+		else
+			puts("\nFailed!\n\n");
 	}
-
 	return ret;
 }
 
-static int memory_post_test3 (unsigned long start, unsigned long size)
+static int memory_post_test3(unsigned long start, unsigned long size, int fast)
 {
 	unsigned long i;
 	ulong *mem = (ulong *) start;
 	ulong readback;
 	int ret = 0;
+	int digit, dots;
+	int scale;
+
+	scale = (int)(((size >> 22) + TOTAL_PROGRESS_DOTS - 1) /
+		TOTAL_PROGRESS_DOTS);
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
 
 	for (i = 0; i < size / sizeof (ulong); i++) {
 		mem[i] = i;
 		if (i % 1024 == 0)
 			WATCHDOG_RESET ();
+		if (!fast && (i & 0xFFFFF) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
 	}
 
+	if (!fast)
+		printf("Filled with address pattern\n");
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
+
 	for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
 		readback = mem[i];
 		if (readback != i) {
@@ -378,24 +448,45 @@ static int memory_post_test3 (unsigned long start, unsigned long size)
 		}
 		if (i % 1024 == 0)
 			WATCHDOG_RESET ();
+		if (!fast && (i & 0xFFFFF) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
+	}
+	if (!fast) {
+		if (ret == 0)
+			puts("Verified OK.\n\n");
+		else
+			puts("\nFailed!\n\n");
 	}
-
 	return ret;
 }
 
-static int memory_post_test4 (unsigned long start, unsigned long size)
+static int memory_post_test4(unsigned long start, unsigned long size, int fast)
 {
 	unsigned long i;
 	ulong *mem = (ulong *) start;
 	ulong readback;
 	int ret = 0;
+	int digit, dots;
+	int scale;
+
+	scale = (int)(((size >> 22) + TOTAL_PROGRESS_DOTS - 1) /
+		TOTAL_PROGRESS_DOTS);
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
 
 	for (i = 0; i < size / sizeof (ulong); i++) {
 		mem[i] = ~i;
 		if (i % 1024 == 0)
 			WATCHDOG_RESET ();
+		if (!fast && (i & 0xFFFFF) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
 	}
 
+	if (!fast)
+		printf("Filled with address complement pattern\n");
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
+
 	for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
 		readback = mem[i];
 		if (readback != ~i) {
@@ -408,75 +499,115 @@ static int memory_post_test4 (unsigned long start, unsigned long size)
 		}
 		if (i % 1024 == 0)
 			WATCHDOG_RESET ();
+		if (!fast && (i & 0xFFFFF) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
+	}
+	if (!fast) {
+		if (ret == 0)
+			puts("Verified OK.\n\n");
+		else
+			puts("\nFailed!\n\n");
 	}
-
 	return ret;
 }
 
-static int memory_post_tests (unsigned long start, unsigned long size)
+static int memory_post_tests(unsigned long start, unsigned long size, int fast)
 {
 	int ret = 0;
 
 	if (ret == 0)
-		ret = memory_post_dataline ((unsigned long long *)start);
+		ret = memory_post_dataline((unsigned long long *)start);
 	WATCHDOG_RESET ();
 	if (ret == 0)
-		ret = memory_post_addrline ((ulong *)start, (ulong *)start, size);
+		ret = memory_post_addrline((ulong *)start, (ulong *)start, size);
 	WATCHDOG_RESET ();
 	if (ret == 0)
-		ret = memory_post_addrline ((ulong *)(start + size - 8),
+		ret = memory_post_addrline((ulong *)(start + size - 8),
 					    (ulong *)start, size);
 	WATCHDOG_RESET ();
 	if (ret == 0)
-		ret = memory_post_test1 (start, size, 0x00000000);
+		ret = memory_post_test1(start, size, 0x00000000, fast);
 	WATCHDOG_RESET ();
 	if (ret == 0)
-		ret = memory_post_test1 (start, size, 0xffffffff);
+		ret = memory_post_test1(start, size, 0xffffffff, fast);
 	WATCHDOG_RESET ();
 	if (ret == 0)
-		ret = memory_post_test1 (start, size, 0x55555555);
+		ret = memory_post_test1(start, size, 0x55555555, fast);
 	WATCHDOG_RESET ();
 	if (ret == 0)
-		ret = memory_post_test1 (start, size, 0xaaaaaaaa);
+		ret = memory_post_test1(start, size, 0xaaaaaaaa, fast);
 	WATCHDOG_RESET ();
 	if (ret == 0)
-		ret = memory_post_test2 (start, size);
+		ret = memory_post_test2(start, size, fast);
 	WATCHDOG_RESET ();
 	if (ret == 0)
-		ret = memory_post_test3 (start, size);
+		ret = memory_post_test3(start, size, fast);
 	WATCHDOG_RESET ();
 	if (ret == 0)
-		ret = memory_post_test4 (start, size);
+		ret = memory_post_test4(start, size, fast);
 	WATCHDOG_RESET ();
 
 	return ret;
 }
 
-int memory_post_test (int flags)
+__attribute__((weak))
+int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
 {
-	int ret = 0;
 	bd_t *bd = gd->bd;
-	unsigned long memsize = (bd->bi_memsize >= 256 << 20 ?
-				 256 << 20 : bd->bi_memsize) - (1 << 20);
-
+	*vstart = CONFIG_SYS_SDRAM_BASE;
+	*size = (bd->bi_memsize >= 256 << 20 ?
+			256 << 20 : bd->bi_memsize) - (1 << 20);
 	/* Limit area to be tested with the board info struct */
-	if (CONFIG_SYS_SDRAM_BASE + memsize > (ulong)bd)
-		memsize = (ulong)bd - CONFIG_SYS_SDRAM_BASE;
+	if ((*vstart) + (*size) > (ulong)bd)
+		*size = (ulong)bd - CONFIG_SYS_SDRAM_BASE;
+	return 0;
+}
+
+__attribute__((weak))
+int arch_memory_test_advance(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
+{
+	return 1;
+}
 
-	if (flags & POST_SLOWTEST) {
-		ret = memory_post_tests (CONFIG_SYS_SDRAM_BASE, memsize);
-	} else {			/* POST_NORMAL */
+__attribute__((weak))
+int arch_memory_test_cleanup(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
+{
+	return 0;
+}
 
-		unsigned long i;
+__attribute__((weak))
+void arch_memory_failure_handle(void)
+{
+	return;
+}
 
-		for (i = 0; i < (memsize >> 20) && ret == 0; i++) {
-			if (ret == 0)
-				ret = memory_post_tests (i << 20, 0x800);
-			if (ret == 0)
-				ret = memory_post_tests ((i << 20) + 0xff800, 0x800);
+int memory_post_test(int flags)
+{
+	int fast, ret = 0;
+	phys_addr_t phys_offset = 0;
+	u32 memsize, vstart;
+	if (hwconfig("memtest"))
+		fast = !hwconfig_arg_cmp("memtest", "slow");
+	else
+		fast = 1;
+
+	arch_memory_test_prepare(&vstart, &memsize, &phys_offset);
+	do {
+		if ((!fast) || (flags & POST_SLOWTEST)) {
+			ret = memory_post_tests(vstart, memsize, fast);
+		} else {			/* POST_NORMAL */
+			unsigned long i;
+			for (i = 0; i < (memsize >> 20) && ret == 0; i++) {
+				if (ret == 0)
+					ret = memory_post_tests(i << 20, 0x800, fast);
+				if (ret == 0)
+					ret = memory_post_tests((i << 20) + 0xff800, 0x800, fast);
+			}
 		}
-	}
-
+	} while (!ret && !arch_memory_test_advance(&vstart, &memsize, &phys_offset));
+	arch_memory_test_cleanup(&vstart, &memsize, &phys_offset);
+	if (ret)
+		arch_memory_failure_handle();
 	return ret;
 }
 
-- 
1.7.0.4

  reply	other threads:[~2010-08-27 21:25 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-27 21:25 [U-Boot] [PATCH 1/7] fix dma for 36bit addressing York Sun
2010-08-27 21:25 ` York Sun [this message]
2010-08-29  8:56   ` [U-Boot] [PATCH 2/7] Expand POST memory test to support arch-depended implementation Wolfgang Denk
2010-08-30 19:46     ` Scott Wood
2010-09-02  7:48       ` Wolfgang Denk
2010-09-02  7:54         ` Bas Mevissen
2010-08-27 21:25 ` [U-Boot] [PATCH 3/7] Add memory test feature for mpc85xx POST York Sun
2010-08-28 20:20   ` Wolfgang Denk
2010-08-27 21:25 ` [U-Boot] [PATCH 4/7] Enabled POST for generic mpc85xx York Sun
2010-08-29  8:56   ` Wolfgang Denk
2010-08-27 21:25 ` [U-Boot] [PATCH 5/7] Enable POST memory test for corenet_ds York Sun
2010-08-29  8:56   ` Wolfgang Denk
2010-08-27 21:25 ` [U-Boot] [PATCH 6/7] Enable POST memory test for P2020DS York Sun
2010-08-27 21:25 ` [U-Boot] [PATCH 7/7] Fix parameters to support RDIMM " York Sun
2010-08-31 16:23   ` Kumar Gala
2010-08-31 16:23 ` [U-Boot] [PATCH 1/7] fix dma for 36bit addressing Kumar Gala
2010-08-29 13:14 [U-Boot] [PATCH 2/7] Expand POST memory test to support arch-depended implementation sun york-R58495

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1282944356-4020-2-git-send-email-yorksun@freescale.com \
    --to=yorksun@freescale.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).