i5000: halt second BSP
[coreboot.git] / src / lib / ramtest.c
1 #include <stdint.h>
2 #include <lib.h> /* Prototypes */
3 #include <console/console.h>
4
5 static void write_phys(unsigned long addr, u32 value)
6 {
7         // Assembler in lib/ is very ugly. But we properly guarded
8         // it so let's obey this one for now
9 #if CONFIG_SSE2
10         asm volatile(
11                 "movnti %1, (%0)"
12                 : /* outputs */
13                 : "r" (addr), "r" (value) /* inputs */
14 #ifndef __GNUC__ /* GCC does not like empty clobbers? */
15                 : /* clobbers */
16 #endif
17                 );
18 #else
19         volatile unsigned long *ptr;
20         ptr = (void *)addr;
21         *ptr = value;
22 #endif
23 }
24
25 static u32 read_phys(unsigned long addr)
26 {
27         volatile unsigned long *ptr;
28         ptr = (void *)addr;
29         return *ptr;
30 }
31
32 static 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
50 static void ram_fill(unsigned long start, unsigned long stop)
51 {
52         unsigned long addr;
53         /*
54          * Fill.
55          */
56 #if !defined(__ROMCC__)
57         printk(BIOS_DEBUG, "DRAM fill: 0x%08lx-0x%08lx\n", start, stop);
58 #else
59         print_debug("DRAM fill: ");
60         print_debug_hex32(start);
61         print_debug("-");
62         print_debug_hex32(stop);
63         print_debug("\n");
64 #endif
65         for(addr = start; addr < stop ; addr += 4) {
66                 /* Display address being filled */
67                 if (!(addr & 0xfffff)) {
68 #if !defined(__ROMCC__)
69                         printk(BIOS_DEBUG, "%08lx \r", addr);
70 #else
71                         print_debug_hex32(addr);
72                         print_debug(" \r");
73 #endif
74                 }
75                 write_phys(addr, (u32)addr);
76         };
77         /* Display final address */
78 #if !defined(__ROMCC__)
79         printk(BIOS_DEBUG, "%08lx\nDRAM filled\n", addr);
80 #else
81         print_debug_hex32(addr);
82         print_debug("\nDRAM filled\n");
83 #endif
84 }
85
86 static int ram_verify_nodie(unsigned long start, unsigned long stop)
87 {
88         unsigned long addr;
89         int i = 0;
90         /*
91          * Verify.
92          */
93 #if !defined(__ROMCC__)
94         printk(BIOS_DEBUG, "DRAM verify: 0x%08lx-0x%08lx\n", start, stop);
95 #else
96         print_debug("DRAM verify: ");
97         print_debug_hex32(start);
98         print_debug_char('-');
99         print_debug_hex32(stop);
100         print_debug("\n");
101 #endif
102         for(addr = start; addr < stop ; addr += 4) {
103                 unsigned long value;
104                 /* Display address being tested */
105                 if (!(addr & 0xfffff)) {
106 #if !defined(__ROMCC__)
107                         printk(BIOS_DEBUG, "%08lx \r", addr);
108 #else
109                         print_debug_hex32(addr);
110                         print_debug(" \r");
111 #endif
112                 }
113                 value = read_phys(addr);
114                 if (value != addr) {
115                         /* Display address with error */
116 #if !defined(__ROMCC__)
117                         printk(BIOS_ERR, "Fail: @0x%08lx Read value=0x%08lx\n", addr, value);
118 #else
119                         print_err("Fail: @0x");
120                         print_err_hex32(addr);
121                         print_err(" Read value=0x");
122                         print_err_hex32(value);
123                         print_err("\n");
124 #endif
125                         i++;
126                         if(i>256) {
127 #if !defined(__ROMCC__)
128                                 printk(BIOS_DEBUG, "Aborting.\n");
129 #else
130                                 print_debug("Aborting.\n");
131 #endif
132                                 break;
133                         }
134                 }
135         }
136         /* Display final address */
137 #if !defined(__ROMCC__)
138         printk(BIOS_DEBUG, "%08lx", addr);
139 #else
140         print_debug_hex32(addr);
141 #endif
142
143         if (i) {
144 #if !defined(__ROMCC__)
145                 printk(BIOS_DEBUG, "\nDRAM did _NOT_ verify!\n");
146 #else
147                 print_debug("\nDRAM did _NOT_ verify!\n");
148 #endif
149                 return 1;
150         }
151         else {
152 #if !defined(__ROMCC__)
153                 printk(BIOS_DEBUG, "\nDRAM range verified.\n");
154 #else
155                 print_debug("\nDRAM range verified.\n");
156                 return 0;
157 #endif
158         }
159         return 0;
160 }
161
162
163 void ram_check(unsigned long start, unsigned long stop)
164 {
165         /*
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          */
170 #if !defined(__ROMCC__)
171         printk(BIOS_DEBUG, "Testing DRAM : %08lx - %08lx\n", start, stop);
172 #else
173         print_debug("Testing DRAM : ");
174         print_debug_hex32(start);
175         print_debug("-");
176         print_debug_hex32(stop);
177         print_debug("\n");
178 #endif
179         ram_fill(start, stop);
180         /* Make sure we don't read before we wrote */
181         phys_memory_barrier();
182         if (ram_verify_nodie(start, stop))
183                 die("DRAM ERROR");
184 #if !defined(__ROMCC__)
185         printk(BIOS_DEBUG, "Done.\n");
186 #else
187         print_debug("Done.\n");
188 #endif
189 }
190
191
192 int 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
222 void 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