1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155#include <post.h>
156#include <watchdog.h>
157
158
159
160
161
162
163
164#undef INJECT_DATA_ERRORS
165#undef INJECT_ADDRESS_ERRORS
166
167#ifdef INJECT_DATA_ERRORS
168#warning "Injecting data line errors for testing purposes"
169#endif
170
171#ifdef INJECT_ADDRESS_ERRORS
172#warning "Injecting address line errors for testing purposes"
173#endif
174
175
176
177
178
179
180
181
182
183
184
185
186
187static void move64(const unsigned long long *src, unsigned long long *dest)
188{
189#if defined(CONFIG_MPC8260) || defined(CONFIG_MPC824X)
190 asm ("lfd 0, 0(3)\n\t"
191 "stfd 0, 0(4)"
192 : : : "fr0" );
193 return;
194#else
195 *dest = *src;
196#endif
197}
198
199
200
201
202
203
204
205
206
207
208const static unsigned long long pattern[] = {
209 0xaaaaaaaaaaaaaaaaULL,
210 0xccccccccccccccccULL,
211 0xf0f0f0f0f0f0f0f0ULL,
212 0xff00ff00ff00ff00ULL,
213 0xffff0000ffff0000ULL,
214 0xffffffff00000000ULL,
215 0x00000000ffffffffULL,
216 0x0000ffff0000ffffULL,
217 0x00ff00ff00ff00ffULL,
218 0x0f0f0f0f0f0f0f0fULL,
219 0x3333333333333333ULL,
220 0x5555555555555555ULL,
221};
222const unsigned long long otherpattern = 0x0123456789abcdefULL;
223
224
225static int memory_post_dataline(unsigned long long * pmem)
226{
227 unsigned long long temp64;
228 int num_patterns = sizeof(pattern)/ sizeof(pattern[0]);
229 int i;
230 unsigned int hi, lo, pathi, patlo;
231 int ret = 0;
232
233 for ( i = 0; i < num_patterns; i++) {
234 move64(&(pattern[i]), pmem++);
235
236
237
238
239 move64(&otherpattern, pmem--);
240 move64(pmem, &temp64);
241
242#ifdef INJECT_DATA_ERRORS
243 temp64 ^= 0x00008000;
244#endif
245
246 if (temp64 != pattern[i]){
247 pathi = (pattern[i]>>32) & 0xffffffff;
248 patlo = pattern[i] & 0xffffffff;
249
250 hi = (temp64>>32) & 0xffffffff;
251 lo = temp64 & 0xffffffff;
252
253 printf ("Memory (date line) error at %08lx, "
254 "wrote %08x%08x, read %08x%08x !\n",
255 (ulong)pmem, pathi, patlo, hi, lo);
256 ret = -1;
257 }
258 }
259 return ret;
260}
261
262static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size)
263{
264 ulong *target;
265 ulong *end;
266 ulong readback;
267 ulong xor;
268 int ret = 0;
269
270 end = (ulong *)((ulong)base + size);
271 xor = 0;
272 for(xor = sizeof(ulong); xor > 0; xor <<= 1) {
273 target = (ulong *)((ulong)testaddr ^ xor);
274 if((target >= base) && (target < end)) {
275 *testaddr = ~*target;
276 readback = *target;
277
278#ifdef INJECT_ADDRESS_ERRORS
279 if(xor == 0x00008000) {
280 readback = *testaddr;
281 }
282#endif
283 if(readback == *testaddr) {
284 printf ("Memory (address line) error at %08lx<->%08lx, "
285 "XOR value %08lx !\n",
286 (ulong)testaddr, (ulong)target,
287 xor);
288 ret = -1;
289 }
290 }
291 }
292 return ret;
293}
294
295static int memory_post_test1 (unsigned long start,
296 unsigned long size,
297 unsigned long val)
298{
299 unsigned long i;
300 ulong *mem = (ulong *) start;
301 ulong readback;
302 int ret = 0;
303
304 for (i = 0; i < size / sizeof (ulong); i++) {
305 mem[i] = val;
306 if (i % 1024 == 0)
307 WATCHDOG_RESET ();
308 }
309
310 for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
311 readback = mem[i];
312 if (readback != val) {
313 printf ("Memory error at %08lx, "
314 "wrote %08lx, read %08lx !\n",
315 (ulong)(mem + i), val, readback);
316
317 ret = -1;
318 break;
319 }
320 if (i % 1024 == 0)
321 WATCHDOG_RESET ();
322 }
323
324 return ret;
325}
326
327static int memory_post_test2 (unsigned long start, unsigned long size)
328{
329 unsigned long i;
330 ulong *mem = (ulong *) start;
331 ulong readback;
332 int ret = 0;
333
334 for (i = 0; i < size / sizeof (ulong); i++) {
335 mem[i] = 1 << (i % 32);
336 if (i % 1024 == 0)
337 WATCHDOG_RESET ();
338 }
339
340 for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
341 readback = mem[i];
342 if (readback != (1 << (i % 32))) {
343 printf ("Memory error at %08lx, "
344 "wrote %08x, read %08lx !\n",
345 (ulong)(mem + i), 1 << (i % 32), readback);
346
347 ret = -1;
348 break;
349 }
350 if (i % 1024 == 0)
351 WATCHDOG_RESET ();
352 }
353
354 return ret;
355}
356
357static int memory_post_test3 (unsigned long start, unsigned long size)
358{
359 unsigned long i;
360 ulong *mem = (ulong *) start;
361 ulong readback;
362 int ret = 0;
363
364 for (i = 0; i < size / sizeof (ulong); i++) {
365 mem[i] = i;
366 if (i % 1024 == 0)
367 WATCHDOG_RESET ();
368 }
369
370 for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
371 readback = mem[i];
372 if (readback != i) {
373 printf ("Memory error at %08lx, "
374 "wrote %08lx, read %08lx !\n",
375 (ulong)(mem + i), i, readback);
376
377 ret = -1;
378 break;
379 }
380 if (i % 1024 == 0)
381 WATCHDOG_RESET ();
382 }
383
384 return ret;
385}
386
387static int memory_post_test4 (unsigned long start, unsigned long size)
388{
389 unsigned long i;
390 ulong *mem = (ulong *) start;
391 ulong readback;
392 int ret = 0;
393
394 for (i = 0; i < size / sizeof (ulong); i++) {
395 mem[i] = ~i;
396 if (i % 1024 == 0)
397 WATCHDOG_RESET ();
398 }
399
400 for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
401 readback = mem[i];
402 if (readback != ~i) {
403 printf ("Memory error at %08lx, "
404 "wrote %08lx, read %08lx !\n",
405 (ulong)(mem + i), ~i, readback);
406
407 ret = -1;
408 break;
409 }
410 if (i % 1024 == 0)
411 WATCHDOG_RESET ();
412 }
413
414 return ret;
415}
416
417int memory_post_tests (unsigned long start, unsigned long size)
418{
419 int ret = 0;
420
421 if (ret == 0)
422 ret = memory_post_dataline ((unsigned long long *)start);
423 WATCHDOG_RESET ();
424 if (ret == 0)
425 ret = memory_post_addrline ((ulong *)start, (ulong *)start, size);
426 WATCHDOG_RESET ();
427 if (ret == 0)
428 ret = memory_post_addrline ((ulong *)(start + size - 8),
429 (ulong *)start, size);
430 WATCHDOG_RESET ();
431 if (ret == 0)
432 ret = memory_post_test1 (start, size, 0x00000000);
433 WATCHDOG_RESET ();
434 if (ret == 0)
435 ret = memory_post_test1 (start, size, 0xffffffff);
436 WATCHDOG_RESET ();
437 if (ret == 0)
438 ret = memory_post_test1 (start, size, 0x55555555);
439 WATCHDOG_RESET ();
440 if (ret == 0)
441 ret = memory_post_test1 (start, size, 0xaaaaaaaa);
442 WATCHDOG_RESET ();
443 if (ret == 0)
444 ret = memory_post_test2 (start, size);
445 WATCHDOG_RESET ();
446 if (ret == 0)
447 ret = memory_post_test3 (start, size);
448 WATCHDOG_RESET ();
449 if (ret == 0)
450 ret = memory_post_test4 (start, size);
451 WATCHDOG_RESET ();
452
453 return ret;
454}
455
456#if 0
457DECLARE_GLOBAL_DATA_PTR;
458
459int memory_post_test (int flags)
460{
461 int ret = 0;
462 bd_t *bd = gd->bd;
463 phys_size_t memsize = (bd->bi_memsize >= 256 << 20 ?
464 256 << 20 : bd->bi_memsize) - (1 << 20);
465
466
467 if (flags & POST_SLOWTEST) {
468 ret = memory_post_tests (CONFIG_SYS_SDRAM_BASE, memsize);
469 } else {
470
471 unsigned long i;
472
473 for (i = 0; i < (memsize >> 20) && ret == 0; i++) {
474 if (ret == 0)
475 ret = memory_post_tests (i << 20, 0x800);
476 if (ret == 0)
477 ret = memory_post_tests ((i << 20) + 0xff800, 0x800);
478 }
479 }
480
481 return ret;
482}
483#endif
484
485
486
487