1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <common.h>
15#include <console.h>
16#include <bootretry.h>
17#include <cli.h>
18#include <command.h>
19#include <console.h>
20#ifdef CONFIG_HAS_DATAFLASH
21#include <dataflash.h>
22#endif
23#include <hash.h>
24#include <inttypes.h>
25#include <mapmem.h>
26#include <watchdog.h>
27#include <asm/io.h>
28#include <linux/compiler.h>
29
30DECLARE_GLOBAL_DATA_PTR;
31
32#ifndef CONFIG_SYS_MEMTEST_SCRATCH
33#define CONFIG_SYS_MEMTEST_SCRATCH 0
34#endif
35
36static int mod_mem(cmd_tbl_t *, int, int, int, char * const []);
37
38
39
40
41static ulong dp_last_addr, dp_last_size;
42static ulong dp_last_length = 0x40;
43static ulong mm_last_addr, mm_last_size;
44
45static ulong base_address = 0;
46
47
48
49
50
51
52#define DISP_LINE_LEN 16
53static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
54{
55 ulong addr, length;
56#if defined(CONFIG_HAS_DATAFLASH)
57 ulong nbytes, linebytes;
58#endif
59 int size;
60 int rc = 0;
61
62
63
64
65 addr = dp_last_addr;
66 size = dp_last_size;
67 length = dp_last_length;
68
69 if (argc < 2)
70 return CMD_RET_USAGE;
71
72 if ((flag & CMD_FLAG_REPEAT) == 0) {
73
74
75
76 if ((size = cmd_get_data_size(argv[0], 4)) < 0)
77 return 1;
78
79
80
81 addr = simple_strtoul(argv[1], NULL, 16);
82 addr += base_address;
83
84
85
86
87 if (argc > 2)
88 length = simple_strtoul(argv[2], NULL, 16);
89 }
90
91#if defined(CONFIG_HAS_DATAFLASH)
92
93
94
95
96
97 nbytes = length * size;
98 do {
99 char linebuf[DISP_LINE_LEN];
100 void* p;
101 linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
102
103 rc = read_dataflash(addr, (linebytes/size)*size, linebuf);
104 p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr;
105 print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size);
106
107 nbytes -= linebytes;
108 addr += linebytes;
109 if (ctrlc()) {
110 rc = 1;
111 break;
112 }
113 } while (nbytes > 0);
114#else
115
116# if defined(CONFIG_BLACKFIN)
117
118 if (addr_bfin_on_chip_mem(addr)) {
119 char linebuf[DISP_LINE_LEN];
120 ulong linebytes, nbytes = length * size;
121 do {
122 linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
123 memcpy(linebuf, (void *)addr, linebytes);
124 print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size);
125
126 nbytes -= linebytes;
127 addr += linebytes;
128 if (ctrlc()) {
129 rc = 1;
130 break;
131 }
132 } while (nbytes > 0);
133 } else
134# endif
135
136 {
137 ulong bytes = size * length;
138 const void *buf = map_sysmem(addr, bytes);
139
140
141 print_buffer(addr, buf, size, length, DISP_LINE_LEN / size);
142 addr += bytes;
143 unmap_sysmem(buf);
144 }
145#endif
146
147 dp_last_addr = addr;
148 dp_last_length = length;
149 dp_last_size = size;
150 return (rc);
151}
152
153static int do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
154{
155 return mod_mem (cmdtp, 1, flag, argc, argv);
156}
157static int do_mem_nm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
158{
159 return mod_mem (cmdtp, 0, flag, argc, argv);
160}
161
162static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
163{
164#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
165 u64 writeval;
166#else
167 ulong writeval;
168#endif
169 ulong addr, count;
170 int size;
171 void *buf, *start;
172 ulong bytes;
173
174 if ((argc < 3) || (argc > 4))
175 return CMD_RET_USAGE;
176
177
178
179 if ((size = cmd_get_data_size(argv[0], 4)) < 1)
180 return 1;
181
182
183
184 addr = simple_strtoul(argv[1], NULL, 16);
185 addr += base_address;
186
187
188
189#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
190 writeval = simple_strtoull(argv[2], NULL, 16);
191#else
192 writeval = simple_strtoul(argv[2], NULL, 16);
193#endif
194
195
196 if (argc == 4) {
197 count = simple_strtoul(argv[3], NULL, 16);
198 } else {
199 count = 1;
200 }
201
202 bytes = size * count;
203 start = map_sysmem(addr, bytes);
204 buf = start;
205 while (count-- > 0) {
206 if (size == 4)
207 *((u32 *)buf) = (u32)writeval;
208#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
209 else if (size == 8)
210 *((u64 *)buf) = (u64)writeval;
211#endif
212 else if (size == 2)
213 *((u16 *)buf) = (u16)writeval;
214 else
215 *((u8 *)buf) = (u8)writeval;
216 buf += size;
217 }
218 unmap_sysmem(start);
219 return 0;
220}
221
222#ifdef CONFIG_MX_CYCLIC
223static int do_mem_mdc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
224{
225 int i;
226 ulong count;
227
228 if (argc < 4)
229 return CMD_RET_USAGE;
230
231 count = simple_strtoul(argv[3], NULL, 10);
232
233 for (;;) {
234 do_mem_md (NULL, 0, 3, argv);
235
236
237 for (i=0; i<count; i++)
238 udelay (1000);
239
240
241 if (ctrlc()) {
242 puts("Abort\n");
243 return 0;
244 }
245 }
246
247 return 0;
248}
249
250static int do_mem_mwc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
251{
252 int i;
253 ulong count;
254
255 if (argc < 4)
256 return CMD_RET_USAGE;
257
258 count = simple_strtoul(argv[3], NULL, 10);
259
260 for (;;) {
261 do_mem_mw (NULL, 0, 3, argv);
262
263
264 for (i=0; i<count; i++)
265 udelay (1000);
266
267
268 if (ctrlc()) {
269 puts("Abort\n");
270 return 0;
271 }
272 }
273
274 return 0;
275}
276#endif
277
278static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
279{
280 ulong addr1, addr2, count, ngood, bytes;
281 int size;
282 int rcode = 0;
283 const char *type;
284 const void *buf1, *buf2, *base;
285#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
286 u64 word1, word2;
287#else
288 ulong word1, word2;
289#endif
290
291 if (argc != 4)
292 return CMD_RET_USAGE;
293
294
295
296 if ((size = cmd_get_data_size(argv[0], 4)) < 0)
297 return 1;
298 type = size == 8 ? "double word" :
299 size == 4 ? "word" :
300 size == 2 ? "halfword" : "byte";
301
302 addr1 = simple_strtoul(argv[1], NULL, 16);
303 addr1 += base_address;
304
305 addr2 = simple_strtoul(argv[2], NULL, 16);
306 addr2 += base_address;
307
308 count = simple_strtoul(argv[3], NULL, 16);
309
310#ifdef CONFIG_HAS_DATAFLASH
311 if (addr_dataflash(addr1) | addr_dataflash(addr2)){
312 puts ("Comparison with DataFlash space not supported.\n\r");
313 return 0;
314 }
315#endif
316
317#ifdef CONFIG_BLACKFIN
318 if (addr_bfin_on_chip_mem(addr1) || addr_bfin_on_chip_mem(addr2)) {
319 puts ("Comparison with L1 instruction memory not supported.\n\r");
320 return 0;
321 }
322#endif
323
324 bytes = size * count;
325 base = buf1 = map_sysmem(addr1, bytes);
326 buf2 = map_sysmem(addr2, bytes);
327 for (ngood = 0; ngood < count; ++ngood) {
328 if (size == 4) {
329 word1 = *(u32 *)buf1;
330 word2 = *(u32 *)buf2;
331#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
332 } else if (size == 8) {
333 word1 = *(u64 *)buf1;
334 word2 = *(u64 *)buf2;
335#endif
336 } else if (size == 2) {
337 word1 = *(u16 *)buf1;
338 word2 = *(u16 *)buf2;
339 } else {
340 word1 = *(u8 *)buf1;
341 word2 = *(u8 *)buf2;
342 }
343 if (word1 != word2) {
344 ulong offset = buf1 - base;
345#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
346 printf("%s at 0x%p (%#0*"PRIx64") != %s at 0x%p (%#0*"
347 PRIx64 ")\n",
348 type, (void *)(addr1 + offset), size, word1,
349 type, (void *)(addr2 + offset), size, word2);
350#else
351 printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n",
352 type, (ulong)(addr1 + offset), size, word1,
353 type, (ulong)(addr2 + offset), size, word2);
354#endif
355 rcode = 1;
356 break;
357 }
358
359 buf1 += size;
360 buf2 += size;
361
362
363 if ((ngood % (64 << 10)) == 0)
364 WATCHDOG_RESET();
365 }
366 unmap_sysmem(buf1);
367 unmap_sysmem(buf2);
368
369 printf("Total of %ld %s(s) were the same\n", ngood, type);
370 return rcode;
371}
372
373static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
374{
375 ulong addr, dest, count, bytes;
376 int size;
377 const void *src;
378 void *buf;
379
380 if (argc != 4)
381 return CMD_RET_USAGE;
382
383
384
385 if ((size = cmd_get_data_size(argv[0], 4)) < 0)
386 return 1;
387
388 addr = simple_strtoul(argv[1], NULL, 16);
389 addr += base_address;
390
391 dest = simple_strtoul(argv[2], NULL, 16);
392 dest += base_address;
393
394 count = simple_strtoul(argv[3], NULL, 16);
395
396 if (count == 0) {
397 puts ("Zero length ???\n");
398 return 1;
399 }
400
401#ifndef CONFIG_SYS_NO_FLASH
402
403 if ( (addr2info(dest) != NULL)
404#ifdef CONFIG_HAS_DATAFLASH
405 && (!addr_dataflash(dest))
406#endif
407 ) {
408 int rc;
409
410 puts ("Copy to Flash... ");
411
412 rc = flash_write ((char *)addr, dest, count*size);
413 if (rc != 0) {
414 flash_perror (rc);
415 return (1);
416 }
417 puts ("done\n");
418 return 0;
419 }
420#endif
421
422#ifdef CONFIG_HAS_DATAFLASH
423
424 if (addr_dataflash(dest) && !addr_dataflash(addr)){
425 int rc;
426
427 puts ("Copy to DataFlash... ");
428
429 rc = write_dataflash (dest, addr, count*size);
430
431 if (rc != 1) {
432 dataflash_perror (rc);
433 return (1);
434 }
435 puts ("done\n");
436 return 0;
437 }
438
439
440 if (addr_dataflash(addr) && !addr_dataflash(dest)
441#ifndef CONFIG_SYS_NO_FLASH
442 && (addr2info(dest) == NULL)
443#endif
444 ){
445 int rc;
446 rc = read_dataflash(addr, count * size, (char *) dest);
447 if (rc != 1) {
448 dataflash_perror (rc);
449 return (1);
450 }
451 return 0;
452 }
453
454 if (addr_dataflash(addr) && addr_dataflash(dest)){
455 puts ("Unsupported combination of source/destination.\n\r");
456 return 1;
457 }
458#endif
459
460#ifdef CONFIG_BLACKFIN
461
462 if (addr_bfin_on_chip_mem(dest) || addr_bfin_on_chip_mem(addr)) {
463 memcpy((void *)dest, (void *)addr, count * size);
464 return 0;
465 }
466#endif
467
468 bytes = size * count;
469 buf = map_sysmem(dest, bytes);
470 src = map_sysmem(addr, bytes);
471 while (count-- > 0) {
472 if (size == 4)
473 *((u32 *)buf) = *((u32 *)src);
474#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
475 else if (size == 8)
476 *((u64 *)buf) = *((u64 *)src);
477#endif
478 else if (size == 2)
479 *((u16 *)buf) = *((u16 *)src);
480 else
481 *((u8 *)buf) = *((u8 *)src);
482 src += size;
483 buf += size;
484
485
486 if ((count % (64 << 10)) == 0)
487 WATCHDOG_RESET();
488 }
489 unmap_sysmem(buf);
490 unmap_sysmem(src);
491
492 return 0;
493}
494
495static int do_mem_base(cmd_tbl_t *cmdtp, int flag, int argc,
496 char * const argv[])
497{
498 if (argc > 1) {
499
500
501 base_address = simple_strtoul(argv[1], NULL, 16);
502 }
503
504
505 printf("Base Address: 0x%08lx\n", base_address);
506 return 0;
507}
508
509static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
510 char * const argv[])
511{
512 ulong addr, length, i, bytes;
513 int size;
514#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
515 volatile u64 *llp;
516#endif
517 volatile u32 *longp;
518 volatile u16 *shortp;
519 volatile u8 *cp;
520 const void *buf;
521
522 if (argc < 3)
523 return CMD_RET_USAGE;
524
525
526
527
528
529 if ((size = cmd_get_data_size(argv[0], 4)) < 0)
530 return 1;
531
532
533
534 addr = simple_strtoul(argv[1], NULL, 16);
535
536
537
538 length = simple_strtoul(argv[2], NULL, 16);
539
540 bytes = size * length;
541 buf = map_sysmem(addr, bytes);
542
543
544
545
546 if (length == 1) {
547#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
548 if (size == 8) {
549 llp = (u64 *)buf;
550 for (;;)
551 i = *llp;
552 }
553#endif
554 if (size == 4) {
555 longp = (u32 *)buf;
556 for (;;)
557 i = *longp;
558 }
559 if (size == 2) {
560 shortp = (u16 *)buf;
561 for (;;)
562 i = *shortp;
563 }
564 cp = (u8 *)buf;
565 for (;;)
566 i = *cp;
567 }
568
569#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
570 if (size == 8) {
571 for (;;) {
572 llp = (u64 *)buf;
573 i = length;
574 while (i-- > 0)
575 *llp++;
576 }
577 }
578#endif
579 if (size == 4) {
580 for (;;) {
581 longp = (u32 *)buf;
582 i = length;
583 while (i-- > 0)
584 *longp++;
585 }
586 }
587 if (size == 2) {
588 for (;;) {
589 shortp = (u16 *)buf;
590 i = length;
591 while (i-- > 0)
592 *shortp++;
593 }
594 }
595 for (;;) {
596 cp = (u8 *)buf;
597 i = length;
598 while (i-- > 0)
599 *cp++;
600 }
601 unmap_sysmem(buf);
602
603 return 0;
604}
605
606#ifdef CONFIG_LOOPW
607static int do_mem_loopw(cmd_tbl_t *cmdtp, int flag, int argc,
608 char * const argv[])
609{
610 ulong addr, length, i, bytes;
611 int size;
612#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
613 volatile u64 *llp;
614 u64 data;
615#else
616 ulong data;
617#endif
618 volatile u32 *longp;
619 volatile u16 *shortp;
620 volatile u8 *cp;
621 void *buf;
622
623 if (argc < 4)
624 return CMD_RET_USAGE;
625
626
627
628
629
630 if ((size = cmd_get_data_size(argv[0], 4)) < 0)
631 return 1;
632
633
634
635 addr = simple_strtoul(argv[1], NULL, 16);
636
637
638
639 length = simple_strtoul(argv[2], NULL, 16);
640
641
642#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
643 data = simple_strtoull(argv[3], NULL, 16);
644#else
645 data = simple_strtoul(argv[3], NULL, 16);
646#endif
647
648 bytes = size * length;
649 buf = map_sysmem(addr, bytes);
650
651
652
653
654 if (length == 1) {
655#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
656 if (size == 8) {
657 llp = (u64 *)buf;
658 for (;;)
659 *llp = data;
660 }
661#endif
662 if (size == 4) {
663 longp = (u32 *)buf;
664 for (;;)
665 *longp = data;
666 }
667 if (size == 2) {
668 shortp = (u16 *)buf;
669 for (;;)
670 *shortp = data;
671 }
672 cp = (u8 *)buf;
673 for (;;)
674 *cp = data;
675 }
676
677#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
678 if (size == 8) {
679 for (;;) {
680 llp = (u64 *)buf;
681 i = length;
682 while (i-- > 0)
683 *llp++ = data;
684 }
685 }
686#endif
687 if (size == 4) {
688 for (;;) {
689 longp = (u32 *)buf;
690 i = length;
691 while (i-- > 0)
692 *longp++ = data;
693 }
694 }
695 if (size == 2) {
696 for (;;) {
697 shortp = (u16 *)buf;
698 i = length;
699 while (i-- > 0)
700 *shortp++ = data;
701 }
702 }
703 for (;;) {
704 cp = (u8 *)buf;
705 i = length;
706 while (i-- > 0)
707 *cp++ = data;
708 }
709}
710#endif
711
712#ifdef CONFIG_CMD_MEMTEST
713static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr,
714 vu_long *dummy)
715{
716 vu_long *addr;
717 ulong errs = 0;
718 ulong val, readback;
719 int j;
720 vu_long offset;
721 vu_long test_offset;
722 vu_long pattern;
723 vu_long temp;
724 vu_long anti_pattern;
725 vu_long num_words;
726 static const ulong bitpattern[] = {
727 0x00000001,
728 0x00000003,
729 0x00000007,
730 0x0000000F,
731 0x00000005,
732 0x00000015,
733 0x00000055,
734 0xaaaaaaaa,
735 };
736
737 num_words = (end_addr - start_addr) / sizeof(vu_long);
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756 addr = buf;
757 for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) {
758 val = bitpattern[j];
759 for (; val != 0; val <<= 1) {
760 *addr = val;
761 *dummy = ~val;
762 readback = *addr;
763 if (readback != val) {
764 printf("FAILURE (data line): "
765 "expected %08lx, actual %08lx\n",
766 val, readback);
767 errs++;
768 if (ctrlc())
769 return -1;
770 }
771 *addr = ~val;
772 *dummy = val;
773 readback = *addr;
774 if (readback != ~val) {
775 printf("FAILURE (data line): "
776 "Is %08lx, should be %08lx\n",
777 readback, ~val);
778 errs++;
779 if (ctrlc())
780 return -1;
781 }
782 }
783 }
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819 pattern = (vu_long) 0xaaaaaaaa;
820 anti_pattern = (vu_long) 0x55555555;
821
822 debug("%s:%d: length = 0x%.8lx\n", __func__, __LINE__, num_words);
823
824
825
826
827 for (offset = 1; offset < num_words; offset <<= 1)
828 addr[offset] = pattern;
829
830
831
832
833 test_offset = 0;
834 addr[test_offset] = anti_pattern;
835
836 for (offset = 1; offset < num_words; offset <<= 1) {
837 temp = addr[offset];
838 if (temp != pattern) {
839 printf("\nFAILURE: Address bit stuck high @ 0x%.8lx:"
840 " expected 0x%.8lx, actual 0x%.8lx\n",
841 start_addr + offset*sizeof(vu_long),
842 pattern, temp);
843 errs++;
844 if (ctrlc())
845 return -1;
846 }
847 }
848 addr[test_offset] = pattern;
849 WATCHDOG_RESET();
850
851
852
853
854 for (test_offset = 1; test_offset < num_words; test_offset <<= 1) {
855 addr[test_offset] = anti_pattern;
856
857 for (offset = 1; offset < num_words; offset <<= 1) {
858 temp = addr[offset];
859 if ((temp != pattern) && (offset != test_offset)) {
860 printf("\nFAILURE: Address bit stuck low or"
861 " shorted @ 0x%.8lx: expected 0x%.8lx,"
862 " actual 0x%.8lx\n",
863 start_addr + offset*sizeof(vu_long),
864 pattern, temp);
865 errs++;
866 if (ctrlc())
867 return -1;
868 }
869 }
870 addr[test_offset] = pattern;
871 }
872
873
874
875
876
877
878
879
880
881
882
883
884
885 num_words++;
886
887
888
889
890 for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
891 WATCHDOG_RESET();
892 addr[offset] = pattern;
893 }
894
895
896
897
898 for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
899 WATCHDOG_RESET();
900 temp = addr[offset];
901 if (temp != pattern) {
902 printf("\nFAILURE (read/write) @ 0x%.8lx:"
903 " expected 0x%.8lx, actual 0x%.8lx)\n",
904 start_addr + offset*sizeof(vu_long),
905 pattern, temp);
906 errs++;
907 if (ctrlc())
908 return -1;
909 }
910
911 anti_pattern = ~pattern;
912 addr[offset] = anti_pattern;
913 }
914
915
916
917
918 for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
919 WATCHDOG_RESET();
920 anti_pattern = ~pattern;
921 temp = addr[offset];
922 if (temp != anti_pattern) {
923 printf("\nFAILURE (read/write): @ 0x%.8lx:"
924 " expected 0x%.8lx, actual 0x%.8lx)\n",
925 start_addr + offset*sizeof(vu_long),
926 anti_pattern, temp);
927 errs++;
928 if (ctrlc())
929 return -1;
930 }
931 addr[offset] = 0;
932 }
933
934 return errs;
935}
936
937static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr,
938 vu_long pattern, int iteration)
939{
940 vu_long *end;
941 vu_long *addr;
942 ulong errs = 0;
943 ulong incr, length;
944 ulong val, readback;
945
946
947 incr = 1;
948 if (iteration & 1) {
949 incr = -incr;
950
951
952
953
954
955
956 if (pattern & 0x80000000)
957 pattern = -pattern;
958 else
959 pattern = ~pattern;
960 }
961 length = (end_addr - start_addr) / sizeof(ulong);
962 end = buf + length;
963 printf("\rPattern %08lX Writing..."
964 "%12s"
965 "\b\b\b\b\b\b\b\b\b\b",
966 pattern, "");
967
968 for (addr = buf, val = pattern; addr < end; addr++) {
969 WATCHDOG_RESET();
970 *addr = val;
971 val += incr;
972 }
973
974 puts("Reading...");
975
976 for (addr = buf, val = pattern; addr < end; addr++) {
977 WATCHDOG_RESET();
978 readback = *addr;
979 if (readback != val) {
980 ulong offset = addr - buf;
981
982 printf("\nMem error @ 0x%08X: "
983 "found %08lX, expected %08lX\n",
984 (uint)(uintptr_t)(start_addr + offset*sizeof(vu_long)),
985 readback, val);
986 errs++;
987 if (ctrlc())
988 return -1;
989 }
990 val += incr;
991 }
992
993 return errs;
994}
995
996
997
998
999
1000
1001static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
1002 char * const argv[])
1003{
1004 ulong start, end;
1005 vu_long *buf, *dummy;
1006 ulong iteration_limit = 0;
1007 int ret;
1008 ulong errs = 0;
1009 ulong pattern = 0;
1010 int iteration;
1011#if defined(CONFIG_SYS_ALT_MEMTEST)
1012 const int alt_test = 1;
1013#else
1014 const int alt_test = 0;
1015#endif
1016
1017 start = CONFIG_SYS_MEMTEST_START;
1018 end = CONFIG_SYS_MEMTEST_END;
1019
1020 if (argc > 1)
1021 if (strict_strtoul(argv[1], 16, &start) < 0)
1022 return CMD_RET_USAGE;
1023
1024 if (argc > 2)
1025 if (strict_strtoul(argv[2], 16, &end) < 0)
1026 return CMD_RET_USAGE;
1027
1028 if (argc > 3)
1029 if (strict_strtoul(argv[3], 16, &pattern) < 0)
1030 return CMD_RET_USAGE;
1031
1032 if (argc > 4)
1033 if (strict_strtoul(argv[4], 16, &iteration_limit) < 0)
1034 return CMD_RET_USAGE;
1035
1036 if (end < start) {
1037 printf("Refusing to do empty test\n");
1038 return -1;
1039 }
1040
1041 printf("Testing %08lx ... %08lx:\n", start, end);
1042 debug("%s:%d: start %#08lx end %#08lx\n", __func__, __LINE__,
1043 start, end);
1044
1045 buf = map_sysmem(start, end - start);
1046 dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long));
1047 for (iteration = 0;
1048 !iteration_limit || iteration < iteration_limit;
1049 iteration++) {
1050 if (ctrlc()) {
1051 errs = -1UL;
1052 break;
1053 }
1054
1055 printf("Iteration: %6d\r", iteration + 1);
1056 debug("\n");
1057 if (alt_test) {
1058 errs = mem_test_alt(buf, start, end, dummy);
1059 } else {
1060 errs = mem_test_quick(buf, start, end, pattern,
1061 iteration);
1062 }
1063 if (errs == -1UL)
1064 break;
1065 }
1066
1067
1068
1069
1070
1071
1072 {
1073 void *vbuf = (void *)buf;
1074 void *vdummy = (void *)dummy;
1075
1076 unmap_sysmem(vbuf);
1077 unmap_sysmem(vdummy);
1078 }
1079
1080 if (errs == -1UL) {
1081
1082 putc('\n');
1083 ret = 1;
1084 } else {
1085 printf("Tested %d iteration(s) with %lu errors.\n",
1086 iteration, errs);
1087 ret = errs != 0;
1088 }
1089
1090 return ret;
1091}
1092#endif
1093
1094
1095
1096
1097
1098
1099
1100static int
1101mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
1102{
1103 ulong addr;
1104#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1105 u64 i;
1106#else
1107 ulong i;
1108#endif
1109 int nbytes, size;
1110 void *ptr = NULL;
1111
1112 if (argc != 2)
1113 return CMD_RET_USAGE;
1114
1115 bootretry_reset_cmd_timeout();
1116
1117
1118
1119 addr = mm_last_addr;
1120 size = mm_last_size;
1121
1122 if ((flag & CMD_FLAG_REPEAT) == 0) {
1123
1124
1125
1126 if ((size = cmd_get_data_size(argv[0], 4)) < 0)
1127 return 1;
1128
1129
1130
1131 addr = simple_strtoul(argv[1], NULL, 16);
1132 addr += base_address;
1133 }
1134
1135#ifdef CONFIG_HAS_DATAFLASH
1136 if (addr_dataflash(addr)){
1137 puts ("Can't modify DataFlash in place. Use cp instead.\n\r");
1138 return 0;
1139 }
1140#endif
1141
1142#ifdef CONFIG_BLACKFIN
1143 if (addr_bfin_on_chip_mem(addr)) {
1144 puts ("Can't modify L1 instruction in place. Use cp instead.\n\r");
1145 return 0;
1146 }
1147#endif
1148
1149
1150
1151
1152 do {
1153 ptr = map_sysmem(addr, size);
1154 printf("%08lx:", addr);
1155 if (size == 4)
1156 printf(" %08x", *((u32 *)ptr));
1157#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1158 else if (size == 8)
1159 printf(" %016" PRIx64, *((u64 *)ptr));
1160#endif
1161 else if (size == 2)
1162 printf(" %04x", *((u16 *)ptr));
1163 else
1164 printf(" %02x", *((u8 *)ptr));
1165
1166 nbytes = cli_readline(" ? ");
1167 if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
1168
1169
1170
1171 if (incrflag)
1172 addr += nbytes ? -size : size;
1173 nbytes = 1;
1174
1175 bootretry_reset_cmd_timeout();
1176 }
1177#ifdef CONFIG_BOOT_RETRY_TIME
1178 else if (nbytes == -2) {
1179 break;
1180 }
1181#endif
1182 else {
1183 char *endp;
1184#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1185 i = simple_strtoull(console_buffer, &endp, 16);
1186#else
1187 i = simple_strtoul(console_buffer, &endp, 16);
1188#endif
1189 nbytes = endp - console_buffer;
1190 if (nbytes) {
1191
1192
1193 bootretry_reset_cmd_timeout();
1194 if (size == 4)
1195 *((u32 *)ptr) = i;
1196#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1197 else if (size == 8)
1198 *((u64 *)ptr) = i;
1199#endif
1200 else if (size == 2)
1201 *((u16 *)ptr) = i;
1202 else
1203 *((u8 *)ptr) = i;
1204 if (incrflag)
1205 addr += size;
1206 }
1207 }
1208 } while (nbytes);
1209 if (ptr)
1210 unmap_sysmem(ptr);
1211
1212 mm_last_addr = addr;
1213 mm_last_size = size;
1214 return 0;
1215}
1216
1217#ifdef CONFIG_CMD_CRC32
1218
1219static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1220{
1221 int flags = 0;
1222 int ac;
1223 char * const *av;
1224
1225 if (argc < 3)
1226 return CMD_RET_USAGE;
1227
1228 av = argv + 1;
1229 ac = argc - 1;
1230#ifdef CONFIG_HASH_VERIFY
1231 if (strcmp(*av, "-v") == 0) {
1232 flags |= HASH_FLAG_VERIFY | HASH_FLAG_ENV;
1233 av++;
1234 ac--;
1235 }
1236#endif
1237
1238 return hash_command("crc32", flags, cmdtp, flag, ac, av);
1239}
1240
1241#endif
1242
1243
1244U_BOOT_CMD(
1245 md, 3, 1, do_mem_md,
1246 "memory display",
1247#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1248 "[.b, .w, .l, .q] address [# of objects]"
1249#else
1250 "[.b, .w, .l] address [# of objects]"
1251#endif
1252);
1253
1254
1255U_BOOT_CMD(
1256 mm, 2, 1, do_mem_mm,
1257 "memory modify (auto-incrementing address)",
1258#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1259 "[.b, .w, .l, .q] address"
1260#else
1261 "[.b, .w, .l] address"
1262#endif
1263);
1264
1265
1266U_BOOT_CMD(
1267 nm, 2, 1, do_mem_nm,
1268 "memory modify (constant address)",
1269#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1270 "[.b, .w, .l, .q] address"
1271#else
1272 "[.b, .w, .l] address"
1273#endif
1274);
1275
1276U_BOOT_CMD(
1277 mw, 4, 1, do_mem_mw,
1278 "memory write (fill)",
1279#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1280 "[.b, .w, .l, .q] address value [count]"
1281#else
1282 "[.b, .w, .l] address value [count]"
1283#endif
1284);
1285
1286U_BOOT_CMD(
1287 cp, 4, 1, do_mem_cp,
1288 "memory copy",
1289#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1290 "[.b, .w, .l, .q] source target count"
1291#else
1292 "[.b, .w, .l] source target count"
1293#endif
1294);
1295
1296U_BOOT_CMD(
1297 cmp, 4, 1, do_mem_cmp,
1298 "memory compare",
1299#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1300 "[.b, .w, .l, .q] addr1 addr2 count"
1301#else
1302 "[.b, .w, .l] addr1 addr2 count"
1303#endif
1304);
1305
1306#ifdef CONFIG_CMD_CRC32
1307
1308#ifndef CONFIG_HASH_VERIFY
1309
1310U_BOOT_CMD(
1311 crc32, 4, 1, do_mem_crc,
1312 "checksum calculation",
1313 "address count [addr]\n - compute CRC32 checksum [save at addr]"
1314);
1315
1316#else
1317
1318U_BOOT_CMD(
1319 crc32, 5, 1, do_mem_crc,
1320 "checksum calculation",
1321 "address count [addr]\n - compute CRC32 checksum [save at addr]\n"
1322 "-v address count crc\n - verify crc of memory area"
1323);
1324
1325#endif
1326
1327#endif
1328
1329#ifdef CONFIG_CMD_MEMINFO
1330__weak void board_show_dram(phys_size_t size)
1331{
1332 puts("DRAM: ");
1333 print_size(size, "\n");
1334}
1335
1336static int do_mem_info(cmd_tbl_t *cmdtp, int flag, int argc,
1337 char * const argv[])
1338{
1339 board_show_dram(gd->ram_size);
1340
1341 return 0;
1342}
1343#endif
1344
1345U_BOOT_CMD(
1346 base, 2, 1, do_mem_base,
1347 "print or set address offset",
1348 "\n - print address offset for memory commands\n"
1349 "base off\n - set address offset for memory commands to 'off'"
1350);
1351
1352U_BOOT_CMD(
1353 loop, 3, 1, do_mem_loop,
1354 "infinite loop on address range",
1355#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1356 "[.b, .w, .l, .q] address number_of_objects"
1357#else
1358 "[.b, .w, .l] address number_of_objects"
1359#endif
1360);
1361
1362#ifdef CONFIG_LOOPW
1363U_BOOT_CMD(
1364 loopw, 4, 1, do_mem_loopw,
1365 "infinite write loop on address range",
1366#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1367 "[.b, .w, .l, .q] address number_of_objects data_to_write"
1368#else
1369 "[.b, .w, .l] address number_of_objects data_to_write"
1370#endif
1371);
1372#endif
1373
1374#ifdef CONFIG_CMD_MEMTEST
1375U_BOOT_CMD(
1376 mtest, 5, 1, do_mem_mtest,
1377 "simple RAM read/write test",
1378 "[start [end [pattern [iterations]]]]"
1379);
1380#endif
1381
1382#ifdef CONFIG_MX_CYCLIC
1383U_BOOT_CMD(
1384 mdc, 4, 1, do_mem_mdc,
1385 "memory display cyclic",
1386#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1387 "[.b, .w, .l, .q] address count delay(ms)"
1388#else
1389 "[.b, .w, .l] address count delay(ms)"
1390#endif
1391);
1392
1393U_BOOT_CMD(
1394 mwc, 4, 1, do_mem_mwc,
1395 "memory write cyclic",
1396#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
1397 "[.b, .w, .l, .q] address value delay(ms)"
1398#else
1399 "[.b, .w, .l] address value delay(ms)"
1400#endif
1401);
1402#endif
1403
1404#ifdef CONFIG_CMD_MEMINFO
1405U_BOOT_CMD(
1406 meminfo, 3, 1, do_mem_info,
1407 "display memory information",
1408 ""
1409);
1410#endif
1411