2 #include <lib.h> /* Prototypes */
3 #include <console/console.h>
5 static void write_phys(unsigned long addr
, u32 value
)
7 // Assembler in lib/ is very ugly. But we properly guarded
8 // it so let's obey this one for now
9 #if IS_ENABLED(CONFIG_SSE2)
13 : "r" (addr
), "r" (value
) /* inputs */
14 #ifndef __GNUC__ /* GCC does not like empty clobbers? */
19 volatile unsigned long *ptr
;
25 static u32
read_phys(unsigned long addr
)
27 volatile unsigned long *ptr
;
32 static void phys_memory_barrier(void)
34 #if IS_ENABLED(CONFIG_SSE2)
39 #ifdef __GNUC__ /* ROMCC does not like memory clobbers */
44 #ifdef __GNUC__ /* ROMCC does not like empty asm statements */
45 asm volatile ("" ::: "memory");
51 * Rotate ones test pattern that access every bit on a 128bit wide
52 * memory bus. To test most address lines, addresses are scattered
53 * using 256B, 4kB and 64kB increments.
55 * @param idx Index to test pattern (0=<idx<0x400)
56 * @param addr Memory to access on idx
57 * @param value Value to write or read at addr
59 static inline void test_pattern(unsigned short int idx
,
60 unsigned long *addr
, unsigned long *value
)
65 j
= (idx
>> 4) & 0x0f;
68 *value
= 0x01010101 << (j
& 7);
74 * Simple write-read-verify memory test. See console debug output for
75 * any dislocated bytes.
77 * @param start System memory offset, aligned to 128bytes
79 static int ram_bitset_nodie(unsigned long start
)
81 unsigned long addr
, value
, value2
;
82 unsigned short int idx
;
83 unsigned char failed
, failures
;
86 printk(BIOS_DEBUG
, "DRAM bitset write: 0x%08lx\n", start
);
87 for (idx
= 0; idx
< 0x400; idx
+= 4) {
88 test_pattern(idx
, &addr
, &value
);
89 write_phys(start
+ addr
, value
);
92 /* Make sure we don't read before we wrote */
93 phys_memory_barrier();
95 printk(BIOS_DEBUG
, "DRAM bitset verify: 0x%08lx\n", start
);
97 for (idx
= 0; idx
< 0x400; idx
+= 4) {
98 test_pattern(idx
, &addr
, &value
);
99 value2
= read_phys(start
+ addr
);
101 failed
= (value2
!= value
);
103 if (failed
&& !verbose
) {
104 printk(BIOS_ERR
, "0x%08lx wr: 0x%08lx rd: 0x%08lx FAIL\n",
105 start
+ addr
, value
, value2
);
108 if ((addr
& 0x0f) == 0)
109 printk(BIOS_DEBUG
, "%08lx wr: %08lx rd:",
110 start
+ addr
, value
);
112 printk(BIOS_DEBUG
, " %08lx!", value2
);
114 printk(BIOS_DEBUG
, " %08lx ", value2
);
115 if ((addr
& 0x0f) == 0xc)
116 printk(BIOS_DEBUG
, "\n");
121 printk(BIOS_DEBUG
, "\nDRAM did _NOT_ verify!\n");
124 printk(BIOS_DEBUG
, "\nDRAM range verified.\n");
129 void ram_check(unsigned long start
, unsigned long stop
)
132 * This is much more of a "Is my DRAM properly configured?"
133 * test than a "Is my DRAM faulty?" test. Not all bits
136 printk(BIOS_DEBUG
, "Testing DRAM at: %08lx\n", start
);
137 if (ram_bitset_nodie(start
))
139 printk(BIOS_DEBUG
, "Done.\n");
143 int ram_check_nodie(unsigned long start
, unsigned long stop
)
147 * This is much more of a "Is my DRAM properly configured?"
148 * test than a "Is my DRAM faulty?" test. Not all bits
151 printk(BIOS_DEBUG
, "Testing DRAM at : %08lx\n", start
);
153 ret
= ram_bitset_nodie(start
);
154 printk(BIOS_DEBUG
, "Done.\n");
158 int ram_check_noprint_nodie(unsigned long start
, unsigned long stop
)
160 unsigned long addr
, value
, value2
;
161 unsigned short int idx
;
162 unsigned char failed
, failures
;
164 for (idx
= 0; idx
< 0x400; idx
+= 4) {
165 test_pattern(idx
, &addr
, &value
);
166 write_phys(start
+ addr
, value
);
169 /* Make sure we don't read before we wrote */
170 phys_memory_barrier();
173 for (idx
= 0; idx
< 0x400; idx
+= 4) {
174 test_pattern(idx
, &addr
, &value
);
175 value2
= read_phys(start
+ addr
);
177 failed
= (value2
!= value
);
183 static void __quick_ram_check(uintptr_t dst
)
187 backup
= read_phys(dst
);
188 write_phys(dst
, 0x55555555);
189 phys_memory_barrier();
190 if (read_phys(dst
) != 0x55555555)
192 write_phys(dst
, 0xaaaaaaaa);
193 phys_memory_barrier();
194 if (read_phys(dst
) != 0xaaaaaaaa)
196 write_phys(dst
, 0x00000000);
197 phys_memory_barrier();
198 if (read_phys(dst
) != 0x00000000)
200 write_phys(dst
, 0xffffffff);
201 phys_memory_barrier();
202 if (read_phys(dst
) != 0xffffffff)
205 write_phys(dst
, backup
);
208 die("RAM INIT FAILURE!\n");
210 phys_memory_barrier();
213 void quick_ram_check(void)
215 __quick_ram_check(0x100000);