+/*
+ * Perform a memory test. A more complete alternative test can be
+ * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until
+ * interrupted by ctrl-c or by a failure of one of the sub-tests.
+ */
+static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ ulong start, end;
+ vu_long *buf, *dummy;
+ int iteration_limit;
+ int ret;
+ ulong errs = 0; /* number of errors, or -1 if interrupted */
+ ulong pattern;
+ int iteration;
+#if defined(CONFIG_SYS_ALT_MEMTEST)
+ const int alt_test = 1;
+#else
+ const int alt_test = 0;
+#endif
+
+ if (argc > 1)
+ start = simple_strtoul(argv[1], NULL, 16);
+ else
+ start = CONFIG_SYS_MEMTEST_START;
+
+ if (argc > 2)
+ end = simple_strtoul(argv[2], NULL, 16);
+ else
+ end = CONFIG_SYS_MEMTEST_END;
+
+ if (argc > 3)
+ pattern = (ulong)simple_strtoul(argv[3], NULL, 16);
+ else
+ pattern = 0;
+
+ if (argc > 4)
+ iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16);
+ else
+ iteration_limit = 0;
+
+ printf("Testing %08x ... %08x:\n", (uint)start, (uint)end);
+ debug("%s:%d: start %#08lx end %#08lx\n", __func__, __LINE__,
+ start, end);
+
+ buf = map_sysmem(start, end - start);
+ dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long));
+ for (iteration = 0;
+ !iteration_limit || iteration < iteration_limit;
+ iteration++) {
+ if (ctrlc()) {
+ errs = -1UL;
+ break;
+ }
+
+ printf("Iteration: %6d\r", iteration + 1);
+ debug("\n");
+ if (alt_test) {
+ errs = mem_test_alt(buf, start, end, dummy);
+ } else {
+ errs = mem_test_quick(buf, start, end, pattern,
+ iteration);
+ }
+ if (errs == -1UL)
+ break;
+ }
+
+ /*
+ * Work-around for eldk-4.2 which gives this warning if we try to
+ * case in the unmap_sysmem() call:
+ * warning: initialization discards qualifiers from pointer target type
+ */
+ {
+ void *vbuf = (void *)buf;
+ void *vdummy = (void *)dummy;
+
+ unmap_sysmem(vbuf);
+ unmap_sysmem(vdummy);
+ }
+
+ if (errs == -1UL) {
+ /* Memory test was aborted - write a newline to finish off */
+ putc('\n');
+ ret = 1;
+ } else {
+ printf("Tested %d iteration(s) with %lu errors.\n",
+ iteration, errs);
+ ret = errs != 0;
+ }
+
+ return ret; /* not reached */
+}
+#endif /* CONFIG_CMD_MEMTEST */