blob: 605d555e467527404024e85d68a46ef2b5aceec4 [file] [log] [blame]
Myles Watson34261952010-03-19 02:33:40 +00001#include <lib.h> /* Prototypes */
2
Stefan Reinauere0d607a2010-03-28 21:31:30 +00003static void write_phys(unsigned long addr, u32 value)
Eric Biederman8ca8d762003-04-22 19:02:15 +00004{
Stefan Reinauera7acc512010-02-25 13:40:49 +00005 // Assembler in lib/ is very ugly. But we properly guarded
6 // it so let's obey this one for now
7#if CONFIG_SSE2
Eric Biederman8d9c1232003-06-17 08:42:17 +00008 asm volatile(
9 "movnti %1, (%0)"
10 : /* outputs */
11 : "r" (addr), "r" (value) /* inputs */
Stefan Reinauere0d607a2010-03-28 21:31:30 +000012#ifndef __GNUC__ /* GCC does not like empty clobbers? */
Eric Biederman8d9c1232003-06-17 08:42:17 +000013 : /* clobbers */
Stefan Reinauer76712932004-05-27 11:13:24 +000014#endif
Eric Biederman8d9c1232003-06-17 08:42:17 +000015 );
16#else
Eric Biederman52685572003-05-19 19:16:21 +000017 volatile unsigned long *ptr;
Eric Biederman8ca8d762003-04-22 19:02:15 +000018 ptr = (void *)addr;
19 *ptr = value;
Eric Biederman8d9c1232003-06-17 08:42:17 +000020#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000021}
22
Stefan Reinauere0d607a2010-03-28 21:31:30 +000023static u32 read_phys(unsigned long addr)
Eric Biederman8ca8d762003-04-22 19:02:15 +000024{
Eric Biederman52685572003-05-19 19:16:21 +000025 volatile unsigned long *ptr;
Eric Biederman8ca8d762003-04-22 19:02:15 +000026 ptr = (void *)addr;
27 return *ptr;
28}
29
Stefan Reinauere0d607a2010-03-28 21:31:30 +000030static void phys_memory_barrier(void)
31{
32#if CONFIG_SSE2
33 // Needed for movnti
34 asm volatile (
35 "sfence"
36 ::
37#ifdef __GNUC__ /* ROMCC does not like memory clobbers */
38 : "memory"
39#endif
40 );
41#else
42#ifdef __GNUC__ /* ROMCC does not like empty asm statements */
43 asm volatile ("" ::: "memory");
44#endif
45#endif
46}
47
Eric Biederman8d9c1232003-06-17 08:42:17 +000048static void ram_fill(unsigned long start, unsigned long stop)
Eric Biederman8ca8d762003-04-22 19:02:15 +000049{
50 unsigned long addr;
51 /*
52 * Fill.
53 */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000054#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000055 printk(BIOS_DEBUG, "DRAM fill: 0x%08lx-0x%08lx\n", start, stop);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000056#else
Eric Biederman8ca8d762003-04-22 19:02:15 +000057 print_debug("DRAM fill: ");
58 print_debug_hex32(start);
59 print_debug("-");
60 print_debug_hex32(stop);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000061 print_debug("\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000062#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000063 for(addr = start; addr < stop ; addr += 4) {
64 /* Display address being filled */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000065 if (!(addr & 0xfffff)) {
66#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000067 printk(BIOS_DEBUG, "%08lx \r", addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000068#else
Eric Biederman8ca8d762003-04-22 19:02:15 +000069 print_debug_hex32(addr);
Eric Biederman69afe282004-11-11 06:53:24 +000070 print_debug(" \r");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000071#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000072 }
Stefan Reinauere0d607a2010-03-28 21:31:30 +000073 write_phys(addr, (u32)addr);
Eric Biederman8ca8d762003-04-22 19:02:15 +000074 };
75 /* Display final address */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000076#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000077 printk(BIOS_DEBUG, "%08lx\nDRAM filled\n", addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000078#else
Eric Biederman8ca8d762003-04-22 19:02:15 +000079 print_debug_hex32(addr);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000080 print_debug("\nDRAM filled\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000081#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000082}
83
Eric Biederman8d9c1232003-06-17 08:42:17 +000084static void ram_verify(unsigned long start, unsigned long stop)
Eric Biederman8ca8d762003-04-22 19:02:15 +000085{
86 unsigned long addr;
Eric Biederman69afe282004-11-11 06:53:24 +000087 int i = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +000088 /*
89 * Verify.
90 */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000091#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000092 printk(BIOS_DEBUG, "DRAM verify: 0x%08lx-0x%08lx\n", start, stop);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000093#else
Eric Biederman8ca8d762003-04-22 19:02:15 +000094 print_debug("DRAM verify: ");
95 print_debug_hex32(start);
96 print_debug_char('-');
97 print_debug_hex32(stop);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +000098 print_debug("\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +000099#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000100 for(addr = start; addr < stop ; addr += 4) {
101 unsigned long value;
102 /* Display address being tested */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000103 if (!(addr & 0xfffff)) {
104#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000105 printk(BIOS_DEBUG, "%08lx \r", addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000106#else
Eric Biederman8ca8d762003-04-22 19:02:15 +0000107 print_debug_hex32(addr);
Eric Biederman69afe282004-11-11 06:53:24 +0000108 print_debug(" \r");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000109#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000110 }
111 value = read_phys(addr);
112 if (value != addr) {
113 /* Display address with error */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000114#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000115 printk(BIOS_ERR, "Fail: @0x%08lx Read value=0x%08lx\n", addr, value);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000116#else
Richard Smithffb7d8a2006-04-01 04:10:44 +0000117 print_err("Fail: @0x");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000118 print_err_hex32(addr);
Richard Smithffb7d8a2006-04-01 04:10:44 +0000119 print_err(" Read value=0x");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000120 print_err_hex32(value);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000121 print_err("\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000122#endif
Eric Biederman69afe282004-11-11 06:53:24 +0000123 i++;
Richard Smithffb7d8a2006-04-01 04:10:44 +0000124 if(i>256) {
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000125#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000126 printk(BIOS_DEBUG, "Aborting.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000127#else
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000128 print_debug("Aborting.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000129#endif
Richard Smithffb7d8a2006-04-01 04:10:44 +0000130 break;
131 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000132 }
133 }
134 /* Display final address */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000135#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000136 printk(BIOS_DEBUG, "%08lx", addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000137#else
Eric Biederman8ca8d762003-04-22 19:02:15 +0000138 print_debug_hex32(addr);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000139#endif
140
Richard Smithffb7d8a2006-04-01 04:10:44 +0000141 if (i) {
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000142#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000143 printk(BIOS_DEBUG, "\nDRAM did _NOT_ verify!\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000144#else
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000145 print_debug("\nDRAM did _NOT_ verify!\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000146#endif
147 die("DRAM ERROR");
Richard Smithffb7d8a2006-04-01 04:10:44 +0000148 }
149 else {
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000150#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000151 printk(BIOS_DEBUG, "\nDRAM range verified.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000152#else
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000153 print_debug("\nDRAM range verified.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000154#endif
Richard Smithffb7d8a2006-04-01 04:10:44 +0000155 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000156}
157
158
Eric Biederman8d9c1232003-06-17 08:42:17 +0000159void ram_check(unsigned long start, unsigned long stop)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000160{
Eric Biederman8ca8d762003-04-22 19:02:15 +0000161 /*
162 * This is much more of a "Is my DRAM properly configured?"
163 * test than a "Is my DRAM faulty?" test. Not all bits
164 * are tested. -Tyson
165 */
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000166#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000167 printk(BIOS_DEBUG, "Testing DRAM : %08lx - %08lx\n", start, stop);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000168#else
Ronald G. Minnichbfdc5622004-03-22 04:24:29 +0000169 print_debug("Testing DRAM : ");
170 print_debug_hex32(start);
171 print_debug("-");
172 print_debug_hex32(stop);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000173 print_debug("\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000174#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000175 ram_fill(start, stop);
Stefan Reinauere0d607a2010-03-28 21:31:30 +0000176 /* Make sure we don't read before we wrote */
177 phys_memory_barrier();
Eric Biederman8ca8d762003-04-22 19:02:15 +0000178 ram_verify(start, stop);
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000179#if CONFIG_USE_PRINTK_IN_CAR
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000180 printk(BIOS_DEBUG, "Done.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000181#else
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000182 print_debug("Done.\n");
Stefan Reinauer48b85fc2008-08-01 12:12:37 +0000183#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000184}
185
Stefan Reinauere0d607a2010-03-28 21:31:30 +0000186void quick_ram_check(void)
187{
188 int fail = 0;
189 u32 backup;
190 backup = read_phys(CONFIG_RAMBASE);
191 write_phys(CONFIG_RAMBASE, 0x55555555);
192 phys_memory_barrier();
193 if (read_phys(CONFIG_RAMBASE) != 0x55555555)
194 fail=1;
195 write_phys(CONFIG_RAMBASE, 0xaaaaaaaa);
196 phys_memory_barrier();
197 if (read_phys(CONFIG_RAMBASE) != 0xaaaaaaaa)
198 fail=1;
199 write_phys(CONFIG_RAMBASE, 0x00000000);
200 phys_memory_barrier();
201 if (read_phys(CONFIG_RAMBASE) != 0x00000000)
202 fail=1;
203 write_phys(CONFIG_RAMBASE, 0xffffffff);
204 phys_memory_barrier();
205 if (read_phys(CONFIG_RAMBASE) != 0xffffffff)
206 fail=1;
207
208 write_phys(CONFIG_RAMBASE, backup);
209 if (fail) {
210 post_code(0xea);
211 die("RAM INIT FAILURE!\n");
212 }
213 phys_memory_barrier();
214}
215