diff mbox series

[4/4] cmd: mem: Add bitflip memory test to alternate mtest

Message ID 20200305062132.22932-4-sr@denx.de
State Accepted
Commit 8e434cb705d463bc8cff935160e4fb4c77cb99ab
Delegated to: Tom Rini
Headers show
Series [1/4] cmd: mem: Correctly count the errors in mtest | expand

Commit Message

Stefan Roese March 5, 2020, 6:21 a.m. UTC
This additional bitflip memory test is inspired by the bitflip test
in memtester v4.3.0. It show some errors on some problematic GARDENA
MT7688 based boards. The other memory tests usually don't show any
errors here.

Signed-off-by: Stefan Roese <sr@denx.de>
---
 cmd/mem.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

Comments

Tom Rini April 21, 2020, 12:26 p.m. UTC | #1
On Thu, Mar 05, 2020 at 07:21:32AM +0100, Stefan Roese wrote:

> This additional bitflip memory test is inspired by the bitflip test
> in memtester v4.3.0. It show some errors on some problematic GARDENA
> MT7688 based boards. The other memory tests usually don't show any
> errors here.
> 
> Signed-off-by: Stefan Roese <sr@denx.de>

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/cmd/mem.c b/cmd/mem.c
index 2ccc7032ad..0bfb6081e7 100644
--- a/cmd/mem.c
+++ b/cmd/mem.c
@@ -801,6 +801,59 @@  static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr,
 	return errs;
 }
 
+static int compare_regions(volatile unsigned long *bufa,
+			   volatile unsigned long *bufb, size_t count)
+{
+	volatile unsigned long  *p1 = bufa;
+	volatile unsigned long  *p2 = bufb;
+	int errs = 0;
+	size_t i;
+
+	for (i = 0; i < count; i++, p1++, p2++) {
+		if (*p1 != *p2) {
+			printf("FAILURE: 0x%08lx != 0x%08lx (delta=0x%08lx -> bit %ld) at offset 0x%08lx\n",
+			       (unsigned long)*p1, (unsigned long)*p2,
+			       *p1 ^ *p2, __ffs(*p1 ^ *p2),
+				(unsigned long)(i * sizeof(unsigned long)));
+			errs++;
+		}
+	}
+
+	return errs;
+}
+
+static ulong test_bitflip_comparison(volatile unsigned long *bufa,
+				     volatile unsigned long *bufb, size_t count)
+{
+	volatile unsigned long *p1 = bufa;
+	volatile unsigned long *p2 = bufb;
+	unsigned int j, k;
+	unsigned long q;
+	size_t i;
+	int max;
+	int errs = 0;
+
+	max = sizeof(unsigned long) * 8;
+	for (k = 0; k < max; k++) {
+		q = 0x00000001L << k;
+		for (j = 0; j < 8; j++) {
+			WATCHDOG_RESET();
+			q = ~q;
+			p1 = (volatile unsigned long *)bufa;
+			p2 = (volatile unsigned long *)bufb;
+			for (i = 0; i < count; i++)
+				*p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
+
+			errs += compare_regions(bufa, bufb, count);
+		}
+
+		if (ctrlc())
+			return -1UL;
+	}
+
+	return errs;
+}
+
 static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr,
 			    vu_long pattern, int iteration)
 {
@@ -918,6 +971,13 @@  static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
 		debug("\n");
 		if (IS_ENABLED(CONFIG_SYS_ALT_MEMTEST)) {
 			errs = mem_test_alt(buf, start, end, dummy);
+			if (errs == -1UL)
+				break;
+			count += errs;
+			errs = test_bitflip_comparison(buf,
+						       buf + (end - start) / 2,
+						       (end - start) /
+						       sizeof(unsigned long));
 		} else {
 			errs = mem_test_quick(buf, start, end, pattern,
 					      iteration);