Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/294
-gerrit
commit c62ee4b1f3f61d9913caa6cc54edc30fa85c99b8 Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Fri Nov 18 12:38:37 2011 +0200
Replace ramtest pattern to assist in DIMM configuration
This is developer's testtool. Output from a "rotate ones" -style pattern helps figure out how DIMM addresses are encoded or routed on a certain mainboard.
Scattered test should cover every data and address lines on the memory bus, but is probably limited to the first bank of first DIMM.
Change-Id: I533a7a873bcc434f99e7faed9dc9337d9ab64196 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- src/lib/ramtest.c | 187 ++++++++++++++++++++++++++--------------------------- 1 files changed, 91 insertions(+), 96 deletions(-)
diff --git a/src/lib/ramtest.c b/src/lib/ramtest.c index b35c36d..e09d0d1 100644 --- a/src/lib/ramtest.c +++ b/src/lib/ramtest.c @@ -47,117 +47,118 @@ static void phys_memory_barrier(void) #endif }
-static void ram_fill(unsigned long start, unsigned long stop) +/** + * Rotate ones test pattern that access every bit on a 128bit wide + * memory bus. To test most address lines, addresses are scattered + * using 256B, 4kB and 64kB increments. + * + * @idx Index to test pattern (0=<idx<0x400) + * @addr Memory to access on @idx + * @value Value to write or read at @addr + */ +static inline void test_pattern(unsigned short int idx, + unsigned long *addr, unsigned long *value) { - unsigned long addr; - /* - * Fill. - */ -#if !defined(__ROMCC__) - printk(BIOS_DEBUG, "DRAM fill: 0x%08lx-0x%08lx\n", start, stop); -#else - print_debug("DRAM fill: "); - print_debug_hex32(start); - print_debug("-"); - print_debug_hex32(stop); - print_debug("\n"); -#endif - for(addr = start; addr < stop ; addr += 4) { - /* Display address being filled */ - if (!(addr & 0xfffff)) { -#if !defined(__ROMCC__) - printk(BIOS_DEBUG, "%08lx \r", addr); -#else - print_debug_hex32(addr); - print_debug(" \r"); -#endif - } - write_phys(addr, (u32)addr); - }; - /* Display final address */ -#if !defined(__ROMCC__) - printk(BIOS_DEBUG, "%08lx\nDRAM filled\n", addr); -#else - print_debug_hex32(addr); - print_debug("\nDRAM filled\n"); -#endif + uint8_t j, k; + + k = (idx >> 8) + 1; + j = (idx >> 4) & 0x0f; + *addr = idx & 0x0f; + *addr |= j << (4*k); + *value = 0x01010101 << (j & 7); + if (j & 8) + *value = ~(*value); }
-static void ram_verify(unsigned long start, unsigned long stop) +/** + * Simple write-read-verify memory test. See console debug output for + * any dislocated bytes. + * + * @start System memory offset, aligned to 128bytes + */ +static void ram_bitset(unsigned long start) { - unsigned long addr; - int i = 0; - /* - * Verify. - */ + unsigned long addr, value, value2; + unsigned short int idx; + unsigned char failed, failures; + uint8_t verbose = 0; + #if !defined(__ROMCC__) - printk(BIOS_DEBUG, "DRAM verify: 0x%08lx-0x%08lx\n", start, stop); + printk(BIOS_DEBUG, "DRAM bitset write: 0x%08lx\n", start); #else - print_debug("DRAM verify: "); + print_debug("DRAM bitset write: 0x"); print_debug_hex32(start); - print_debug_char('-'); - print_debug_hex32(stop); print_debug("\n"); #endif - for(addr = start; addr < stop ; addr += 4) { - unsigned long value; - /* Display address being tested */ - if (!(addr & 0xfffff)) { + for (idx=0; idx<0x400; idx+=4) { + test_pattern(idx, &addr, &value); + write_phys(start + addr, value); + } + + /* Make sure we don't read before we wrote */ + phys_memory_barrier(); + #if !defined(__ROMCC__) - printk(BIOS_DEBUG, "%08lx \r", addr); + printk(BIOS_DEBUG, "DRAM bitset verify: 0x%08lx\n", start); #else - print_debug_hex32(addr); - print_debug(" \r"); + print_debug("DRAM bitset verify: 0x"); + print_debug_hex32(start); + print_debug("\n"); #endif - } - value = read_phys(addr); - if (value != addr) { - /* Display address with error */ + failures = 0; + for (idx=0; idx<0x400; idx+=4) { + test_pattern(idx, &addr, &value); + value2 = read_phys(start + addr); + + failed = (value2 != value); + failures |= failed; + if (failed && !verbose) { #if !defined(__ROMCC__) - printk(BIOS_ERR, "Fail: @0x%08lx Read value=0x%08lx\n", addr, value); + printk(BIOS_ERR, "0x%08lx wr: 0x%08lx rd: 0x%08lx FAIL\n", + start + addr, value, value2); #else - print_err("Fail: @0x"); - print_err_hex32(addr); - print_err(" Read value=0x"); + print_err_hex32(start + addr); + print_err(" wr: 0x"); print_err_hex32(value); - print_err("\n"); -#endif - i++; - if(i>256) { -#if !defined(__ROMCC__) - printk(BIOS_DEBUG, "Aborting.\n"); -#else - print_debug("Aborting.\n"); + print_err(" rd: 0x"); + print_err_hex32(value2); + print_err(" FAIL\n"); #endif - break; - } } - } - /* Display final address */ -#if !defined(__ROMCC__) - printk(BIOS_DEBUG, "%08lx", addr); -#else - print_debug_hex32(addr); -#endif - - if (i) { + if (verbose) { #if !defined(__ROMCC__) - printk(BIOS_DEBUG, "\nDRAM did _NOT_ verify!\n"); + if ((addr & 0x0f) == 0) + printk(BIOS_DEBUG, "%08lx wr: %08lx rd:", + start + addr, value); + if (failed) + printk(BIOS_DEBUG, " %08lx!", value2); + else + printk(BIOS_DEBUG, " %08lx ", value2); + if ((addr & 0x0f) == 0xc) + printk(BIOS_DEBUG, "\n"); #else - print_debug("\nDRAM did _NOT_ verify!\n"); + if ((addr & 0x0f) == 0) { + print_dbg_hex32(start + addr); + print_dbg(" wr: "); + print_dbg_hex32(value); + print_dbg(" rd: "); + } + print_dbg_hex32(value2); + if (failed) + print_dbg("! "); + else + print_dbg(" "); + if ((addr & 0x0f) == 0xc) + print_dbg("\n"); #endif - die("DRAM ERROR"); + } } - else { -#if !defined(__ROMCC__) - printk(BIOS_DEBUG, "\nDRAM range verified.\n"); -#else - print_debug("\nDRAM range verified.\n"); -#endif + if (failures) { + post_code(0xea); + die("RAM INIT FAILURE!\n"); } }
- void ram_check(unsigned long start, unsigned long stop) { /* @@ -166,18 +167,13 @@ void ram_check(unsigned long start, unsigned long stop) * are tested. -Tyson */ #if !defined(__ROMCC__) - printk(BIOS_DEBUG, "Testing DRAM : %08lx - %08lx\n", start, stop); + printk(BIOS_DEBUG, "Testing DRAM at: %08lx\n", start); #else - print_debug("Testing DRAM : "); + print_debug("Testing DRAM at: "); print_debug_hex32(start); - print_debug("-"); - print_debug_hex32(stop); print_debug("\n"); #endif - ram_fill(start, stop); - /* Make sure we don't read before we wrote */ - phys_memory_barrier(); - ram_verify(start, stop); + ram_bitset(start); #if !defined(__ROMCC__) printk(BIOS_DEBUG, "Done.\n"); #else @@ -214,4 +210,3 @@ void quick_ram_check(void) } phys_memory_barrier(); } -