]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - avr/cmd_mem.c
switch fifos conin,conout
[z180-stamp.git] / avr / cmd_mem.c
index 20a4412a0b2e770e8b8cc232c628057771b73bff..101b91210d84e1f0b2ae13a263ec7b1f86a78fa2 100644 (file)
 #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
@@ -150,8 +152,8 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
                        if (incrflag)
                                addr += nbytes ? -1 : 1;
                        nbytes = 1;
-               }
-               else {
+
+               else {
                        char *endp;
                        data = strtoul(console_buffer, &endp, 16);
                        nbytes = endp - console_buffer;
@@ -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 */