xref: /OK3568_Linux_fs/u-boot/cmd/ddr_tool/memtester/tests.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Very simple but very effective user-space memory tester.
4  * Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
5  * Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca>
6  * Version 3 not publicly released.
7  * Version 4 rewrite:
8  * Copyright (C) 2004-2012 Charles Cazabon <charlesc-memtester@pyropus.ca>
9  * Licensed under the terms of the GNU General Public License version 2 (only).
10  * See the file COPYING for details.
11  *
12  * This file contains the functions for the actual tests, called from the
13  * main routine in memtester.c.  See other comments in that file.
14  *
15  */
16 
17 #include "memtester.h"
18 #include "sizes.h"
19 #include "types.h"
20 #include "../io_map.h"
21 
22 union {
23 	unsigned char bytes[UL_LEN / 8];
24 	u32 val;
25 } mword8;
26 
27 union {
28 	unsigned short u16s[UL_LEN / 16];
29 	u32 val;
30 } mword16;
31 
32 char progress[] = "-\\|/";
33 #define PROGRESSLEN 4
34 #define PROGRESSOFTEN 2500
35 #define ONE 0x00000001L
36 
37 #define fflush(n)
38 
39 /* Function definitions. */
compare_regions(u32v * bufa,u32v * bufb,size_t count)40 int compare_regions(u32v *bufa, u32v *bufb, size_t count)
41 {
42 	int r = 0;
43 	size_t i;
44 	u32v *p1 = bufa;
45 	u32v *p2 = bufb;
46 	off_t physaddr;
47 
48 	for (i = 0; i < count; i++, p1++, p2++) {
49 		if (*p1 != *p2) {
50 			if (use_phys) {
51 				physaddr = physaddrbase + (i * sizeof(u32v));
52 				fprintf(stderr,
53 					"FAILURE: 0x%08lx != 0x%08lx at physical address "
54 					"0x%08lx.\n",
55 					(ul)*p1, (ul)*p2, physaddr);
56 			} else {
57 				fprintf(stderr,
58 					"FAILURE: 0x%08lx != 0x%08lx at offset 0x%08lx.\n",
59 					(ul)*p1, (ul)*p2,
60 					(ul)(i * sizeof(u32v)));
61 			}
62 			/* printf("Skipping to next test..."); */
63 			r = -1;
64 		}
65 	}
66 	return r;
67 }
68 
test_stuck_address(u32v * bufa,size_t count)69 int test_stuck_address(u32v *bufa, size_t count)
70 {
71 	u32v *p1 = bufa;
72 	unsigned int j;
73 	size_t i;
74 	off_t physaddr;
75 
76 	printf("           ");
77 	fflush(stdout);
78 	for (j = 0; j < 16; j++) {
79 		printf("\b\b\b\b\b\b\b\b\b\b\b");
80 		p1 = (u32v *)bufa;
81 		printf("setting %3u", j);
82 		fflush(stdout);
83 		for (i = 0; i < count; i++) {
84 			*p1 = ((j + i) % 2) == 0 ? (u32)(ul)p1 : ~((u32)(ul)p1);
85 			*p1++;
86 		}
87 		printf("\b\b\b\b\b\b\b\b\b\b\b");
88 		printf("testing %3u", j);
89 		fflush(stdout);
90 		p1 = (u32v *)bufa;
91 		for (i = 0; i < count; i++, p1++) {
92 			if (*p1 != (((j + i) % 2) == 0 ?
93 				    (u32)(ul)p1 : ~((u32)(ul)p1))) {
94 				if (use_phys) {
95 					physaddr =
96 					    physaddrbase + (i * sizeof(u32v));
97 					fprintf(stderr,
98 						"FAILURE: possible bad address line at physical "
99 						"address 0x%08lx.\n", physaddr);
100 				} else {
101 					fprintf(stderr,
102 						"FAILURE: possible bad address line at offset "
103 						"0x%08lx.\n",
104 						(ul)(i * sizeof(u32v)));
105 				}
106 				printf("Skipping to next test...\n");
107 				fflush(stdout);
108 				return -1;
109 			}
110 		}
111 	}
112 	printf("\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b");
113 	fflush(stdout);
114 	return 0;
115 }
116 
test_random_value(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)117 int test_random_value(u32v *bufa, u32v *bufb, size_t count,
118 		      ul fix_bit, ul fix_level)
119 {
120 	u32v *p1 = bufa;
121 	u32v *p2 = bufb;
122 	ul j = 0;
123 	size_t i;
124 
125 	putc(' ');
126 	fflush(stdout);
127 	for (i = 0; i < count; i++) {
128 		*p1++ = *p2++ = rand_ul();
129 		if (!(i % PROGRESSOFTEN)) {
130 			putc('\b');
131 			putc(progress[++j % PROGRESSLEN]);
132 			fflush(stdout);
133 		}
134 	}
135 	printf("\b \b");
136 	fflush(stdout);
137 	return compare_regions(bufa, bufb, count);
138 }
139 
test_xor_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)140 int test_xor_comparison(u32v *bufa, u32v *bufb, size_t count,
141 			ul fix_bit, ul fix_level)
142 
143 {
144 	u32v *p1 = bufa;
145 	u32v *p2 = bufb;
146 	size_t i;
147 	u32 q = rand_ul();
148 
149 	for (i = 0; i < count; i++) {
150 		*p1++ ^= q;
151 		*p2++ ^= q;
152 	}
153 	return compare_regions(bufa, bufb, count);
154 }
155 
test_sub_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)156 int test_sub_comparison(u32v *bufa, u32v *bufb, size_t count,
157 			ul fix_bit, ul fix_level)
158 {
159 	u32v *p1 = bufa;
160 	u32v *p2 = bufb;
161 	size_t i;
162 	u32 q = rand_ul();
163 
164 	for (i = 0; i < count; i++) {
165 		*p1++ -= q;
166 		*p2++ -= q;
167 	}
168 	return compare_regions(bufa, bufb, count);
169 }
170 
test_mul_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)171 int test_mul_comparison(u32v *bufa, u32v *bufb, size_t count,
172 			ul fix_bit, ul fix_level)
173 {
174 	u32v *p1 = bufa;
175 	u32v *p2 = bufb;
176 	size_t i;
177 	u32 q = rand_ul();
178 
179 	for (i = 0; i < count; i++) {
180 		*p1++ *= q;
181 		*p2++ *= q;
182 	}
183 	return compare_regions(bufa, bufb, count);
184 }
185 
test_div_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)186 int test_div_comparison(u32v *bufa, u32v *bufb, size_t count,
187 			ul fix_bit, ul fix_level)
188 {
189 	u32v *p1 = bufa;
190 	u32v *p2 = bufb;
191 	size_t i;
192 	u32 q = rand_ul();
193 
194 	for (i = 0; i < count; i++) {
195 		if (!q)
196 			q++;
197 		*p1++ /= q;
198 		*p2++ /= q;
199 	}
200 	return compare_regions(bufa, bufb, count);
201 }
202 
test_or_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)203 int test_or_comparison(u32v *bufa, u32v *bufb, size_t count,
204 		       ul fix_bit, ul fix_level)
205 {
206 	u32v *p1 = bufa;
207 	u32v *p2 = bufb;
208 	size_t i;
209 	u32 q = rand_ul();
210 
211 	for (i = 0; i < count; i++) {
212 		*p1++ |= q;
213 		*p2++ |= q;
214 	}
215 	return compare_regions(bufa, bufb, count);
216 }
217 
test_and_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)218 int test_and_comparison(u32v *bufa, u32v *bufb, size_t count,
219 			ul fix_bit, ul fix_level)
220 {
221 	u32v *p1 = bufa;
222 	u32v *p2 = bufb;
223 	size_t i;
224 	u32 q = rand_ul();
225 
226 	for (i = 0; i < count; i++) {
227 		*p1++ &= q;
228 		*p2++ &= q;
229 	}
230 	return compare_regions(bufa, bufb, count);
231 }
232 
test_seqinc_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)233 int test_seqinc_comparison(u32v *bufa, u32v *bufb, size_t count,
234 			   ul fix_bit, ul fix_level)
235 {
236 	u32v *p1 = bufa;
237 	u32v *p2 = bufb;
238 	size_t i;
239 	u32 q = rand_ul();
240 
241 	for (i = 0; i < count; i++)
242 		*p1++ = *p2++ = (i + q);
243 	return compare_regions(bufa, bufb, count);
244 }
245 
test_solidbits_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)246 int test_solidbits_comparison(u32v *bufa, u32v *bufb, size_t count,
247 			      ul fix_bit, ul fix_level)
248 {
249 	u32v *p1 = bufa;
250 	u32v *p2 = bufb;
251 	unsigned int j;
252 	u32 q;
253 	u32 data[4];
254 	size_t i;
255 
256 	printf("           ");
257 	fflush(stdout);
258 	for (j = 0; j < 64; j++) {
259 		printf("\b\b\b\b\b\b\b\b\b\b\b");
260 		q = (j % 2) == 0 ? UL_ONEBITS : 0;
261 		if (fix_level)
262 			q |= fix_bit;
263 		else
264 			q &= ~fix_bit;
265 		data[0] = data[2] = q;
266 		data[1] = data[3] = ~q;
267 		data_cpu_2_io(data, sizeof(data));
268 		printf("setting %3u", j);
269 		fflush(stdout);
270 		p1 = (u32v *)bufa;
271 		p2 = (u32v *)bufb;
272 		for (i = 0; i < count; i++)
273 			*p1++ = *p2++ = data[i & 3];
274 		printf("\b\b\b\b\b\b\b\b\b\b\b");
275 		printf("testing %3u", j);
276 		fflush(stdout);
277 		if (compare_regions(bufa, bufb, count))
278 			return -1;
279 	}
280 	printf("\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b");
281 	fflush(stdout);
282 	return 0;
283 }
284 
test_checkerboard_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)285 int test_checkerboard_comparison(u32v *bufa, u32v *bufb, size_t count,
286 				 ul fix_bit, ul fix_level)
287 {
288 	u32v *p1 = bufa;
289 	u32v *p2 = bufb;
290 	unsigned int j;
291 	u32 q;
292 	u32 data[4];
293 	size_t i;
294 
295 	printf("           ");
296 	fflush(stdout);
297 	for (j = 0; j < 64; j++) {
298 		printf("\b\b\b\b\b\b\b\b\b\b\b");
299 		q = (j % 2) == 0 ? CHECKERBOARD1 : CHECKERBOARD2;
300 		if (fix_level)
301 			q |= fix_bit;
302 		else
303 			q &= ~fix_bit;
304 
305 		data[0] = data[2] = q;
306 		data[1] = data[3] = ~q;
307 		data_cpu_2_io(data, sizeof(data));
308 		printf("setting %3u", j);
309 		fflush(stdout);
310 		p1 = (u32v *)bufa;
311 		p2 = (u32v *)bufb;
312 		for (i = 0; i < count; i++)
313 			*p1++ = *p2++ = data[i & 3];
314 		printf("\b\b\b\b\b\b\b\b\b\b\b");
315 		printf("testing %3u", j);
316 		fflush(stdout);
317 		if (compare_regions(bufa, bufb, count))
318 			return -1;
319 	}
320 	printf("\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b");
321 	fflush(stdout);
322 	return 0;
323 }
324 
test_blockseq_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)325 int test_blockseq_comparison(u32v *bufa, u32v *bufb, size_t count,
326 			     ul fix_bit, ul fix_level)
327 {
328 	u32v *p1 = bufa;
329 	u32v *p2 = bufb;
330 	unsigned int j;
331 	u32 data[4];
332 	u32 q;
333 	size_t i;
334 
335 	printf("           ");
336 	fflush(stdout);
337 	for (j = 0; j < 256; j++) {
338 		printf("\b\b\b\b\b\b\b\b\b\b\b");
339 		p1 = (u32v *)bufa;
340 		p2 = (u32v *)bufb;
341 		printf("setting %3u", j);
342 		fflush(stdout);
343 		q = (u32)UL_BYTE(j);
344 		if (fix_level)
345 			q |= fix_bit;
346 		else
347 			q &= ~fix_bit;
348 
349 		data[0] = q;
350 		data[1] = q;
351 		data[2] = q;
352 		data[3] = q;
353 
354 		data_cpu_2_io(data, sizeof(data));
355 
356 		for (i = 0; i < count; i++)
357 			*p1++ = *p2++ = data[i & 3];
358 		printf("\b\b\b\b\b\b\b\b\b\b\b");
359 		printf("testing %3u", j);
360 		fflush(stdout);
361 		if (compare_regions(bufa, bufb, count))
362 			return -1;
363 	}
364 	printf("\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b");
365 	fflush(stdout);
366 	return 0;
367 }
368 
test_walkbits0_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)369 int test_walkbits0_comparison(u32v *bufa, u32v *bufb, size_t count,
370 			      ul fix_bit, ul fix_level)
371 {
372 	u32v *p1 = bufa;
373 	u32v *p2 = bufb;
374 	unsigned int j;
375 	u32 data[4];
376 	u32 q;
377 	size_t i;
378 
379 	printf("           ");
380 	fflush(stdout);
381 	for (j = 0; j < UL_LEN * 2; j++) {
382 		printf("\b\b\b\b\b\b\b\b\b\b\b");
383 		p1 = (u32v *)bufa;
384 		p2 = (u32v *)bufb;
385 		printf("setting %3u", j);
386 		fflush(stdout);
387 		if (j < UL_LEN)
388 			q = ONE << j;
389 		else
390 			q = ONE << (UL_LEN * 2 - j - 1);
391 
392 		if (fix_level)
393 			q |= fix_bit;
394 		else
395 			q &= ~fix_bit;
396 
397 		data[0] = q;
398 		data[1] = q;
399 		data[2] = q;
400 		data[3] = q;
401 		data_cpu_2_io(data, sizeof(data));
402 
403 		for (i = 0; i < count; i++) {
404 				*p1++ = *p2++ = data[i & 3];
405 		}
406 		printf("\b\b\b\b\b\b\b\b\b\b\b");
407 		printf("testing %3u", j);
408 		fflush(stdout);
409 		if (compare_regions(bufa, bufb, count))
410 			return -1;
411 	}
412 	printf("\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b");
413 	fflush(stdout);
414 	return 0;
415 }
416 
test_walkbits1_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)417 int test_walkbits1_comparison(u32v *bufa, u32v *bufb, size_t count,
418 			      ul fix_bit, ul fix_level)
419 {
420 	u32v *p1 = bufa;
421 	u32v *p2 = bufb;
422 	unsigned int j;
423 	u32 data[4];
424 	u32 q;
425 	size_t i;
426 
427 	printf("           ");
428 	fflush(stdout);
429 	for (j = 0; j < UL_LEN * 2; j++) {
430 		printf("\b\b\b\b\b\b\b\b\b\b\b");
431 		p1 = (u32v *)bufa;
432 		p2 = (u32v *)bufb;
433 		printf("setting %3u", j);
434 		fflush(stdout);
435 		if (j < UL_LEN)
436 			q = UL_ONEBITS ^ (ONE << j);
437 		else
438 			q = UL_ONEBITS ^ (ONE << (UL_LEN * 2 - j - 1));
439 		if (fix_level)
440 			q |= fix_bit;
441 		else
442 			q &= ~fix_bit;
443 
444 		data[0] = q;
445 		data[1] = q;
446 		data[2] = q;
447 		data[3] = q;
448 		data_cpu_2_io(data, sizeof(data));
449 
450 		for (i = 0; i < count; i++) {
451 				*p1++ = *p2++ = data[i & 3];
452 		}
453 		printf("\b\b\b\b\b\b\b\b\b\b\b");
454 		printf("testing %3u", j);
455 		fflush(stdout);
456 		if (compare_regions(bufa, bufb, count))
457 			return -1;
458 	}
459 	printf("\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b");
460 	fflush(stdout);
461 	return 0;
462 }
463 
test_bitspread_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)464 int test_bitspread_comparison(u32v *bufa, u32v *bufb, size_t count,
465 			      ul fix_bit, ul fix_level)
466 {
467 	u32v *p1 = bufa;
468 	u32v *p2 = bufb;
469 	unsigned int j;
470 	u32 data[4];
471 	size_t i;
472 
473 	printf("           ");
474 	fflush(stdout);
475 	for (j = 0; j < UL_LEN * 2; j++) {
476 		printf("\b\b\b\b\b\b\b\b\b\b\b");
477 		p1 = (u32v *)bufa;
478 		p2 = (u32v *)bufb;
479 		printf("setting %3u", j);
480 		fflush(stdout);
481 		if (j < UL_LEN) {
482 			data[0] = (ONE << j) | (ONE << (j + 2));
483 			data[1] = UL_ONEBITS ^ ((ONE << j) | (ONE << (j + 2)));
484 		} else {
485 			data[0] = (ONE << (UL_LEN * 2 - 1 - j)) |
486 				  (ONE << (UL_LEN * 2 + 1 - j));
487 			data[1] = UL_ONEBITS ^ (ONE << (UL_LEN * 2 - 1 - j)
488 						| (ONE << (UL_LEN * 2 + 1 - j)));
489 		}
490 		if (fix_level) {
491 			data[0] |= fix_bit;
492 			data[1] |= fix_bit;
493 		} else {
494 			data[0] &= ~fix_bit;
495 			data[1] &= ~fix_bit;
496 		}
497 		data[2] = data[0];
498 		data[3] = data[1];
499 		data_cpu_2_io(data, sizeof(data));
500 
501 		for (i = 0; i < count; i++) {
502 			*p1++ = *p2++ = data[i & 3];
503 		}
504 		printf("\b\b\b\b\b\b\b\b\b\b\b");
505 		printf("testing %3u", j);
506 		fflush(stdout);
507 		if (compare_regions(bufa, bufb, count))
508 			return -1;
509 	}
510 	printf("\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b");
511 	fflush(stdout);
512 	return 0;
513 }
514 
test_bitflip_comparison(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)515 int test_bitflip_comparison(u32v *bufa, u32v *bufb, size_t count,
516 			    ul fix_bit, ul fix_level)
517 {
518 	u32v *p1 = bufa;
519 	u32v *p2 = bufb;
520 	unsigned int j, k;
521 	u32 q;
522 	u32 data[4];
523 	size_t i;
524 
525 	printf("           ");
526 	fflush(stdout);
527 	for (k = 0; k < UL_LEN; k++) {
528 		q = ONE << k;
529 		for (j = 0; j < 8; j++) {
530 			printf("\b\b\b\b\b\b\b\b\b\b\b");
531 			q = ~q;
532 			printf("setting %3u", k * 8 + j);
533 			fflush(stdout);
534 			if (fix_level)
535 				q |= fix_bit;
536 			else
537 				q &= ~fix_bit;
538 
539 			data[0] = data[2] = q;
540 			data[1] = data[3] = ~q;
541 			data_cpu_2_io(data, sizeof(data));
542 			p1 = (u32v *)bufa;
543 			p2 = (u32v *)bufb;
544 			for (i = 0; i < count; i++)
545 				*p1++ = *p2++ = data[i & 3];
546 			printf("\b\b\b\b\b\b\b\b\b\b\b");
547 			printf("testing %3u", k * 8 + j);
548 			fflush(stdout);
549 			if (compare_regions(bufa, bufb, count))
550 				return -1;
551 		}
552 	}
553 	printf("\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b");
554 	fflush(stdout);
555 	return 0;
556 }
557 
558 #ifdef TEST_NARROW_WRITES
test_8bit_wide_random(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)559 int test_8bit_wide_random(u32v *bufa, u32v *bufb, size_t count,
560 			  ul fix_bit, ul fix_level)
561 {
562 	u8v *p1, *t;
563 	u32v *p2;
564 	int attempt;
565 	unsigned int b, j = 0;
566 	size_t i;
567 
568 	putc(' ');
569 	fflush(stdout);
570 	for (attempt = 0; attempt < 2; attempt++) {
571 		if (attempt & 1) {
572 			p1 = (u8v *)bufa;
573 			p2 = bufb;
574 		} else {
575 			p1 = (u8v *)bufb;
576 			p2 = bufa;
577 		}
578 		for (i = 0; i < count; i++) {
579 			t = mword8.bytes;
580 			*p2++ = mword8.val = rand_ul();
581 			for (b = 0; b < UL_LEN / 8; b++)
582 				*p1++ = *t++;
583 			if (!(i % PROGRESSOFTEN)) {
584 				putc('\b');
585 				putc(progress[++j % PROGRESSLEN]);
586 				fflush(stdout);
587 			}
588 		}
589 		if (compare_regions(bufa, bufb, count))
590 			return -1;
591 	}
592 	printf("\b \b");
593 	fflush(stdout);
594 	return 0;
595 }
596 
test_16bit_wide_random(u32v * bufa,u32v * bufb,size_t count,ul fix_bit,ul fix_level)597 int test_16bit_wide_random(u32v *bufa, u32v *bufb, size_t count,
598 			   ul fix_bit, ul fix_level)
599 {
600 	u16v *p1, *t;
601 	u32v *p2;
602 	int attempt;
603 	unsigned int b, j = 0;
604 	size_t i;
605 
606 	putc(' ');
607 	fflush(stdout);
608 	for (attempt = 0; attempt < 2; attempt++) {
609 		if (attempt & 1) {
610 			p1 = (u16v *)bufa;
611 			p2 = bufb;
612 		} else {
613 			p1 = (u16v *)bufb;
614 			p2 = bufa;
615 		}
616 		for (i = 0; i < count; i++) {
617 			t = mword16.u16s;
618 			*p2++ = mword16.val = rand_ul();
619 			for (b = 0; b < UL_LEN / 16; b++)
620 				*p1++ = *t++;
621 			if (!(i % PROGRESSOFTEN)) {
622 				putc('\b');
623 				putc(progress[++j % PROGRESSLEN]);
624 				fflush(stdout);
625 			}
626 		}
627 		if (compare_regions(bufa, bufb, count))
628 			return -1;
629 	}
630 	printf("\b \b");
631 	fflush(stdout);
632 	return 0;
633 }
634 #endif
635