blob: e118062c2617d2e2a8f6b63bd17e561a3aee599d [file] [log] [blame]
Patrick Georgid0835952010-10-05 09:07:10 +00001#include <stdint.h>
Myles Watson34261952010-03-19 02:33:40 +00002#include <lib.h> /* Prototypes */
Patrick Georgid0835952010-10-05 09:07:10 +00003#include <console/console.h>
Myles Watson34261952010-03-19 02:33:40 +00004
Stefan Reinauere0d607a2010-03-28 21:31:30 +00005static void write_phys(unsigned long addr, u32 value)
Eric Biederman8ca8d762003-04-22 19:02:15 +00006{
Stefan Reinauera7acc512010-02-25 13:40:49 +00007 // Assembler in lib/ is very ugly. But we properly guarded
8 // it so let's obey this one for now
9#if CONFIG_SSE2
Eric Biederman8d9c1232003-06-17 08:42:17 +000010 asm volatile(
11 "movnti %1, (%0)"
12 : /* outputs */
13 : "r" (addr), "r" (value) /* inputs */
Stefan Reinauere0d607a2010-03-28 21:31:30 +000014#ifndef __GNUC__ /* GCC does not like empty clobbers? */
Eric Biederman8d9c1232003-06-17 08:42:17 +000015 : /* clobbers */
Stefan Reinauer76712932004-05-27 11:13:24 +000016#endif
Eric Biederman8d9c1232003-06-17 08:42:17 +000017 );
18#else
Eric Biederman52685572003-05-19 19:16:21 +000019 volatile unsigned long *ptr;
Eric Biederman8ca8d762003-04-22 19:02:15 +000020 ptr = (void *)addr;
21 *ptr = value;
Eric Biederman8d9c1232003-06-17 08:42:17 +000022#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000023}
24
Stefan Reinauere0d607a2010-03-28 21:31:30 +000025static u32 read_phys(unsigned long addr)
Eric Biederman8ca8d762003-04-22 19:02:15 +000026{
Eric Biederman52685572003-05-19 19:16:21 +000027 volatile unsigned long *ptr;
Eric Biederman8ca8d762003-04-22 19:02:15 +000028 ptr = (void *)addr;
29 return *ptr;
30}
31
Stefan Reinauere0d607a2010-03-28 21:31:30 +000032static void phys_memory_barrier(void)
33{
34#if CONFIG_SSE2
35 // Needed for movnti
36 asm volatile (
37 "sfence"
38 ::
39#ifdef __GNUC__ /* ROMCC does not like memory clobbers */
40 : "memory"
41#endif
42 );
43#else
44#ifdef __GNUC__ /* ROMCC does not like empty asm statements */
45 asm volatile ("" ::: "memory");
46#endif
47#endif
48}
49
Eric Biederman8d9c1232003-06-17 08:42:17 +000050static void ram_fill(unsigned long start, unsigned long stop)
Eric Biederman8ca8d762003-04-22 19:02:15 +000051{
52 unsigned long addr;
Stefan Reinauer14e22772010-04-27 06:56:47 +000053 /*
Eric Biederman8ca8d762003-04-22 19:02:15 +000054 * Fill.
55 */
Kyösti Mälkki481814d2011-10-28 16:15:47 +030056#if !defined(__ROMCC__)
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000057 printk(BIOS_DEBUG, "DRAM fill: 0x%08lx-0x%08lx\n", start, stop);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000058#else
Eric Biederman8ca8d762003-04-22 19:02:15 +000059 print_debug("DRAM fill: ");
60 print_debug_hex32(start);
61 print_debug("-");
62 print_debug_hex32(stop);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000063 print_debug("\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000064#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000065 for(addr = start; addr < stop ; addr += 4) {
66 /* Display address being filled */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000067 if (!(addr & 0xfffff)) {
Kyösti Mälkki481814d2011-10-28 16:15:47 +030068#if !defined(__ROMCC__)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000069 printk(BIOS_DEBUG, "%08lx \r", addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000070#else
Eric Biederman8ca8d762003-04-22 19:02:15 +000071 print_debug_hex32(addr);
Eric Biederman69afe282004-11-11 06:53:24 +000072 print_debug(" \r");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000073#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000074 }
Stefan Reinauere0d607a2010-03-28 21:31:30 +000075 write_phys(addr, (u32)addr);
Eric Biederman8ca8d762003-04-22 19:02:15 +000076 };
77 /* Display final address */
Kyösti Mälkki481814d2011-10-28 16:15:47 +030078#if !defined(__ROMCC__)
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000079 printk(BIOS_DEBUG, "%08lx\nDRAM filled\n", addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000080#else
Eric Biederman8ca8d762003-04-22 19:02:15 +000081 print_debug_hex32(addr);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000082 print_debug("\nDRAM filled\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000083#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000084}
85
Sven Schnelle3ad8c542011-12-02 16:23:06 +010086static int ram_verify_nodie(unsigned long start, unsigned long stop)
Eric Biederman8ca8d762003-04-22 19:02:15 +000087{
88 unsigned long addr;
Eric Biederman69afe282004-11-11 06:53:24 +000089 int i = 0;
Stefan Reinauer14e22772010-04-27 06:56:47 +000090 /*
Eric Biederman8ca8d762003-04-22 19:02:15 +000091 * Verify.
92 */
Kyösti Mälkki481814d2011-10-28 16:15:47 +030093#if !defined(__ROMCC__)
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000094 printk(BIOS_DEBUG, "DRAM verify: 0x%08lx-0x%08lx\n", start, stop);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000095#else
Eric Biederman8ca8d762003-04-22 19:02:15 +000096 print_debug("DRAM verify: ");
97 print_debug_hex32(start);
98 print_debug_char('-');
99 print_debug_hex32(stop);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000100 print_debug("\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000101#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000102 for(addr = start; addr < stop ; addr += 4) {
103 unsigned long value;
104 /* Display address being tested */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000105 if (!(addr & 0xfffff)) {
Kyösti Mälkki481814d2011-10-28 16:15:47 +0300106#if !defined(__ROMCC__)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000107 printk(BIOS_DEBUG, "%08lx \r", addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000108#else
Eric Biederman8ca8d762003-04-22 19:02:15 +0000109 print_debug_hex32(addr);
Eric Biederman69afe282004-11-11 06:53:24 +0000110 print_debug(" \r");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000111#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000112 }
113 value = read_phys(addr);
114 if (value != addr) {
115 /* Display address with error */
Kyösti Mälkki481814d2011-10-28 16:15:47 +0300116#if !defined(__ROMCC__)
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000117 printk(BIOS_ERR, "Fail: @0x%08lx Read value=0x%08lx\n", addr, value);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000118#else
Richard Smithffb7d8a2006-04-01 04:10:44 +0000119 print_err("Fail: @0x");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000120 print_err_hex32(addr);
Richard Smithffb7d8a2006-04-01 04:10:44 +0000121 print_err(" Read value=0x");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000122 print_err_hex32(value);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000123 print_err("\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000124#endif
Eric Biederman69afe282004-11-11 06:53:24 +0000125 i++;
Richard Smithffb7d8a2006-04-01 04:10:44 +0000126 if(i>256) {
Kyösti Mälkki481814d2011-10-28 16:15:47 +0300127#if !defined(__ROMCC__)
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000128 printk(BIOS_DEBUG, "Aborting.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000129#else
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000130 print_debug("Aborting.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000131#endif
Richard Smithffb7d8a2006-04-01 04:10:44 +0000132 break;
133 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000134 }
135 }
136 /* Display final address */
Kyösti Mälkki481814d2011-10-28 16:15:47 +0300137#if !defined(__ROMCC__)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000138 printk(BIOS_DEBUG, "%08lx", addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000139#else
Eric Biederman8ca8d762003-04-22 19:02:15 +0000140 print_debug_hex32(addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000141#endif
142
Richard Smithffb7d8a2006-04-01 04:10:44 +0000143 if (i) {
Kyösti Mälkki481814d2011-10-28 16:15:47 +0300144#if !defined(__ROMCC__)
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000145 printk(BIOS_DEBUG, "\nDRAM did _NOT_ verify!\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000146#else
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000147 print_debug("\nDRAM did _NOT_ verify!\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000148#endif
Sven Schnelle3ad8c542011-12-02 16:23:06 +0100149 return 1;
Richard Smithffb7d8a2006-04-01 04:10:44 +0000150 }
151 else {
Kyösti Mälkki481814d2011-10-28 16:15:47 +0300152#if !defined(__ROMCC__)
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000153 printk(BIOS_DEBUG, "\nDRAM range verified.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000154#else
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000155 print_debug("\nDRAM range verified.\n");
Sven Schnelle3ad8c542011-12-02 16:23:06 +0100156 return 0;
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000157#endif
Richard Smithffb7d8a2006-04-01 04:10:44 +0000158 }
Sven Schnelle3ad8c542011-12-02 16:23:06 +0100159 return 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000160}
161
162
Eric Biederman8d9c1232003-06-17 08:42:17 +0000163void ram_check(unsigned long start, unsigned long stop)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000164{
Eric Biederman8ca8d762003-04-22 19:02:15 +0000165 /*
166 * This is much more of a "Is my DRAM properly configured?"
167 * test than a "Is my DRAM faulty?" test. Not all bits
168 * are tested. -Tyson
169 */
Kyösti Mälkki481814d2011-10-28 16:15:47 +0300170#if !defined(__ROMCC__)
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000171 printk(BIOS_DEBUG, "Testing DRAM : %08lx - %08lx\n", start, stop);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000172#else
Ronald G. Minnichbfdc5622004-03-22 04:24:29 +0000173 print_debug("Testing DRAM : ");
174 print_debug_hex32(start);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000175 print_debug("-");
Ronald G. Minnichbfdc5622004-03-22 04:24:29 +0000176 print_debug_hex32(stop);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000177 print_debug("\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000178#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000179 ram_fill(start, stop);
Stefan Reinauere0d607a2010-03-28 21:31:30 +0000180 /* Make sure we don't read before we wrote */
181 phys_memory_barrier();
Sven Schnelle3ad8c542011-12-02 16:23:06 +0100182 if (ram_verify_nodie(start, stop))
183 die("DRAM ERROR");
Kyösti Mälkki481814d2011-10-28 16:15:47 +0300184#if !defined(__ROMCC__)
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000185 printk(BIOS_DEBUG, "Done.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000186#else
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000187 print_debug("Done.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000188#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000189}
190
Sven Schnelle3ad8c542011-12-02 16:23:06 +0100191
192int ram_check_nodie(unsigned long start, unsigned long stop)
193{
194 int ret;
195 /*
196 * This is much more of a "Is my DRAM properly configured?"
197 * test than a "Is my DRAM faulty?" test. Not all bits
198 * are tested. -Tyson
199 */
200#if !defined(__ROMCC__)
201 printk(BIOS_DEBUG, "Testing DRAM : %08lx - %08lx\n", start, stop);
202#else
203 print_debug("Testing DRAM : ");
204 print_debug_hex32(start);
205 print_debug("-");
206 print_debug_hex32(stop);
207 print_debug("\n");
208#endif
209 ram_fill(start, stop);
210 /* Make sure we don't read before we wrote */
211 phys_memory_barrier();
212 ret = ram_verify_nodie(start, stop);
213
214#if !defined(__ROMCC__)
215 printk(BIOS_DEBUG, "Done.\n");
216#else
217 print_debug("Done.\n");
218#endif
219 return ret;
220}
221
Stefan Reinauere0d607a2010-03-28 21:31:30 +0000222void quick_ram_check(void)
223{
224 int fail = 0;
225 u32 backup;
226 backup = read_phys(CONFIG_RAMBASE);
227 write_phys(CONFIG_RAMBASE, 0x55555555);
228 phys_memory_barrier();
229 if (read_phys(CONFIG_RAMBASE) != 0x55555555)
230 fail=1;
231 write_phys(CONFIG_RAMBASE, 0xaaaaaaaa);
232 phys_memory_barrier();
233 if (read_phys(CONFIG_RAMBASE) != 0xaaaaaaaa)
234 fail=1;
235 write_phys(CONFIG_RAMBASE, 0x00000000);
236 phys_memory_barrier();
237 if (read_phys(CONFIG_RAMBASE) != 0x00000000)
238 fail=1;
239 write_phys(CONFIG_RAMBASE, 0xffffffff);
240 phys_memory_barrier();
241 if (read_phys(CONFIG_RAMBASE) != 0xffffffff)
242 fail=1;
243
244 write_phys(CONFIG_RAMBASE, backup);
245 if (fail) {
246 post_code(0xea);
247 die("RAM INIT FAILURE!\n");
248 }
249 phys_memory_barrier();
250}
251