具体代码实现如下: static void move64(unsigned long long *src, unsigned long long *dest) { *dest = *src; } /* * This is 64 bit wide test patterns. Note that they reside in ROM * (which presumably works) and the tests write them to RAM which may * not work. * * The "otherpattern" is written to drive the data bus to values other * than the test pattern. This is for detecting floating bus lines. * */ const static unsigned long long pattern[] = { 0xaaaaaaaaaaaaaaaaULL, 0xccccccccccccccccULL, 0xf0f0f0f0f0f0f0f0ULL, 0xff00ff00ff00ff00ULL, 0xffff0000ffff0000ULL, 0xffffffff00000000ULL, 0x00000000ffffffffULL, 0x0000ffff0000ffffULL, 0x00ff00ff00ff00ffULL, 0x0f0f0f0f0f0f0f0fULL, 0x3333333333333333ULL, 0x5555555555555555ULL }; const unsigned long long otherpattern = 0x0123456789abcdefULL; /* 数据线检测 */ static int memory_post_dataline(unsigned long long * pmem) { unsigned long long temp64 = 0; int num_patterns = sizeof(pattern)/ sizeof(pattern[0]); int i; unsigned int hi, lo, pathi, patlo; int ret = 0; for ( i = 0; i < num_patterns; i++) { move64((unsigned long long *)&(pattern[i]), pmem++); /* * Put a different pattern on the data lines: otherwise they * may float long enough to read back what we wrote. */ /* 预防floating buses错误 */ move64((unsigned long long *)&otherpattern, pmem--); move64(pmem, &temp64); #ifdef INJECT_DATA_ERRORS temp64 ^= 0x00008000; #endif if (temp64 != pattern[i]) { pathi = (pattern[i]>>32) & 0xffffffff; patlo = pattern[i] & 0xffffffff; hi = (temp64>>32) & 0xffffffff; lo = temp64 & 0xffffffff; post_log ("Memory (date line) error at %08x, " "wrote %08x%08x, read %08x%08x ! ", pmem, pathi, patlo, hi, lo); ret = -1; } } return ret; } /* 地址线检测 */ static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size) { ulong *target; ulong *end; ulong readback; ulong xor; int ret = 0; end = (ulong *)((ulong)base + size);/* pointer arith! */ xor = 0; for(xor = sizeof(ulong); xor > 0; xor <<= 1) { /* 对测试的地址的某一根地址线的值翻转 */ target = (ulong *)((ulong)testaddr ^ xor); if((target >= base) && (target < end)) { /* 由于target是testaddr某一根地址线的值翻转得来 故testaddr != target,下面赋值操作后 应有*testaddr != *target */ *testaddr = ~*target; readback = *target; #ifdef INJECT_ADDRESS_ERRORS if(xor == 0x00008000) { readback = *testaddr; } #endif /* 出现此种情况只有testaddr == target,即某根地址线翻转无效 */ if(readback == *testaddr) { post_log ("Memory (address line) error at %08x<->%08x, " "XOR value %08x ! ", testaddr, target, xor); ret = -1; } } } return ret; } static int memory_post_test1 (unsigned long start, unsigned long size, unsigned long val) { unsigned long i; ulong *mem = (ulong *) start; ulong readback; int ret = 0; for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = val; if (i % 1024 == 0) WATCHDOG_RESET (); } for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) { readback = mem[i]; if (readback != val) { post_log ("Memory error at %08x, " "wrote %08x, read %08x ! ", mem + i, val, readback); ret = -1; break; } if (i % 1024 == 0) WATCHDOG_RESET (); } return ret; } static int memory_post_test2 (unsigned long start, unsigned long size) { unsigned long i; ulong *mem = (ulong *) start; ulong readback; int ret = 0; for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = 1 << (i % 32); if (i % 1024 == 0) WATCHDOG_RESET (); } for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) { readback = mem[i]; if (readback != (1 << (i % 32))) { post_log ("Memory error at %08x, " "wrote %08x, read %08x ! ", mem + i, 1 << (i % 32), readback); ret = -1; break; } if (i % 1024 == 0) WATCHDOG_RESET (); } return ret; } static int memory_post_test3 (unsigned long start, unsigned long size) { unsigned long i; ulong *mem = (ulong *) start; ulong readback; int ret = 0; for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = i; if (i % 1024 == 0) WATCHDOG_RESET (); } for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) { readback = mem[i]; if (readback != i) { post_log ("Memory error at %08x, " "wrote %08x, read %08x ! ", mem + i, i, readback); ret = -1; break; } if (i % 1024 == 0) WATCHDOG_RESET (); } return ret; } static int memory_post_test4 (unsigned long start, unsigned long size) { unsigned long i; ulong *mem = (ulong *) start; ulong readback; int ret = 0; for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = ~i; if (i % 1024 == 0) WATCHDOG_RESET (); } for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) { readback = mem[i]; if (readback != ~i) { post_log ("Memory error at %08x, " "wrote %08x, read %08x ! ", mem + i, ~i, readback); ret = -1; break; } if (i % 1024 == 0) WATCHDOG_RESET (); } return ret; } static int memory_post_tests (unsigned long start, unsigned long size) { int ret = 0; if (ret == 0) ret = memory_post_dataline ((unsigned long long *)start); WATCHDOG_RESET (); if (ret == 0) ret = memory_post_addrline ((ulong *)start, (ulong *)start, size); WATCHDOG_RESET (); if (ret == 0) ret = memory_post_addrline ((ulong *)(start + size - 8), (ulong *)start, size); WATCHDOG_RESET (); if (ret == 0) ret = memory_post_test1 (start, size, 0x00000000); WATCHDOG_RESET (); if (ret == 0) ret = memory_post_test1 (start, size, 0xffffffff); WATCHDOG_RESET (); if (ret == 0) ret = memory_post_test1 (start, size, 0x55555555); WATCHDOG_RESET (); if (ret == 0) ret = memory_post_test1 (start, size, 0xaaaaaaaa); WATCHDOG_RESET (); if (ret == 0) ret = memory_post_test2 (start, size); WATCHDOG_RESET (); if (ret == 0) ret = memory_post_test3 (start, size); WATCHDOG_RESET (); if (ret == 0) ret = memory_post_test4 (start, size); WATCHDOG_RESET (); return ret; } |
|