diff --git a/cmd/memtester/memtester.c b/cmd/memtester/memtester.c index 8f624edbd2..7936c03303 100644 --- a/cmd/memtester/memtester.c +++ b/cmd/memtester/memtester.c @@ -61,7 +61,8 @@ off_t physaddrbase; * err_exit: 1: exit test when found fail. * return 0: success, other: fail */ -int doing_memtester(ul *arg, ul testenable, ul loops, ul err_exit) +int doing_memtester(ul *arg, ul testenable, ul loops, ul err_exit, + ul fix_bit, ul fix_level) { ul loop, i, j; ul start_adr[CONFIG_NR_DRAM_BANKS], length[CONFIG_NR_DRAM_BANKS]; @@ -115,7 +116,8 @@ int doing_memtester(ul *arg, ul testenable, ul loops, ul err_exit) if (testenable && (!((1 << i) & testenable))) continue; printf(" %-20s: ", tests[i].name); - if (!tests[i].fp(bufa[j], bufb[j], count[j])) { + if (!tests[i].fp(bufa[j], bufb[j], count[j], + fix_bit, fix_level)) { printf("ok\n"); } else { exit_code |= EXIT_FAIL_OTHERTEST; @@ -157,6 +159,8 @@ static int do_memtester(cmd_tbl_t *cmdtp, int flag, int argc, ul loops = 0; ul testenable = 0; ul err_exit = 0; + ul fix_bit = 0; + ul fix_level = 0; printf("memtester version " __version__ " (%d-bit)\n", UL_LEN); printf("Copyright (C) 2001-2012 Charles Cazabon.\n"); @@ -184,18 +188,26 @@ static int do_memtester(cmd_tbl_t *cmdtp, int flag, int argc, return CMD_RET_USAGE; if (argc > 5) - if (strict_strtoul(argv[5], 0, &loops) < 0) + if (strict_strtoul(argv[5], 0, &fix_bit) < 0) return CMD_RET_USAGE; - doing_memtester(arg, testenable, loops, err_exit); + if (argc > 6) + if (strict_strtoul(argv[6], 0, &fix_level) < 0) + return CMD_RET_USAGE; + + if (argc > 7) + if (strict_strtoul(argv[7], 0, &loops) < 0) + return CMD_RET_USAGE; + + doing_memtester(arg, testenable, loops, err_exit, fix_bit, fix_level); printf("Done.\n"); return 0; } -U_BOOT_CMD(memtester, 6, 1, do_memtester, +U_BOOT_CMD(memtester, 8, 1, do_memtester, "do memtester", - "[start length [testenable err_exit [loop]]]\n" + "[start length [testenable err_exit fix_bit fix_level [loop]]]\n" "start: start address, should be 4k align\n" "length: test length, should be 4k align, if 0 testing full space\n" "testenable[option]: enable pattern by set bit to 1, null or 0" @@ -220,6 +232,8 @@ U_BOOT_CMD(memtester, 6, 1, do_memtester, " bit17: test stuck address\n" " example: testenable=0x1000,enable Bit Flip only\n" "err_exit: if 1 stop testing immediately when finding error\n" + "fix_bit: fixed bit to a exact level\n" + "fix_level: fix_bit's level, 0: low, 1: high\n" "loop[option]: testing loop, if 0 or null endless loop\n" "example:\n" " memtester 0x200000 0x1000000: start address: 0x200000 length:" diff --git a/cmd/memtester/memtester.h b/cmd/memtester/memtester.h index 779a1ece41..5275a8cf82 100644 --- a/cmd/memtester/memtester.h +++ b/cmd/memtester/memtester.h @@ -23,5 +23,6 @@ extern int use_phys; extern off_t physaddrbase; int doing_memtester(unsigned long *arg, unsigned long testenable, - unsigned long loops, unsigned long err_exit); + unsigned long loops, unsigned long err_exit, + unsigned long fix_bit, unsigned long fix_level); #endif /* _CMD_MEMTESTER_H */ diff --git a/cmd/memtester/tests.c b/cmd/memtester/tests.c index f50db4c19e..4f27c1c4cd 100644 --- a/cmd/memtester/tests.c +++ b/cmd/memtester/tests.c @@ -114,7 +114,8 @@ int test_stuck_address(u32v *bufa, size_t count) return 0; } -int test_random_value(u32v *bufa, u32v *bufb, size_t count) +int test_random_value(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -136,7 +137,9 @@ int test_random_value(u32v *bufa, u32v *bufb, size_t count) return compare_regions(bufa, bufb, count); } -int test_xor_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_xor_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) + { u32v *p1 = bufa; u32v *p2 = bufb; @@ -150,7 +153,8 @@ int test_xor_comparison(u32v *bufa, u32v *bufb, size_t count) return compare_regions(bufa, bufb, count); } -int test_sub_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_sub_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -164,7 +168,8 @@ int test_sub_comparison(u32v *bufa, u32v *bufb, size_t count) return compare_regions(bufa, bufb, count); } -int test_mul_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_mul_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -178,7 +183,8 @@ int test_mul_comparison(u32v *bufa, u32v *bufb, size_t count) return compare_regions(bufa, bufb, count); } -int test_div_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_div_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -194,7 +200,8 @@ int test_div_comparison(u32v *bufa, u32v *bufb, size_t count) return compare_regions(bufa, bufb, count); } -int test_or_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_or_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -208,7 +215,8 @@ int test_or_comparison(u32v *bufa, u32v *bufb, size_t count) return compare_regions(bufa, bufb, count); } -int test_and_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_and_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -222,7 +230,8 @@ int test_and_comparison(u32v *bufa, u32v *bufb, size_t count) return compare_regions(bufa, bufb, count); } -int test_seqinc_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_seqinc_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -234,7 +243,8 @@ int test_seqinc_comparison(u32v *bufa, u32v *bufb, size_t count) return compare_regions(bufa, bufb, count); } -int test_solidbits_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_solidbits_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -248,6 +258,10 @@ int test_solidbits_comparison(u32v *bufa, u32v *bufb, size_t count) for (j = 0; j < 64; j++) { printf("\b\b\b\b\b\b\b\b\b\b\b"); q = (j % 2) == 0 ? UL_ONEBITS : 0; + if (fix_level) + q |= fix_bit; + else + q &= ~fix_bit; data[0] = data[2] = q; data[1] = data[3] = ~q; data_cpu_2_io(data, sizeof(data)); @@ -268,7 +282,8 @@ int test_solidbits_comparison(u32v *bufa, u32v *bufb, size_t count) return 0; } -int test_checkerboard_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_checkerboard_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -282,6 +297,11 @@ int test_checkerboard_comparison(u32v *bufa, u32v *bufb, size_t count) for (j = 0; j < 64; j++) { printf("\b\b\b\b\b\b\b\b\b\b\b"); q = (j % 2) == 0 ? CHECKERBOARD1 : CHECKERBOARD2; + if (fix_level) + q |= fix_bit; + else + q &= ~fix_bit; + data[0] = data[2] = q; data[1] = data[3] = ~q; data_cpu_2_io(data, sizeof(data)); @@ -302,12 +322,14 @@ int test_checkerboard_comparison(u32v *bufa, u32v *bufb, size_t count) return 0; } -int test_blockseq_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_blockseq_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; unsigned int j; u32 data[4]; + u32 q; size_t i; printf(" "); @@ -318,8 +340,17 @@ int test_blockseq_comparison(u32v *bufa, u32v *bufb, size_t count) p2 = (u32v *)bufb; printf("setting %3u", j); fflush(stdout); - data[0] = data[2] = (u32)UL_BYTE(j); - data[1] = data[3] = (u32)UL_BYTE(j); + q = (u32)UL_BYTE(j); + if (fix_level) + q |= fix_bit; + else + q &= ~fix_bit; + + data[0] = q; + data[1] = q; + data[2] = q; + data[3] = q; + data_cpu_2_io(data, sizeof(data)); for (i = 0; i < count; i++) @@ -335,12 +366,14 @@ int test_blockseq_comparison(u32v *bufa, u32v *bufb, size_t count) return 0; } -int test_walkbits0_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_walkbits0_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; unsigned int j; u32 data[4]; + u32 q; size_t i; printf(" "); @@ -352,12 +385,19 @@ int test_walkbits0_comparison(u32v *bufa, u32v *bufb, size_t count) printf("setting %3u", j); fflush(stdout); if (j < UL_LEN) - data[0] = ONE << j; + q = ONE << j; else - data[0] = ONE << (UL_LEN * 2 - j - 1); - data[1] = data[0]; - data[2] = data[0]; - data[3] = data[0]; + q = ONE << (UL_LEN * 2 - j - 1); + + if (fix_level) + q |= fix_bit; + else + q &= ~fix_bit; + + data[0] = q; + data[1] = q; + data[2] = q; + data[3] = q; data_cpu_2_io(data, sizeof(data)); for (i = 0; i < count; i++) { @@ -374,12 +414,14 @@ int test_walkbits0_comparison(u32v *bufa, u32v *bufb, size_t count) return 0; } -int test_walkbits1_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_walkbits1_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; unsigned int j; u32 data[4]; + u32 q; size_t i; printf(" "); @@ -391,12 +433,18 @@ int test_walkbits1_comparison(u32v *bufa, u32v *bufb, size_t count) printf("setting %3u", j); fflush(stdout); if (j < UL_LEN) - data[0] = UL_ONEBITS ^ (ONE << j); + q = UL_ONEBITS ^ (ONE << j); else - data[0] = UL_ONEBITS ^ (ONE << (UL_LEN * 2 - j - 1)); - data[1] = data[0]; - data[2] = data[0]; - data[3] = data[0]; + q = UL_ONEBITS ^ (ONE << (UL_LEN * 2 - j - 1)); + if (fix_level) + q |= fix_bit; + else + q &= ~fix_bit; + + data[0] = q; + data[1] = q; + data[2] = q; + data[3] = q; data_cpu_2_io(data, sizeof(data)); for (i = 0; i < count; i++) { @@ -413,7 +461,8 @@ int test_walkbits1_comparison(u32v *bufa, u32v *bufb, size_t count) return 0; } -int test_bitspread_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_bitspread_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -438,6 +487,13 @@ int test_bitspread_comparison(u32v *bufa, u32v *bufb, size_t count) data[1] = UL_ONEBITS ^ (ONE << (UL_LEN * 2 - 1 - j) | (ONE << (UL_LEN * 2 + 1 - j))); } + if (fix_level) { + data[0] |= fix_bit; + data[1] |= fix_bit; + } else { + data[0] &= ~fix_bit; + data[1] &= ~fix_bit; + } data[2] = data[0]; data[3] = data[1]; data_cpu_2_io(data, sizeof(data)); @@ -456,7 +512,8 @@ int test_bitspread_comparison(u32v *bufa, u32v *bufb, size_t count) return 0; } -int test_bitflip_comparison(u32v *bufa, u32v *bufb, size_t count) +int test_bitflip_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u32v *p1 = bufa; u32v *p2 = bufb; @@ -474,6 +531,11 @@ int test_bitflip_comparison(u32v *bufa, u32v *bufb, size_t count) q = ~q; printf("setting %3u", k * 8 + j); fflush(stdout); + if (fix_level) + q |= fix_bit; + else + q &= ~fix_bit; + data[0] = data[2] = q; data[1] = data[3] = ~q; data_cpu_2_io(data, sizeof(data)); @@ -494,7 +556,8 @@ int test_bitflip_comparison(u32v *bufa, u32v *bufb, size_t count) } #ifdef TEST_NARROW_WRITES -int test_8bit_wide_random(u32v *bufa, u32v *bufb, size_t count) +int test_8bit_wide_random(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u8v *p1, *t; u32v *p2; @@ -531,7 +594,8 @@ int test_8bit_wide_random(u32v *bufa, u32v *bufb, size_t count) return 0; } -int test_16bit_wide_random(u32v *bufa, u32v *bufb, size_t count) +int test_16bit_wide_random(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level) { u16v *p1, *t; u32v *p2; diff --git a/cmd/memtester/tests.h b/cmd/memtester/tests.h index cfd096e560..b3ddcaed2e 100644 --- a/cmd/memtester/tests.h +++ b/cmd/memtester/tests.h @@ -19,38 +19,38 @@ int test_stuck_address(u32v *bufa, size_t count); int test_random_value(u32v *bufa, - u32v *bufb, size_t count); + u32v *bufb, size_t count, ul fix_bit, ul fix_level); int test_xor_comparison(u32v *bufa, - u32v *bufb, size_t count); + u32v *bufb, size_t count, ul fix_bit, ul fix_level); int test_sub_comparison(u32v *bufa, - u32v *bufb, size_t count); + u32v *bufb, size_t count, ul fix_bit, ul fix_level); int test_mul_comparison(u32v *bufa, - u32v *bufb, size_t count); + u32v *bufb, size_t count, ul fix_bit, ul fix_level); int test_div_comparison(u32v *bufa, - u32v *bufb, size_t count); + u32v *bufb, size_t count, ul fix_bit, ul fix_level); int test_or_comparison(u32v *bufa, - u32v *bufb, size_t count); + u32v *bufb, size_t count, ul fix_bit, ul fix_level); int test_and_comparison(u32v *bufa, - u32v *bufb, size_t count); -int test_seqinc_comparison(u32v *bufa, - u32v *bufb, size_t count); -int test_solidbits_comparison(u32v *bufa, - u32v *bufb, size_t count); -int test_checkerboard_comparison(u32v *bufa, - u32v *bufb, size_t count); -int test_blockseq_comparison(u32v *bufa, - u32v *bufb, size_t count); -int test_walkbits0_comparison(u32v *bufa, - u32v *bufb, size_t count); -int test_walkbits1_comparison(u32v *bufa, - u32v *bufb, size_t count); -int test_bitspread_comparison(u32v *bufa, - u32v *bufb, size_t count); -int test_bitflip_comparison(u32v *bufa, - u32v *bufb, size_t count); + u32v *bufb, size_t count, ul fix_bit, ul fix_level); +int test_seqinc_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); +int test_solidbits_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); +int test_checkerboard_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); +int test_blockseq_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); +int test_walkbits0_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); +int test_walkbits1_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); +int test_bitspread_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); +int test_bitflip_comparison(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); #ifdef TEST_NARROW_WRITES -int test_8bit_wide_random(u32v *bufa, - u32v *bufb, size_t count); -int test_16bit_wide_random(u32v *bufa, - u32v *bufb, size_t count); +int test_8bit_wide_random(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); +int test_16bit_wide_random(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); #endif diff --git a/cmd/memtester/types.h b/cmd/memtester/types.h index 4442eb3c2e..3fa4ca5c9d 100644 --- a/cmd/memtester/types.h +++ b/cmd/memtester/types.h @@ -24,7 +24,8 @@ typedef unsigned short volatile u16v; struct test { char *name; - int (*fp)(u32v *bufa, u32v *bufb, size_t count); + int (*fp)(u32v *bufa, u32v *bufb, size_t count, + ul fix_bit, ul fix_level); }; #endif /* __MEMTESTER_TYPES_H */