1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * memtester version 4 4 * 5 * Very simple but very effective user-space memory tester. 6 * Originally by Simon Kirby <sim@stormix.com> <sim@neato.org> 7 * Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca> 8 * Version 3 not publicly released. 9 * Version 4 rewrite: 10 * Copyright (C) 2004-2012 Charles Cazabon <charlesc-memtester@pyropus.ca> 11 * Licensed under the terms of the GNU General Public License version 2 (only). 12 * See the file COPYING for details. 13 * 14 */ 15 16 #define __version__ "4.3.0" 17 18 #include <common.h> 19 #include <console.h> 20 #include "sizes.h" 21 #include "types.h" 22 #include "tests.h" 23 #include "../ddr_tool_common.h" 24 #include "../io_map.h" 25 26 #define EXIT_FAIL_NONSTARTER 0x01 27 #define EXIT_FAIL_ADDRESSLINES 0x02 28 #define EXIT_FAIL_OTHERTEST 0x04 29 30 struct test tests[] = { 31 {"Random Value", test_random_value}, 32 {"Compare XOR", test_xor_comparison}, 33 {"Compare SUB", test_sub_comparison}, 34 {"Compare MUL", test_mul_comparison}, 35 {"Compare DIV", test_div_comparison}, 36 {"Compare OR", test_or_comparison}, 37 {"Compare AND", test_and_comparison}, 38 {"Sequential Increment", test_seqinc_comparison}, 39 {"Solid Bits", test_solidbits_comparison}, 40 {"Block Sequential", test_blockseq_comparison}, 41 {"Checkerboard", test_checkerboard_comparison}, 42 {"Bit Spread", test_bitspread_comparison}, 43 {"Bit Flip", test_bitflip_comparison}, 44 {"Walking Ones", test_walkbits1_comparison}, 45 {"Walking Zeroes", test_walkbits0_comparison}, 46 #ifdef TEST_NARROW_WRITES 47 {"8-bit Writes", test_8bit_wide_random}, 48 {"16-bit Writes", test_16bit_wide_random}, 49 #endif 50 {NULL, NULL} 51 }; 52 53 int use_phys; 54 off_t physaddrbase; 55 56 /* 57 * arg[0]: test start address 58 * arg[1]: test length, unit: byte 59 * testenable: enable test case, if 0 enable all case 60 * loops: test loops, if 0 endless loop 61 * err_exit: 1: exit test when found fail. 62 * return 0: success, other: fail 63 */ 64 int doing_memtester(ul *arg, ul testenable, ul loops, ul err_exit, 65 ul fix_bit, ul fix_level) 66 { 67 ul loop, i, j; 68 ul start_adr[CONFIG_NR_DRAM_BANKS], length[CONFIG_NR_DRAM_BANKS]; 69 u32v * bufa[CONFIG_NR_DRAM_BANKS], *bufb[CONFIG_NR_DRAM_BANKS]; 70 ul count[CONFIG_NR_DRAM_BANKS]; 71 int exit_code = 0; 72 int abort = 0; 73 int test_banks; 74 75 get_print_available_addr(start_adr, length, 0); 76 77 test_banks = judge_test_addr(arg, start_adr, length); 78 79 if (!test_banks) { 80 printf("unavailable test address\n"); 81 return -1; 82 } 83 84 for (i = 0; i < ARRAY_SIZE(start_adr); i++) { 85 bufa[i] = (u32v *)start_adr[i]; 86 bufb[i] = (u32v *)(start_adr[i] + length[i] / 2); 87 count[i] = length[i] / 2 / sizeof(u32); 88 } 89 90 data_cpu_2_io_init(); 91 92 for (loop = 1; ((!loops) || loop <= loops); loop++) { 93 for (j = 0; j < test_banks; j++) { 94 if (!count[j]) 95 continue; 96 printf("testing:0x%lx - 0x%lx\n", (ul)bufa[j], 97 (ul)bufa[j] + count[j] * 2 * sizeof(u32)); 98 printf("Loop %lu", loop); 99 if (loops) 100 printf("/%lu", loops); 101 printf(":\n"); 102 if (testenable && ((1 << 17) & testenable)) { 103 printf(" %-20s: ", "Stuck Address"); 104 if (!test_stuck_address(bufa[j], count[j] * 2)) 105 printf("ok\n"); 106 else 107 exit_code |= EXIT_FAIL_ADDRESSLINES; 108 } 109 for (i = 0;; i++) { 110 if (!tests[i].name) 111 break; 112 /* If using a custom testenable, only run this 113 * test if the bit corresponding to this test 114 * was set by the user. 115 */ 116 if (testenable && (!((1 << i) & testenable))) 117 continue; 118 printf(" %-20s: ", tests[i].name); 119 if (!tests[i].fp(bufa[j], bufb[j], count[j], 120 fix_bit, fix_level)) { 121 printf("ok\n"); 122 } else { 123 exit_code |= EXIT_FAIL_OTHERTEST; 124 if (err_exit) { 125 goto out; 126 } 127 } 128 if (ctrlc()) { 129 abort = 1; 130 break; 131 } 132 } 133 printf("\n"); 134 if (abort) 135 break; 136 } 137 if (abort) 138 break; 139 } 140 141 out: 142 if (exit_code & EXIT_FAIL_NONSTARTER) 143 printf("Fail: EXIT_FAIL_NONSTARTER\n"); 144 if (exit_code & EXIT_FAIL_ADDRESSLINES) 145 printf("Fail: EXIT_FAIL_ADDRESSLINES\n"); 146 if (exit_code & EXIT_FAIL_OTHERTEST) 147 printf("Fail: EXIT_FAIL_OTHERTEST\n"); 148 149 if (exit_code) 150 return -1; 151 return 0; 152 } 153 154 static int do_memtester(cmd_tbl_t *cmdtp, int flag, int argc, 155 char *const argv[]) 156 { 157 ul start_adr[CONFIG_NR_DRAM_BANKS], length[CONFIG_NR_DRAM_BANKS]; 158 ul arg[2]; 159 ul loops = 0; 160 ul testenable = 0; 161 ul err_exit = 0; 162 ul fix_bit = 0; 163 ul fix_level = 0; 164 165 printf("memtester version " __version__ " (%d-bit)\n", UL_LEN); 166 printf("Copyright (C) 2001-2012 Charles Cazabon.\n"); 167 printf("Licensed under the GNU General Public License version 2 (only).\n"); 168 printf("\n"); 169 170 get_print_available_addr(start_adr, length, 1); 171 172 if (argc < 2) 173 return CMD_RET_USAGE; 174 175 if (strict_strtoul(argv[1], 0, &arg[0]) < 0) 176 return CMD_RET_USAGE; 177 178 if (argc > 2) 179 if (strict_strtoul(argv[2], 0, &arg[1]) < 0) 180 return CMD_RET_USAGE; 181 182 if (argc > 3) 183 if (strict_strtoul(argv[3], 0, &testenable) < 0) 184 return CMD_RET_USAGE; 185 186 if (argc > 4) 187 if (strict_strtoul(argv[4], 0, &err_exit) < 0) 188 return CMD_RET_USAGE; 189 190 if (argc > 5) 191 if (strict_strtoul(argv[5], 0, &fix_bit) < 0) 192 return CMD_RET_USAGE; 193 194 if (argc > 6) 195 if (strict_strtoul(argv[6], 0, &fix_level) < 0) 196 return CMD_RET_USAGE; 197 198 if (argc > 7) 199 if (strict_strtoul(argv[7], 0, &loops) < 0) 200 return CMD_RET_USAGE; 201 202 doing_memtester(arg, testenable, loops, err_exit, fix_bit, fix_level); 203 204 printf("Done.\n"); 205 return 0; 206 } 207 208 U_BOOT_CMD(memtester, 8, 1, do_memtester, 209 "do memtester", 210 "[start length [testenable err_exit fix_bit fix_level [loop]]]\n" 211 "start: start address, should be 4k align\n" 212 "length: test length, should be 4k align, if 0 testing full space\n" 213 "testenable[option]: enable pattern by set bit to 1, null or 0" 214 " enable all pattern\n" 215 " bit0: Random Value\n" 216 " bit1: Compare XOR\n" 217 " bit2: Compare SUB\n" 218 " bit3: Compare MUL\n" 219 " bit4: Compare DIV\n" 220 " bit5: Compare OR\n" 221 " bit6: Compare AND\n" 222 " bit7: Sequential Increment\n" 223 " bit8: Solid Bits\n" 224 " bit9: Block Sequential\n" 225 " bit10: Checkerboard\n" 226 " bit11: Bit Spread\n" 227 " bit12: Bit Flip\n" 228 " bit13: Walking Ones\n" 229 " bit14: Walking Zeroes\n" 230 " bit15: 8-bit Writes\n" 231 " bit16: 16-bit Writes\n" 232 " bit17: test stuck address\n" 233 " example: testenable=0x1000,enable Bit Flip only\n" 234 "err_exit: if 1 stop testing immediately when finding error\n" 235 "fix_bit: fixed bit to a exact level\n" 236 "fix_level: fix_bit's level, 0: low, 1: high\n" 237 "loop[option]: testing loop, if 0 or null endless loop\n" 238 "example:\n" 239 " memtester 0x200000 0x1000000: start address: 0x200000 length:" 240 "0x1000000, enable all pattern, endless loop\n" 241 " memtester 0x200000 0x1000000 0x1000 100: start address:0x200000" 242 " length:0x1000000, Bit Flip only, loop 100 times\n" 243 " memtester 0 0: testing full space\n"); 244