aboutsummaryrefslogtreecommitdiff
path: root/src/lib/ramtest.c
diff options
context:
space:
mode:
authorStefan Reinauer <stepan@coresystems.de>2010-03-28 21:31:30 +0000
committerStefan Reinauer <stepan@openbios.org>2010-03-28 21:31:30 +0000
commite0d607a4c5838628822904e75bdb3cd69ffa3220 (patch)
treeb0744985fec4250ec5a801ce6a7aa5e101050430 /src/lib/ramtest.c
parentbcd31fff4213345c3447f0ffffec7331dfed8c3e (diff)
Add a non-time consuming version of ram check so we can print a decent error
rather than looping on non-working ram. Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5309 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/lib/ramtest.c')
-rw-r--r--src/lib/ramtest.c62
1 files changed, 54 insertions, 8 deletions
diff --git a/src/lib/ramtest.c b/src/lib/ramtest.c
index 5f24bc1c7d..a43101235b 100644
--- a/src/lib/ramtest.c
+++ b/src/lib/ramtest.c
@@ -1,6 +1,6 @@
#include <lib.h> /* Prototypes */
-static void write_phys(unsigned long addr, unsigned long value)
+static void write_phys(unsigned long addr, u32 value)
{
// Assembler in lib/ is very ugly. But we properly guarded
// it so let's obey this one for now
@@ -9,7 +9,7 @@ static void write_phys(unsigned long addr, unsigned long value)
"movnti %1, (%0)"
: /* outputs */
: "r" (addr), "r" (value) /* inputs */
-#ifndef __GNUC__
+#ifndef __GNUC__ /* GCC does not like empty clobbers? */
: /* clobbers */
#endif
);
@@ -20,13 +20,31 @@ static void write_phys(unsigned long addr, unsigned long value)
#endif
}
-static unsigned long read_phys(unsigned long addr)
+static u32 read_phys(unsigned long addr)
{
volatile unsigned long *ptr;
ptr = (void *)addr;
return *ptr;
}
+static void phys_memory_barrier(void)
+{
+#if CONFIG_SSE2
+ // Needed for movnti
+ asm volatile (
+ "sfence"
+ ::
+#ifdef __GNUC__ /* ROMCC does not like memory clobbers */
+ : "memory"
+#endif
+ );
+#else
+#ifdef __GNUC__ /* ROMCC does not like empty asm statements */
+ asm volatile ("" ::: "memory");
+#endif
+#endif
+}
+
static void ram_fill(unsigned long start, unsigned long stop)
{
unsigned long addr;
@@ -52,12 +70,8 @@ static void ram_fill(unsigned long start, unsigned long stop)
print_debug(" \r");
#endif
}
- write_phys(addr, addr);
+ write_phys(addr, (u32)addr);
};
-#if CONFIG_SSE2
- // Needed for movnti
- asm volatile ("sfence" ::: "memory");
-#endif
/* Display final address */
#if CONFIG_USE_PRINTK_IN_CAR
printk(BIOS_DEBUG, "%08lx\r\nDRAM filled\r\n", addr);
@@ -159,6 +173,8 @@ void ram_check(unsigned long start, unsigned long stop)
print_debug("\r\n");
#endif
ram_fill(start, stop);
+ /* Make sure we don't read before we wrote */
+ phys_memory_barrier();
ram_verify(start, stop);
#if CONFIG_USE_PRINTK_IN_CAR
printk(BIOS_DEBUG, "Done.\r\n");
@@ -167,3 +183,33 @@ void ram_check(unsigned long start, unsigned long stop)
#endif
}
+void quick_ram_check(void)
+{
+ int fail = 0;
+ u32 backup;
+ backup = read_phys(CONFIG_RAMBASE);
+ write_phys(CONFIG_RAMBASE, 0x55555555);
+ phys_memory_barrier();
+ if (read_phys(CONFIG_RAMBASE) != 0x55555555)
+ fail=1;
+ write_phys(CONFIG_RAMBASE, 0xaaaaaaaa);
+ phys_memory_barrier();
+ if (read_phys(CONFIG_RAMBASE) != 0xaaaaaaaa)
+ fail=1;
+ write_phys(CONFIG_RAMBASE, 0x00000000);
+ phys_memory_barrier();
+ if (read_phys(CONFIG_RAMBASE) != 0x00000000)
+ fail=1;
+ write_phys(CONFIG_RAMBASE, 0xffffffff);
+ phys_memory_barrier();
+ if (read_phys(CONFIG_RAMBASE) != 0xffffffff)
+ fail=1;
+
+ write_phys(CONFIG_RAMBASE, backup);
+ if (fail) {
+ post_code(0xea);
+ die("RAM INIT FAILURE!\n");
+ }
+ phys_memory_barrier();
+}
+