diff --git a/common/memsize.c b/common/memsize.c index 66d5be6a1f..d646df8b04 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -7,9 +7,18 @@ #include #include #include +#include +#include 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 @@ -20,6 +29,15 @@ 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 @@ -34,6 +52,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! */ @@ -41,6 +60,8 @@ long get_ram_size(long *base, long maxsize) save[i++] = *addr; sync(); *addr = ~cnt; + if (dcache_en) + dcache_flush_invalidate(addr); } addr = base; @@ -50,6 +71,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();