]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/cmd_mem.c
enum command_ret_t --> typedef
[z180-stamp.git] / avr / cmd_mem.c
CommitLineData
72f58822
L
1/*
2 * (C) Copyright 2000
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8/*
9 * Memory Functions
10 *
11 * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
12 */
13
14#include "common.h"
15#include <stdlib.h>
16#include <ctype.h>
17
18#include "config.h"
19#include "debug.h"
20#include "command.h"
21#include "cli_readline.h"
22#include "con-utils.h"
23#include "z80-if.h"
24
25/*
26 * TODO: printf() --> printf_P()
27 */
28
29#ifndef CONFIG_SYS_MEMTEST_SCRATCH
30#define CONFIG_SYS_MEMTEST_SCRATCH 0
31#endif
32
72f58822
L
33/* Display values from last command.
34 * Memory modify remembered values are different from display memory.
35 */
36static uint32_t dp_last_addr;
37static uint32_t dp_last_length = 0x100;
38static uint32_t mm_last_addr;
39
40static uint32_t base_address = 0;
41
42/*--------------------------------------------------------------------------*/
43
44static void print_blanks(uint_fast8_t count)
45{
46 while(count--)
47 putchar(' ');
48}
49
50int z180_dump_mem(uint32_t startaddr, uint32_t len, const char *title)
51{
52 uint8_t buf[16];
53 uint8_t llen = 16;
54 uint8_t pre = startaddr % 16;
55 uint32_t addr = startaddr & ~0x0f;
56 len += pre;
57 uint8_t i;
58
59 if (title && *title)
60 printf_P(PSTR("%s\n"),title);
61
62 while (len) {
63 if (len < 16)
64 llen = len;
65
62f624d3 66 z80_bus_cmd(Request);
72f58822
L
67 for (i = pre; i < llen; i++)
68 buf[i] = z80_read(addr + i);
62f624d3 69 z80_bus_cmd(Release);
72f58822
L
70
71 printf_P(PSTR("%.5lx:"), addr);
72#if 0
73 print_blanks(3 * pre);
74
75 /* Print hex values */
76 for (i = pre; i < llen; i++)
77 printf_P(PSTR(" %.2x"), buf[i]);
78#else
79 for (i = 0; i < llen; i++) {
80 if ((i % 8) == 0)
81 putchar(' ');
82 if (i < pre)
83 printf_P(PSTR(".. "));
84 else
85 printf_P(PSTR("%.2x "), buf[i]);
86 }
87#endif
88 /* fill line with whitespace for nice ASCII print */
89#if 1
90 print_blanks(3 * (16u - i) + (16u-i)/8 + 1 + pre);
91#else
92
93#endif
94 /* Print data in ASCII characters */
95 for (i = pre; i < llen; i++)
96 printf_P(PSTR("%c"), isprint(buf[i]) ? buf[i] : '.');
97 putchar('\n');
98
99 pre = 0;
100 addr += 16;
101 len -= llen;
102
103 if (ctrlc())
104 return -1;
105 }
106 return 0;
107}
108
109
110/*--------------------------------------------------------------------------*/
111
112/* Memory Display
113 *
114 * Syntax:
115 * md {addr} {len}
116 */
d0581f88 117command_ret_t do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
72f58822
L
118{
119 uint32_t addr, length;
120
121 (void) cmdtp;
122
123#if 0
124 printf_P(PSTR("flag: %d, argc: %d"), flag, argc);
125 for (int i = 0; i < argc; i++) {
126 printf_P(PSTR(", argv[%d]: %s"), i, argv[i] ? argv[i] : "<NULL>");
127 }
128 putchar('\n');
129#endif
130
131 /* We use the last specified parameters, unless new ones are
132 * entered.
133 */
134 addr = dp_last_addr;
135 length = dp_last_length;
136
137 if (argc < 2)
138 return CMD_RET_USAGE;
139
140 if ((flag & CMD_FLAG_REPEAT) == 0) {
141 /* Address is specified since argc > 1 */
142 addr = strtoul(argv[1], NULL, 16);
143 addr += base_address;
144
145 /* If another parameter, it is the length to display. */
146 if (argc > 2)
147 length = strtoul(argv[2], NULL, 16);
148 }
149
150 /* Print the lines. */
151 z180_dump_mem(addr, length, NULL);
152
153 dp_last_addr = addr + length;
154 dp_last_length = length;
d0581f88 155 return CMD_RET_SUCCESS;
72f58822
L
156}
157
d0581f88
L
158/* Modify memory.
159 *
160 * Syntax:
161 * mm {addr}
162 * nm {addr}
163 */
164static command_ret_t
165mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
166{
167 uint32_t addr;
168 uint8_t data;
169 int nbytes;
170
171 (void) cmdtp;
172
173 if (argc != 2)
174 return CMD_RET_USAGE;
175
176 /* We use the last specified parameters, unless new ones are
177 * entered.
178 */
179 addr = mm_last_addr;
180
181 if ((flag & CMD_FLAG_REPEAT) == 0) {
182 /* New command specified.
183 */
184
185 /* Address is specified since argc > 1
186 */
187 addr = strtoul(argv[1], NULL, 16);
188 addr += base_address;
189 }
190
191 /* Print the address, followed by value. Then accept input for
192 * the next value. A non-converted value exits.
193 */
194 do {
195 z80_bus_cmd(Request);
196 data = z80_read(addr);
197 printf("%05lx: %02x", addr, data);
198 z80_bus_cmd(Release);
199
200 nbytes = cli_readline(PSTR(" ? "));
201 if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
202 /* <CR> pressed as only input, don't modify current
203 * location and move to next. "-" pressed will go back.
204 */
205 if (incrflag)
206 addr += nbytes ? -1 : 1;
207 nbytes = 1;
208 }
209 else {
210 char *endp;
211 data = strtoul(console_buffer, &endp, 16);
212 nbytes = endp - console_buffer;
213 if (nbytes) {
214 z80_bus_cmd(Request);
215 z80_write(addr, data);
216 z80_bus_cmd(Release);
217 if (incrflag)
218 addr++;
219 }
220 }
221 } while (nbytes);
222
223 mm_last_addr = addr;
224 return CMD_RET_SUCCESS;
225}
226
227
228command_ret_t do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
72f58822
L
229{
230 return mod_mem (cmdtp, 1, flag, argc, argv);
231}
d0581f88 232command_ret_t do_mem_nm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
72f58822
L
233{
234 return mod_mem (cmdtp, 0, flag, argc, argv);
235}
236
d0581f88 237command_ret_t do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
72f58822
L
238{
239 uint8_t writeval;
240 uint32_t addr, count;
241
242 (void) cmdtp;
243 (void) flag;
244
245 if ((argc < 3) || (argc > 4))
246 return CMD_RET_USAGE;
247
248 /* Address is specified since argc > 1
249 */
250 addr = strtoul(argv[1], NULL, 16);
251 addr += base_address;
252
253 /* Get the value to write.
254 */
255 writeval = (uint8_t) strtoul(argv[2], NULL, 16);
256
257 /* Count ? */
258 if (argc == 4) {
259 count = strtoul(argv[3], NULL, 16);
260 } else {
261 count = 1;
262 }
263
62f624d3 264 z80_bus_cmd(Request);
72f58822
L
265 while (count-- > 0) {
266 z80_write(addr, writeval);
267 ++addr;
268 }
62f624d3 269 z80_bus_cmd(Release);
72f58822 270
d0581f88 271 return CMD_RET_SUCCESS;
72f58822
L
272}
273
274#ifdef CONFIG_MX_CYCLIC
d0581f88 275command_ret_t do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
72f58822
L
276{
277 int i;
278 uint32_t count;
279
280 if (argc < 4)
281 return CMD_RET_USAGE;
282
283 count = strtoul(argv[3], NULL, 10);
284
285 for (;;) {
286 do_mem_md (NULL, 0, 3, argv);
287
288 /* delay for <count> ms... */
289/* TODO: use timer */
290 for (i=0; i<count; i++)
291 udelay (1000);
292
293 /* check for ctrl-c to abort... */
294 if (ctrlc()) {
295 my_puts("Abort\n");
d0581f88 296 return CMD_RET_SUCCESS;
72f58822
L
297 }
298 }
299
d0581f88 300 return CMD_RET_SUCCESS;
72f58822
L
301}
302
d0581f88 303command_ret_t do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
72f58822
L
304{
305 int i;
306 uint32_t count;
307
308 if (argc < 4)
309 return CMD_RET_USAGE;
310
311 count = strtoul(argv[3], NULL, 10);
312
313 for (;;) {
314 do_mem_mw (NULL, 0, 3, argv);
315
316 /* delay for <count> ms... */
317/* TODO: use timer */
318 for (i=0; i<count; i++)
319 udelay (1000);
320
321 /* check for ctrl-c to abort... */
322 if (ctrlc()) {
323 my_puts("Abort\n");
d0581f88 324 return CMD_RET_SUCCESS;
72f58822
L
325 }
326 }
327
d0581f88 328 return CMD_RET_SUCCESS;
72f58822
L
329}
330#endif /* CONFIG_MX_CYCLIC */
331
d0581f88 332command_ret_t do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
72f58822
L
333{
334 uint32_t addr1, addr2, count, ngood;
d0581f88 335 command_ret_t rcode = CMD_RET_SUCCESS;
72f58822
L
336 uint8_t byte1, byte2;
337
338 (void) cmdtp;
339 (void) flag;
340
341 if (argc != 4)
342 return CMD_RET_USAGE;
343
344
345 addr1 = strtoul(argv[1], NULL, 16);
346 addr1 += base_address;
347 addr2 = strtoul(argv[2], NULL, 16);
348 addr2 += base_address;
349 count = strtoul(argv[3], NULL, 16);
350
351 for (ngood = 0; ngood < count; ++ngood) {
62f624d3 352 z80_bus_cmd(Request);
72f58822
L
353 byte1 = z80_read(addr1);
354 byte2 = z80_read(addr2);
62f624d3 355 z80_bus_cmd(Release);
72f58822
L
356 if (byte1 != byte2) {
357 printf( "byte at 0x%05lx (%#02x) != "
358 "byte at 0x%05lx (%#02x)\n",
359 addr1, byte1, addr2, byte2);
d0581f88 360 rcode = CMD_RET_FAILURE;
72f58822
L
361 break;
362 }
363 addr1++;
364 addr2++;
365
366 /* check for ctrl-c to abort... */
367 if (ctrlc()) {
368 my_puts("Abort\n");
d0581f88 369 return CMD_RET_SUCCESS;
72f58822
L
370 }
371 }
372
373 printf("Total of %ld byte(s) (0x%lx) were the same\n", ngood, ngood);
374 return rcode;
375}
376
d0581f88 377command_ret_t do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
72f58822
L
378{
379 uint32_t src, dest, count;
380 int_fast8_t step;
381
382 (void) cmdtp;
383 (void) flag;
384
385 if (argc != 4)
386 return CMD_RET_USAGE;
387
388 src = strtoul(argv[1], NULL, 16);
389 src += base_address;
390 dest = strtoul(argv[2], NULL, 16);
391 dest += base_address;
392 count = strtoul(argv[3], NULL, 16);
393
394 if (count == 0) {
395 my_puts ("Zero length ???\n");
d0581f88 396 return CMD_RET_FAILURE;
72f58822
L
397 }
398
399 if (dest > src) {
400 src += count - 1;
401 dest += count - 1;
402 step = -1;
403 } else
404 step = 1;
405
406 while (count-- > 0) {
407 uint8_t data;
62f624d3 408 z80_bus_cmd(Request);
72f58822
L
409 data = z80_read(src);
410 z80_write(dest, data);
62f624d3 411 z80_bus_cmd(Release);
72f58822
L
412 src += step;
413 dest += step;
414
415 /* check for ctrl-c to abort... */
416 if (ctrlc()) {
417 my_puts("Abort\n");
d0581f88 418 return CMD_RET_SUCCESS;
72f58822
L
419 }
420 }
d0581f88 421 return CMD_RET_SUCCESS;
72f58822
L
422}
423
d0581f88 424command_ret_t do_mem_base(cmd_tbl_t *cmdtp, int flag, int argc,
72f58822
L
425 char * const argv[])
426{
427 (void) cmdtp;
428 (void) flag;
429
430 if (argc > 1) {
431 /* Set new base address. */
432 base_address = strtoul(argv[1], NULL, 16);
433 }
434 /* Print the current base address. */
435 printf("Base Address: 0x%05lx\n", base_address);
d0581f88 436 return CMD_RET_SUCCESS;
72f58822
L
437}
438
d0581f88 439command_ret_t do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
72f58822
L
440 char * const argv[])
441{
442 uint32_t addr, length;
443
444 (void) cmdtp;
445 (void) flag;
446
447 if (argc < 3)
448 return CMD_RET_USAGE;
449
450 /* Address is always specified. */
451 addr = strtoul(argv[1], NULL, 16);
452
453 /* Length is the number of bytes. */
454 length = strtoul(argv[2], NULL, 16);
455
456
457 /* We want to optimize the loops to run as fast as possible.
458 * If we have only one object, just run infinite loops.
459 */
460 if (length == 1) {
62f624d3 461 z80_bus_cmd(Request);
72f58822
L
462 for (;;)
463 z80_read(addr);
62f624d3 464 z80_bus_cmd(Release);
72f58822
L
465 }
466
62f624d3 467 z80_bus_cmd(Request);
72f58822
L
468 for (;;) {
469 uint32_t i = length;
470 uint32_t p = addr;
471 while (i-- > 0)
472 z80_read(p++);
473 }
62f624d3 474 z80_bus_cmd(Release);
72f58822 475
d0581f88 476 return CMD_RET_SUCCESS;
72f58822
L
477}
478
479#ifdef CONFIG_LOOPW
d0581f88 480command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
72f58822
L
481{
482 uint32_t addr, length;
483 uint8_t data;
484
485 (void) cmdtp;
486 (void) flag;
487
488 if (argc < 4)
489 return CMD_RET_USAGE;
490
491 /* Address is always specified. */
492 addr = strtoul(argv[1], NULL, 16);
493
494 /* Length is the number of bytes. */
495 length = strtoul(argv[2], NULL, 16);
496
497 data = strtoul(argv[3], NULL, 16);
498
499 /* We want to optimize the loops to run as fast as possible.
500 * If we have only one object, just run infinite loops.
501 */
502 if (length == 1) {
62f624d3 503 z80_bus_cmd(Request);
72f58822
L
504 for (;;)
505 z80_write(addr, data);
506 }
507
508 for (;;) {
509 uint32_t i = length;
510 uint32_t p = addr;
511 while (i-- > 0)
512 z80_write(p++, data);
513 }
514}
515#endif /* CONFIG_LOOPW */
516
517#ifdef CONFIG_CMD_MEMTEST
518static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_addr,
519 vu_long *dummy)
520{
521 vu_long *addr;
522 uint32_t errs = 0;
523 uint32_t val, readback;
524 int j;
525 vu_long offset;
526 vu_long test_offset;
527 vu_long pattern;
528 vu_long temp;
529 vu_long anti_pattern;
530 vu_long num_words;
531 static const FLASH uint32_t bitpattern[] = {
532 0x00000001, /* single bit */
533 0x00000003, /* two adjacent bits */
534 0x00000007, /* three adjacent bits */
535 0x0000000F, /* four adjacent bits */
536 0x00000005, /* two non-adjacent bits */
537 0x00000015, /* three non-adjacent bits */
538 0x00000055, /* four non-adjacent bits */
539 0xaaaaaaaa, /* alternating 1/0 */
540 };
541
542 num_words = (end_addr - start_addr) / sizeof(vu_long);
543
544 /*
545 * Data line test: write a pattern to the first
546 * location, write the 1's complement to a 'parking'
547 * address (changes the state of the data bus so a
548 * floating bus doesn't give a false OK), and then
549 * read the value back. Note that we read it back
550 * into a variable because the next time we read it,
551 * it might be right (been there, tough to explain to
552 * the quality guys why it prints a failure when the
553 * "is" and "should be" are obviously the same in the
554 * error message).
555 *
556 * Rather than exhaustively testing, we test some
557 * patterns by shifting '1' bits through a field of
558 * '0's and '0' bits through a field of '1's (i.e.
559 * pattern and ~pattern).
560 */
561 addr = buf;
562 for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) {
563 val = bitpattern[j];
564 for (; val != 0; val <<= 1) {
565 *addr = val;
566 *dummy = ~val; /* clear the test data off the bus */
567 readback = *addr;
568 if (readback != val) {
569 printf("FAILURE (data line): "
570 "expected %05lx, actual %05lx\n",
571 val, readback);
572 errs++;
573 if (ctrlc())
574 return -1;
575 }
576 *addr = ~val;
577 *dummy = val;
578 readback = *addr;
579 if (readback != ~val) {
580 printf("FAILURE (data line): "
581 "Is %05lx, should be %05lx\n",
582 readback, ~val);
583 errs++;
584 if (ctrlc())
585 return -1;
586 }
587 }
588 }
589
590 /*
591 * Based on code whose Original Author and Copyright
592 * information follows: Copyright (c) 1998 by Michael
593 * Barr. This software is placed into the public
594 * domain and may be used for any purpose. However,
595 * this notice must not be changed or removed and no
596 * warranty is either expressed or implied by its
597 * publication or distribution.
598 */
599
600 /*
601 * Address line test
602
603 * Description: Test the address bus wiring in a
604 * memory region by performing a walking
605 * 1's test on the relevant bits of the
606 * address and checking for aliasing.
607 * This test will find single-bit
608 * address failures such as stuck-high,
609 * stuck-low, and shorted pins. The base
610 * address and size of the region are
611 * selected by the caller.
612
613 * Notes: For best results, the selected base
614 * address should have enough LSB 0's to
615 * guarantee single address bit changes.
616 * For example, to test a 64-Kbyte
617 * region, select a base address on a
618 * 64-Kbyte boundary. Also, select the
619 * region size as a power-of-two if at
620 * all possible.
621 *
622 * Returns: 0 if the test succeeds, 1 if the test fails.
623 */
624 pattern = (vu_long) 0xaaaaaaaa;
625 anti_pattern = (vu_long) 0x55555555;
626
627 debug("%s:%d: length = 0x%.5lx\n", __func__, __LINE__, num_words);
628 /*
629 * Write the default pattern at each of the
630 * power-of-two offsets.
631 */
632 for (offset = 1; offset < num_words; offset <<= 1)
633 addr[offset] = pattern;
634
635 /*
636 * Check for address bits stuck high.
637 */
638 test_offset = 0;
639 addr[test_offset] = anti_pattern;
640
641 for (offset = 1; offset < num_words; offset <<= 1) {
642 temp = addr[offset];
643 if (temp != pattern) {
644 printf("\nFAILURE: Address bit stuck high @ 0x%.5lx:"
645 " expected 0x%.5lx, actual 0x%.5lx\n",
646 start_addr + offset*sizeof(vu_long),
647 pattern, temp);
648 errs++;
649 if (ctrlc())
650 return -1;
651 }
652 }
653 addr[test_offset] = pattern;
654
655 /*
656 * Check for addr bits stuck low or shorted.
657 */
658 for (test_offset = 1; test_offset < num_words; test_offset <<= 1) {
659 addr[test_offset] = anti_pattern;
660
661 for (offset = 1; offset < num_words; offset <<= 1) {
662 temp = addr[offset];
663 if ((temp != pattern) && (offset != test_offset)) {
664 printf("\nFAILURE: Address bit stuck low or"
665 " shorted @ 0x%.5lx: expected 0x%.5lx,"
666 " actual 0x%.5lx\n",
667 start_addr + offset*sizeof(vu_long),
668 pattern, temp);
669 errs++;
670 if (ctrlc())
671 return -1;
672 }
673 }
674 addr[test_offset] = pattern;
675 }
676
677 /*
678 * Description: Test the integrity of a physical
679 * memory device by performing an
680 * increment/decrement test over the
681 * entire region. In the process every
682 * storage bit in the device is tested
683 * as a zero and a one. The base address
684 * and the size of the region are
685 * selected by the caller.
686 *
687 * Returns: 0 if the test succeeds, 1 if the test fails.
688 */
689 num_words++;
690
691 /*
692 * Fill memory with a known pattern.
693 */
694 for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
695 addr[offset] = pattern;
696 }
697
698 /*
699 * Check each location and invert it for the second pass.
700 */
701 for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
702 temp = addr[offset];
703 if (temp != pattern) {
704 printf("\nFAILURE (read/write) @ 0x%.5lx:"
705 " expected 0x%.5lx, actual 0x%.5lx)\n",
706 start_addr + offset*sizeof(vu_long),
707 pattern, temp);
708 errs++;
709 if (ctrlc())
710 return -1;
711 }
712
713 anti_pattern = ~pattern;
714 addr[offset] = anti_pattern;
715 }
716
717 /*
718 * Check each location for the inverted pattern and zero it.
719 */
720 for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
721 WATCHDOG_RESET();
722 anti_pattern = ~pattern;
723 temp = addr[offset];
724 if (temp != anti_pattern) {
725 printf("\nFAILURE (read/write): @ 0x%.5lx:"
726 " expected 0x%.5lx, actual 0x%.5lx)\n",
727 start_addr + offset*sizeof(vu_long),
728 anti_pattern, temp);
729 errs++;
730 if (ctrlc())
731 return -1;
732 }
733 addr[offset] = 0;
734 }
735
736 return 0;
737}
738
739static uint32_t mem_test_quick(vu_long *buf, uint32_t start_addr, uint32_t end_addr,
740 vu_long pattern, int iteration)
741{
742 vu_long *end;
743 vu_long *addr;
744 uint32_t errs = 0;
745 uint32_t incr, length;
746 uint32_t val, readback;
747
748 /* Alternate the pattern */
749 incr = 1;
750 if (iteration & 1) {
751 incr = -incr;
752 /*
753 * Flip the pattern each time to make lots of zeros and
754 * then, the next time, lots of ones. We decrement
755 * the "negative" patterns and increment the "positive"
756 * patterns to preserve this feature.
757 */
758 if (pattern & 0x80000000)
759 pattern = -pattern; /* complement & increment */
760 else
761 pattern = ~pattern;
762 }
763 length = (end_addr - start_addr) / sizeof(uint32_t);
764 end = buf + length;
765 printf("\rPattern %08lX Writing..."
766 "%12s"
767 "\b\b\b\b\b\b\b\b\b\b",
768 pattern, "");
769
770 for (addr = buf, val = pattern; addr < end; addr++) {
771 *addr = val;
772 val += incr;
773 }
774
775 my_puts("Reading...");
776
777 for (addr = buf, val = pattern; addr < end; addr++) {
778 readback = *addr;
779 if (readback != val) {
780 uint32_t offset = addr - buf;
781
782 printf("\nMem error @ 0x%08X: "
783 "found %08lX, expected %08lX\n",
784 (unsigned int)(uintptr_t)(start_addr + offset*sizeof(vu_long)),
785 readback, val);
786 errs++;
787 if (ctrlc())
788 return -1;
789 }
790 val += incr;
791 }
792
793 return 0;
794}
795
796/*
797 * Perform a memory test. A more complete alternative test can be
798 * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until
799 * interrupted by ctrl-c or by a failure of one of the sub-tests.
800 */
d0581f88 801command_ret_t do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
72f58822
L
802 char * const argv[])
803{
804 uint32_t start, end;
805 vu_long *buf, *dummy;
806 int iteration_limit;
d0581f88 807/* TODO: command_ret_t */
72f58822
L
808 int ret;
809 uint32_t errs = 0; /* number of errors, or -1 if interrupted */
810 uint32_t pattern;
811 int iteration;
812#if defined(CONFIG_SYS_ALT_MEMTEST)
813 const int alt_test = 1;
814#else
815 const int alt_test = 0;
816#endif
817
818 if (argc > 1)
819 start = strtoul(argv[1], NULL, 16);
820 else
821 start = CONFIG_SYS_MEMTEST_START;
822
823 if (argc > 2)
824 end = strtoul(argv[2], NULL, 16);
825 else
826 end = CONFIG_SYS_MEMTEST_END;
827
828 if (argc > 3)
829 pattern = (uint32_t)strtoul(argv[3], NULL, 16);
830 else
831 pattern = 0;
832
833 if (argc > 4)
834 iteration_limit = (uint32_t)strtoul(argv[4], NULL, 16);
835 else
836 iteration_limit = 0;
837
838 printf("Testing %08x ... %08x:\n", (unsigned int)start, (unsigned int)end);
839 debug("%s:%d: start %#05lx end %#05lx\n", __func__, __LINE__,
840 start, end);
841
842/* TODO: */
843// buf = map_sysmem(start, end - start);
844// dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long));
845 for (iteration = 0;
846 !iteration_limit || iteration < iteration_limit;
847 iteration++) {
848 if (ctrlc()) {
849 errs = -1UL;
850 break;
851 }
852
853 printf("Iteration: %6d\r", iteration + 1);
854 debug("\n");
855 if (alt_test) {
856 errs = mem_test_alt(buf, start, end, dummy);
857 } else {
858 errs = mem_test_quick(buf, start, end, pattern,
859 iteration);
860 }
861 if (errs == -1UL)
862 break;
863 }
864
865 if (errs == -1UL) {
866 /* Memory test was aborted - write a newline to finish off */
867 putc('\n');
868 ret = 1;
869 } else {
870 printf("Tested %d iteration(s) with %lu errors.\n",
871 iteration, errs);
872 ret = errs != 0;
873 }
874
875 return ret; /* not reached */
876}
877#endif /* CONFIG_CMD_MEMTEST */
878