summaryrefslogtreecommitdiff
path: root/avr/cmd_mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'avr/cmd_mem.c')
-rw-r--r--avr/cmd_mem.c371
1 files changed, 141 insertions, 230 deletions
diff --git a/avr/cmd_mem.c b/avr/cmd_mem.c
index 20a4412..53b1842 100644
--- a/avr/cmd_mem.c
+++ b/avr/cmd_mem.c
@@ -16,13 +16,15 @@
#include "common.h"
#include <stdlib.h>
#include <ctype.h>
+#include <avr/interrupt.h>
#include "command.h"
#include "cli_readline.h"
#include "print-utils.h"
#include "con-utils.h"
+#include "timer.h"
#include "z80-if.h"
-//#include "debug.h"
+#include "debug.h"
#ifndef CONFIG_SYS_MEMTEST_SCRATCH
@@ -222,55 +224,35 @@ command_ret_t do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
#ifdef CONFIG_MX_CYCLIC
command_ret_t do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- int i;
uint32_t count;
+ uint32_t ts;
+
+ (void) cmdtp;
+ (void) flag;
if (argc < 4)
return CMD_RET_USAGE;
count = strtoul(argv[3], NULL, 10);
+ clear_ctrlc(); /* forget any previous Control C */
for (;;) {
- do_mem_md (NULL, 0, 3, argv);
-
- /* delay for <count> ms... */
-/* TODO: use timer */
- for (i=0; i<count; i++)
- udelay (1000);
-
- /* check for ctrl-c to abort... */
- if (ctrlc()) {
- my_puts_P(PSTR("Abort\n"));
- return CMD_RET_SUCCESS;
- }
- }
-
- return CMD_RET_SUCCESS;
-}
-
-command_ret_t do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- int i;
- uint32_t count;
-
- if (argc < 4)
- return CMD_RET_USAGE;
- count = strtoul(argv[3], NULL, 10);
+ if (argv[0][1] == 'd')
+ do_mem_md (NULL, 0, 3, argv);
+ else
+ do_mem_mw (NULL, 0, 3, argv);
- for (;;) {
- do_mem_mw (NULL, 0, 3, argv);
/* delay for <count> ms... */
-/* TODO: use timer */
- for (i=0; i<count; i++)
- udelay (1000);
-
- /* check for ctrl-c to abort... */
- if (ctrlc()) {
- my_puts_P(PSTR("Abort\n"));
- return CMD_RET_SUCCESS;
- }
+ ts = get_timer(0);
+ do {
+ /* check for ctrl-c to abort... */
+ if (had_ctrlc() || ctrlc()) {
+ my_puts_P(PSTR("Abort\n"));
+ return CMD_RET_SUCCESS;
+ }
+ } while (get_timer(ts) < count);
}
return CMD_RET_SUCCESS;
@@ -417,27 +399,26 @@ command_ret_t do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
my_puts_P(PSTR("Bus timeout\n"));
return CMD_RET_FAILURE;
}
+ cli();
for (;;)
z80_read(addr);
- z80_bus_cmd(Release);
}
if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
my_puts_P(PSTR("Bus timeout\n"));
return CMD_RET_FAILURE;
}
+ cli();
for (;;) {
uint32_t i = length;
uint32_t p = addr;
while (i-- > 0)
z80_read(p++);
}
- z80_bus_cmd(Release);
return CMD_RET_SUCCESS;
}
-#ifdef CONFIG_LOOPW
command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
uint32_t addr, length;
@@ -457,7 +438,8 @@ command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const a
data = strtoul(argv[3], NULL, 16);
- /* We want to optimize the loops to run as fast as possible.
+ /*
+ * We want to optimize the loops to run as fast as possible.
* If we have only one object, just run infinite loops.
*/
if (length == 1) {
@@ -465,6 +447,7 @@ command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const a
my_puts_P(PSTR("Bus timeout\n"));
return CMD_RET_FAILURE;
}
+ cli();
for (;;)
z80_write(addr, data);
}
@@ -473,6 +456,7 @@ command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const a
my_puts_P(PSTR("Bus timeout\n"));
return CMD_RET_FAILURE;
}
+ cli();
for (;;) {
uint32_t i = length;
uint32_t p = addr;
@@ -480,35 +464,33 @@ command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const a
z80_write(p++, data);
}
}
-#endif /* CONFIG_LOOPW */
+
+//#define CONFIG_SYS_ALT_MEMTEST
#ifdef CONFIG_CMD_MEMTEST
-static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_addr,
- vu_long *dummy)
+static uint32_t mem_test_alt(uint32_t start_addr, uint32_t end_addr)
{
- vu_long *addr;
+ uint32_t addr;
+ uint32_t dummy;
uint32_t errs = 0;
- uint32_t val, readback;
- int j;
- vu_long offset;
- vu_long test_offset;
- vu_long pattern;
- vu_long temp;
- vu_long anti_pattern;
- vu_long num_words;
- static const FLASH uint32_t bitpattern[] = {
- 0x00000001, /* single bit */
- 0x00000003, /* two adjacent bits */
- 0x00000007, /* three adjacent bits */
- 0x0000000F, /* four adjacent bits */
- 0x00000005, /* two non-adjacent bits */
- 0x00000015, /* three non-adjacent bits */
- 0x00000055, /* four non-adjacent bits */
- 0xaaaaaaaa, /* alternating 1/0 */
+ uint32_t offset;
+ uint32_t test_offset;
+ uint8_t pattern;
+ uint8_t anti_pattern;
+ uint8_t temp;
+ uint32_t num_bytes;
+
+ static const FLASH uint8_t bitpattern[] = {
+ 0x01, /* single bit */
+ 0x03, /* two adjacent bits */
+ 0x07, /* three adjacent bits */
+ 0x0F, /* four adjacent bits */
+ 0x05, /* two non-adjacent bits */
+ 0x15, /* three non-adjacent bits */
+ 0x55, /* four non-adjacent bits */
+ 0xaa, /* alternating 1/0 */
};
- num_words = (end_addr - start_addr) / sizeof(vu_long);
-
/*
* Data line test: write a pattern to the first
* location, write the 1's complement to a 'parking'
@@ -526,35 +508,39 @@ static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_add
* '0's and '0' bits through a field of '1's (i.e.
* pattern and ~pattern).
*/
- addr = buf;
- for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) {
- val = bitpattern[j];
- for (; val != 0; val <<= 1) {
- *addr = val;
- *dummy = ~val; /* clear the test data off the bus */
- readback = *addr;
- if (readback != val) {
+ addr = start_addr;
+ dummy = start_addr+1;
+ for (unsigned int j = 0; j < ARRAY_SIZE(bitpattern); j++) {
+ pattern = bitpattern[j];
+ for (; pattern != 0; pattern <<= 1) {
+ anti_pattern = ~pattern;
+ z80_write(addr, pattern);
+ z80_write(dummy, anti_pattern); /* clear the test data off the bus */
+ temp = z80_read(addr);
+ if (temp != pattern) {
printf_P(PSTR("FAILURE (data line): "
- "expected %05lx, actual %05lx\n"),
- val, readback);
+ "expected %02x, actual %02x\n"),
+ pattern, temp);
errs++;
- if (ctrlc())
- return -1;
}
- *addr = ~val;
- *dummy = val;
- readback = *addr;
- if (readback != ~val) {
+ z80_write(addr, anti_pattern);
+ z80_write(dummy, pattern); /* clear the test data off the bus */
+ temp = z80_read(addr);
+ if (temp != anti_pattern) {
printf_P(PSTR("FAILURE (data line): "
- "Is %05lx, should be %05lx\n"),
- readback, ~val);
+ "Is %02x, should be %02x\n"),
+ temp, anti_pattern);
errs++;
- if (ctrlc())
- return -1;
}
}
+
+ if (ctrlc())
+ return -1;
}
+ if (errs)
+ return errs;
+
/*
* Based on code whose Original Author and Copyright
* information follows: Copyright (c) 1998 by Michael
@@ -589,59 +575,61 @@ static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_add
*
* Returns: 0 if the test succeeds, 1 if the test fails.
*/
- pattern = (vu_long) 0xaaaaaaaa;
- anti_pattern = (vu_long) 0x55555555;
- debug("%s:%d: length = 0x%.5lx\n", __func__, __LINE__, num_words);
+ num_bytes = (end_addr - start_addr) / sizeof(uint8_t);
+
+ pattern = 0xaa;
+ anti_pattern = 0x55;
+
+// debug("## %s:%d: length = 0x%.5lx\n", __func__, __LINE__, num_bytes);
/*
* Write the default pattern at each of the
* power-of-two offsets.
*/
- for (offset = 1; offset < num_words; offset <<= 1)
- addr[offset] = pattern;
+ for (offset = 1; offset < num_bytes; offset <<= 1)
+ z80_write(addr+offset, pattern);
/*
* Check for address bits stuck high.
*/
- test_offset = 0;
- addr[test_offset] = anti_pattern;
+ z80_write(start_addr, anti_pattern);
- for (offset = 1; offset < num_words; offset <<= 1) {
- temp = addr[offset];
+ for (offset = 1; offset < num_bytes; offset <<= 1) {
+ temp = z80_read(start_addr + offset);
if (temp != pattern) {
- printf_P(PSTR("\nFAILURE: Address bit stuck high @ 0x%.5lx:"
- " expected 0x%.5lx, actual 0x%.5lx\n"),
- start_addr + offset*sizeof(vu_long),
- pattern, temp);
+ printf_P(PSTR("FAILURE: Address bit stuck high @ 0x%.5lx:"
+ " expected 0x%.2x, actual 0x%.2x\n"),
+ start_addr + offset, pattern, temp);
errs++;
if (ctrlc())
return -1;
}
}
- addr[test_offset] = pattern;
+ z80_write(start_addr, pattern);
/*
* Check for addr bits stuck low or shorted.
*/
- for (test_offset = 1; test_offset < num_words; test_offset <<= 1) {
- addr[test_offset] = anti_pattern;
+ for (test_offset = 1; test_offset < num_bytes; test_offset <<= 1) {
+ z80_write(start_addr + test_offset, anti_pattern);
- for (offset = 1; offset < num_words; offset <<= 1) {
- temp = addr[offset];
+ for (offset = 1; offset < num_bytes; offset <<= 1) {
+ temp = z80_read(start_addr + offset);
if ((temp != pattern) && (offset != test_offset)) {
- printf_P(PSTR("\nFAILURE: Address bit stuck low or"
- " shorted @ 0x%.5lx: expected 0x%.5lx,"
- " actual 0x%.5lx\n"),
- start_addr + offset*sizeof(vu_long),
- pattern, temp);
+ printf_P(PSTR("FAILURE: Address bit stuck low or shorted"
+ " @ 0x%.5lx: expected 0x%.2x, actual 0x%.2x\n"),
+ start_addr + offset, pattern, temp);
errs++;
if (ctrlc())
return -1;
}
}
- addr[test_offset] = pattern;
+ z80_write(start_addr + test_offset, pattern);
}
+ if (errs)
+ return errs;
+
/*
* Description: Test the integrity of a physical
* memory device by performing an
@@ -654,111 +642,50 @@ static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_add
*
* Returns: 0 if the test succeeds, 1 if the test fails.
*/
- num_words++;
+ num_bytes++;
/*
* Fill memory with a known pattern.
*/
- for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
- addr[offset] = pattern;
- }
+ for (pattern = 1, addr = start_addr; addr <= end_addr; pattern++, addr++)
+ z80_write(addr, pattern);
/*
* Check each location and invert it for the second pass.
*/
- for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
- temp = addr[offset];
+ for (pattern = 1, addr = start_addr; addr <= end_addr; pattern++, addr++) {
+ temp = z80_read(addr);
if (temp != pattern) {
- printf_P(PSTR("\nFAILURE (read/write) @ 0x%.5lx:"
- " expected 0x%.5lx, actual 0x%.5lx)\n"),
- start_addr + offset*sizeof(vu_long),
- pattern, temp);
+ printf_P(PSTR("FAILURE (read/write) @ 0x%.5lx:"
+ " expected 0x%.2x, actual 0x%.2x)\n"),
+ addr, pattern, temp);
errs++;
if (ctrlc())
return -1;
}
anti_pattern = ~pattern;
- addr[offset] = anti_pattern;
+ z80_write(addr, anti_pattern);
}
/*
* Check each location for the inverted pattern and zero it.
*/
- for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
- WATCHDOG_RESET();
+ for (pattern = 1, addr = start_addr; addr <= end_addr; pattern++, addr++) {
anti_pattern = ~pattern;
- temp = addr[offset];
+ temp = z80_read(addr);
if (temp != anti_pattern) {
- printf_P(PSTR("\nFAILURE (read/write): @ 0x%.5lx:"
- " expected 0x%.5lx, actual 0x%.5lx)\n"),
- start_addr + offset*sizeof(vu_long),
- anti_pattern, temp);
+ printf_P(PSTR("FAILURE (read/write) @ 0x%.5lx:"
+ " expected 0x%.2x, actual 0x%.2x)\n"),
+ start_addr, anti_pattern, temp);
errs++;
if (ctrlc())
return -1;
}
- addr[offset] = 0;
+ z80_write(addr, 0);
}
- return 0;
-}
-
-static uint32_t mem_test_quick(vu_long *buf, uint32_t start_addr, uint32_t end_addr,
- vu_long pattern, int iteration)
-{
- vu_long *end;
- vu_long *addr;
- uint32_t errs = 0;
- uint32_t incr, length;
- uint32_t val, readback;
-
- /* Alternate the pattern */
- incr = 1;
- if (iteration & 1) {
- incr = -incr;
- /*
- * Flip the pattern each time to make lots of zeros and
- * then, the next time, lots of ones. We decrement
- * the "negative" patterns and increment the "positive"
- * patterns to preserve this feature.
- */
- if (pattern & 0x80000000)
- pattern = -pattern; /* complement & increment */
- else
- pattern = ~pattern;
- }
- length = (end_addr - start_addr) / sizeof(uint32_t);
- end = buf + length;
- printf_P(PSTR("\rPattern %08lX Writing..."
- "%12s"
- "\b\b\b\b\b\b\b\b\b\b"),
- pattern, "");
-
- for (addr = buf, val = pattern; addr < end; addr++) {
- *addr = val;
- val += incr;
- }
-
- my_puts_P(PSTR("Reading..."));
-
- for (addr = buf, val = pattern; addr < end; addr++) {
- readback = *addr;
- if (readback != val) {
- uint32_t offset = addr - buf;
-
- printf_P(PSTR("\nMem error @ 0x%08X: "
- "found %08lX, expected %08lX\n"),
- (unsigned int)(uintptr_t)(start_addr + offset*sizeof(vu_long)),
- readback, val);
- errs++;
- if (ctrlc())
- return -1;
- }
- val += incr;
- }
-
- return 0;
+ return errs;
}
/*
@@ -769,77 +696,61 @@ static uint32_t mem_test_quick(vu_long *buf, uint32_t start_addr, uint32_t end_a
command_ret_t do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
- uint32_t start, end;
- vu_long *buf, *dummy;
- int iteration_limit;
-/* TODO: command_ret_t */
+ uint32_t start = 0;
+ uint32_t end;
+ unsigned int iteration_limit = 0;
+ unsigned int iteration;
+ uint32_t errs = 0; /* number of errors */
int ret;
- uint32_t errs = 0; /* number of errors, or -1 if interrupted */
- uint32_t pattern;
- int iteration;
-#if defined(CONFIG_SYS_ALT_MEMTEST)
- const int alt_test = 1;
-#else
- const int alt_test = 0;
-#endif
+
+ (void) cmdtp;
+ (void) flag;
if (argc > 1)
start = strtoul(argv[1], NULL, 16);
- else
- start = CONFIG_SYS_MEMTEST_START;
if (argc > 2)
end = strtoul(argv[2], NULL, 16);
else
- end = CONFIG_SYS_MEMTEST_END;
+ end = CONFIG_SYS_RAMSIZE_MAX - 1;
if (argc > 3)
- pattern = (uint32_t)strtoul(argv[3], NULL, 16);
- else
- pattern = 0;
+ iteration_limit = (unsigned int) strtoul(argv[3], NULL, 16);
- if (argc > 4)
- iteration_limit = (uint32_t)strtoul(argv[4], NULL, 16);
- else
- iteration_limit = 0;
+ printf_P(PSTR("Testing %05lx ... %05lx:\n"), start, end);
+// debug("## %s:%d: start %#05lx end %#05lx\n", __func__, __LINE__, start, end);
- printf_P(PSTR("Testing %08x ... %08x:\n"), (unsigned int)start, (unsigned int)end);
- debug("%s:%d: start %#05lx end %#05lx\n", __func__, __LINE__,
- start, end);
+ clear_ctrlc(); /* forget any previous Control C */
-/* TODO: */
-// 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_P(PSTR("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);
+// debug("\n");
+
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ return CMD_RET_FAILURE;
}
- if (errs == -1UL)
+ errs += mem_test_alt(start, end);
+ z80_bus_cmd(Release);
+
+ if (had_ctrlc() || ctrlc()) {
break;
+ }
}
- if (errs == -1UL) {
+ if (had_ctrlc()) {
/* Memory test was aborted - write a newline to finish off */
- putc('\n');
- ret = 1;
+ putchar('\n');
+ ret = CMD_RET_FAILURE;
} else {
printf_P(PSTR("Tested %d iteration(s) with %lu errors.\n"),
iteration, errs);
- ret = errs != 0;
+ ret = errs ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
}
- return ret; /* not reached */
+ return ret;
}
#endif /* CONFIG_CMD_MEMTEST */