X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cmd%2Fmem.c;h=9b97f7bf694458e39e31ed981504790c6bf6d986;hb=HEAD;hp=545534b1fc7265fb8ca9e3ca833248bc1d86c9ee;hpb=a4ef0657e3075d0f951d78cc1398cb7e05af648a;p=oweals%2Fu-boot.git diff --git a/cmd/mem.c b/cmd/mem.c index 545534b1fc..9b97f7bf69 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -16,11 +16,16 @@ #include #include #include +#include #include +#include #include +#include #include #include +#include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -28,7 +33,7 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_SYS_MEMTEST_SCRATCH 0 #endif -static int mod_mem(cmd_tbl_t *, int, int, int, char * const []); +static int mod_mem(struct cmd_tbl *, int, int, int, char * const []); /* Display values from last command. * Memory modify remembered values are different from display memory. @@ -45,7 +50,8 @@ static ulong base_address = 0; * md{.b, .w, .l, .q} {addr} {len} */ #define DISP_LINE_LEN 16 -static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_mem_md(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { ulong addr, length, bytes; const void *buf; @@ -95,18 +101,22 @@ static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return (rc); } -static int do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_mem_mm(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { return mod_mem (cmdtp, 1, flag, argc, argv); } -static int do_mem_nm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) + +static int do_mem_nm(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { return mod_mem (cmdtp, 0, flag, argc, argv); } -static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA u64 writeval; #else ulong writeval; @@ -131,7 +141,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* Get the value to write. */ -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA writeval = simple_strtoull(argv[2], NULL, 16); #else writeval = simple_strtoul(argv[2], NULL, 16); @@ -150,7 +160,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) while (count-- > 0) { if (size == 4) *((u32 *)buf) = (u32)writeval; -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA else if (size == 8) *((u64 *)buf) = (u64)writeval; #endif @@ -164,8 +174,9 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } -#ifdef CONFIG_MX_CYCLIC -static int do_mem_mdc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +#ifdef CONFIG_CMD_MX_CYCLIC +static int do_mem_mdc(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { int i; ulong count; @@ -180,7 +191,7 @@ static int do_mem_mdc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* delay for ms... */ for (i=0; i ms... */ for (i=0; i 1) { /* Set new base address. @@ -362,12 +386,12 @@ static int do_mem_base(cmd_tbl_t *cmdtp, int flag, int argc, return 0; } -static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) +static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { ulong addr, length, i, bytes; int size; -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA volatile u64 *llp; #endif volatile u32 *longp; @@ -400,7 +424,7 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, * If we have only one object, just run infinite loops. */ if (length == 1) { -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA if (size == 8) { llp = (u64 *)buf; for (;;) @@ -422,7 +446,7 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, i = *cp; } -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA if (size == 8) { for (;;) { llp = (u64 *)buf; @@ -460,12 +484,12 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, } #ifdef CONFIG_LOOPW -static int do_mem_loopw(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) +static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { ulong addr, length, i, bytes; int size; -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA volatile u64 *llp; u64 data; #else @@ -495,7 +519,7 @@ static int do_mem_loopw(cmd_tbl_t *cmdtp, int flag, int argc, length = simple_strtoul(argv[2], NULL, 16); /* data to write */ -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA data = simple_strtoull(argv[3], NULL, 16); #else data = simple_strtoul(argv[3], NULL, 16); @@ -508,7 +532,7 @@ static int do_mem_loopw(cmd_tbl_t *cmdtp, int flag, int argc, * If we have only one object, just run infinite loops. */ if (length == 1) { -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA if (size == 8) { llp = (u64 *)buf; for (;;) @@ -530,7 +554,7 @@ static int do_mem_loopw(cmd_tbl_t *cmdtp, int flag, int argc, *cp = data; } -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA if (size == 8) { for (;;) { llp = (u64 *)buf; @@ -790,6 +814,59 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, return errs; } +static int compare_regions(volatile unsigned long *bufa, + volatile unsigned long *bufb, size_t count) +{ + volatile unsigned long *p1 = bufa; + volatile unsigned long *p2 = bufb; + int errs = 0; + size_t i; + + for (i = 0; i < count; i++, p1++, p2++) { + if (*p1 != *p2) { + printf("FAILURE: 0x%08lx != 0x%08lx (delta=0x%08lx -> bit %ld) at offset 0x%08lx\n", + (unsigned long)*p1, (unsigned long)*p2, + *p1 ^ *p2, __ffs(*p1 ^ *p2), + (unsigned long)(i * sizeof(unsigned long))); + errs++; + } + } + + return errs; +} + +static ulong test_bitflip_comparison(volatile unsigned long *bufa, + volatile unsigned long *bufb, size_t count) +{ + volatile unsigned long *p1 = bufa; + volatile unsigned long *p2 = bufb; + unsigned int j, k; + unsigned long q; + size_t i; + int max; + int errs = 0; + + max = sizeof(unsigned long) * 8; + for (k = 0; k < max; k++) { + q = 0x00000001L << k; + for (j = 0; j < 8; j++) { + WATCHDOG_RESET(); + q = ~q; + p1 = (volatile unsigned long *)bufa; + p2 = (volatile unsigned long *)bufb; + for (i = 0; i < count; i++) + *p1++ = *p2++ = (i % 2) == 0 ? q : ~q; + + errs += compare_regions(bufa, bufb, count); + } + + if (ctrlc()) + return -1UL; + } + + return errs; +} + static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, vu_long pattern, int iteration) { @@ -854,21 +931,17 @@ static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, * 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[]) +static int do_mem_mtest(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { ulong start, end; - vu_long *buf, *dummy; + vu_long scratch_space; + vu_long *buf, *dummy = &scratch_space; ulong iteration_limit = 0; - int ret; + ulong count = 0; ulong errs = 0; /* number of errors, or -1 if interrupted */ ulong pattern = 0; int iteration; -#if defined(CONFIG_SYS_ALT_MEMTEST) - const int alt_test = 1; -#else - const int alt_test = 0; -#endif start = CONFIG_SYS_MEMTEST_START; end = CONFIG_SYS_MEMTEST_END; @@ -899,7 +972,6 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, 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++) { @@ -910,40 +982,33 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, printf("Iteration: %6d\r", iteration + 1); debug("\n"); - if (alt_test) { + if (IS_ENABLED(CONFIG_SYS_ALT_MEMTEST)) { errs = mem_test_alt(buf, start, end, dummy); + if (errs == -1UL) + break; + count += errs; + errs = test_bitflip_comparison(buf, + buf + (end - start) / 2, + (end - start) / + sizeof(unsigned long)); } else { errs = mem_test_quick(buf, start, end, pattern, iteration); } if (errs == -1UL) break; + count += errs; } - /* - * 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); - } + unmap_sysmem((void *)buf); 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; } + printf("Tested %d iteration(s) with %lu errors.\n", iteration, count); - return ret; + return errs != 0; } #endif /* CONFIG_CMD_MEMTEST */ @@ -954,10 +1019,11 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, * nm{.b, .w, .l, .q} {addr} */ static int -mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) +mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, + char *const argv[]) { ulong addr; -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA u64 i; #else ulong i; @@ -996,7 +1062,7 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) printf("%08lx:", addr); if (size == 4) printf(" %08x", *((u32 *)ptr)); -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA else if (size == 8) printf(" %016llx", *((u64 *)ptr)); #endif @@ -1023,7 +1089,7 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) #endif else { char *endp; -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA i = simple_strtoull(console_buffer, &endp, 16); #else i = simple_strtoul(console_buffer, &endp, 16); @@ -1035,7 +1101,7 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) bootretry_reset_cmd_timeout(); if (size == 4) *((u32 *)ptr) = i; -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA else if (size == 8) *((u64 *)ptr) = i; #endif @@ -1058,7 +1124,8 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) #ifdef CONFIG_CMD_CRC32 -static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_mem_crc(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { int flags = 0; int ac; @@ -1083,7 +1150,8 @@ static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #endif #ifdef CONFIG_CMD_RANDOM -static int do_random(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_random(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { unsigned long addr, len; unsigned long seed; // NOT INITIALIZED ON PURPOSE @@ -1091,10 +1159,8 @@ static int do_random(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) unsigned char *buf8; unsigned int i; - if (argc < 3 || argc > 4) { - printf("usage: %s []\n", argv[0]); - return 0; - } + if (argc < 3 || argc > 4) + return CMD_RET_USAGE; len = simple_strtoul(argv[2], NULL, 16); addr = simple_strtoul(argv[1], NULL, 16); @@ -1121,7 +1187,8 @@ static int do_random(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) unmap_sysmem(start); printf("%lu bytes filled with random data\n", len); - return 1; + + return CMD_RET_SUCCESS; } #endif @@ -1129,7 +1196,7 @@ static int do_random(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( md, 3, 1, do_mem_md, "memory display", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address [# of objects]" #else "[.b, .w, .l] address [# of objects]" @@ -1140,7 +1207,7 @@ U_BOOT_CMD( U_BOOT_CMD( mm, 2, 1, do_mem_mm, "memory modify (auto-incrementing address)", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address" #else "[.b, .w, .l] address" @@ -1151,7 +1218,7 @@ U_BOOT_CMD( U_BOOT_CMD( nm, 2, 1, do_mem_nm, "memory modify (constant address)", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address" #else "[.b, .w, .l] address" @@ -1161,7 +1228,7 @@ U_BOOT_CMD( U_BOOT_CMD( mw, 4, 1, do_mem_mw, "memory write (fill)", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address value [count]" #else "[.b, .w, .l] address value [count]" @@ -1171,7 +1238,7 @@ U_BOOT_CMD( U_BOOT_CMD( cp, 4, 1, do_mem_cp, "memory copy", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] source target count" #else "[.b, .w, .l] source target count" @@ -1181,7 +1248,7 @@ U_BOOT_CMD( U_BOOT_CMD( cmp, 4, 1, do_mem_cmp, "memory compare", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] addr1 addr2 count" #else "[.b, .w, .l] addr1 addr2 count" @@ -1212,8 +1279,8 @@ U_BOOT_CMD( #endif #ifdef CONFIG_CMD_MEMINFO -static int do_mem_info(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) +static int do_mem_info(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { puts("DRAM: "); print_size(gd->ram_size, "\n"); @@ -1232,7 +1299,7 @@ U_BOOT_CMD( U_BOOT_CMD( loop, 3, 1, do_mem_loop, "infinite loop on address range", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address number_of_objects" #else "[.b, .w, .l] address number_of_objects" @@ -1243,7 +1310,7 @@ U_BOOT_CMD( U_BOOT_CMD( loopw, 4, 1, do_mem_loopw, "infinite write loop on address range", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address number_of_objects data_to_write" #else "[.b, .w, .l] address number_of_objects data_to_write" @@ -1259,11 +1326,11 @@ U_BOOT_CMD( ); #endif /* CONFIG_CMD_MEMTEST */ -#ifdef CONFIG_MX_CYCLIC +#ifdef CONFIG_CMD_MX_CYCLIC U_BOOT_CMD( mdc, 4, 1, do_mem_mdc, "memory display cyclic", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address count delay(ms)" #else "[.b, .w, .l] address count delay(ms)" @@ -1273,13 +1340,13 @@ U_BOOT_CMD( U_BOOT_CMD( mwc, 4, 1, do_mem_mwc, "memory write cyclic", -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address value delay(ms)" #else "[.b, .w, .l] address value delay(ms)" #endif ); -#endif /* CONFIG_MX_CYCLIC */ +#endif /* CONFIG_CMD_MX_CYCLIC */ #ifdef CONFIG_CMD_MEMINFO U_BOOT_CMD(