diff options
-rw-r--r-- | common/memsize.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/common/memsize.c b/common/memsize.c index e95c68265a..9b46eca105 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -6,9 +6,19 @@ #include <common.h> #include <init.h> +#include <asm/global_data.h> +#include <cpu_func.h> +#include <stdint.h> DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_SYS_CACHELINE_SIZE +# define MEMSIZE_CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE +#else +/* Just use the greatest cache flush alignment requirement I'm aware of */ +# define MEMSIZE_CACHELINE_SIZE 128 +#endif + #ifdef __PPC__ /* * At least on G2 PowerPC cores, sequential accesses to non-existent @@ -19,6 +29,16 @@ DECLARE_GLOBAL_DATA_PTR; # define sync() /* nothing */ #endif +static void dcache_flush_invalidate(volatile long *p) +{ + uintptr_t start, stop; + + start = ALIGN_DOWN((uintptr_t)p, MEMSIZE_CACHELINE_SIZE); + stop = start + MEMSIZE_CACHELINE_SIZE; + flush_dcache_range(start, stop); + invalidate_dcache_range(start, stop); +} + /* * Check memory range for valid RAM. A simple memory test determines * the actually available RAM size between addresses `base' and @@ -33,6 +53,7 @@ long get_ram_size(long *base, long maxsize) long val; long size; int i = 0; + int dcache_en = dcache_status(); for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) { addr = base + cnt; /* pointer arith! */ @@ -40,6 +61,8 @@ long get_ram_size(long *base, long maxsize) save[i++] = *addr; sync(); *addr = ~cnt; + if (dcache_en) + dcache_flush_invalidate(addr); } addr = base; @@ -49,6 +72,9 @@ long get_ram_size(long *base, long maxsize) *addr = 0; sync(); + if (dcache_en) + dcache_flush_invalidate(addr); + if ((val = *addr) != 0) { /* Restore the original data before leaving the function. */ sync(); |