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