MIPS: Break out of cache loops for unimplemented caches
authorPaul Burton <paul.burton@mips.com>
Tue, 21 Nov 2017 19:18:39 +0000 (11:18 -0800)
committerDaniel Schwierzeck <daniel.schwierzeck@gmail.com>
Tue, 28 Nov 2017 20:59:30 +0000 (21:59 +0100)
If we run on a CPU which doesn't implement a particular cache then we
would previously get stuck in an infinite loop, executing a cache op on
the first "line" of the missing cache & then incrementing the address by
0. This was being avoided for the L2 caches, but not for the L1s. Fix
this by generalising the check for a zero line size & avoiding the cache
op loop when this is the case.

Signed-off-by: Paul Burton <paul.burton@mips.com>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: u-boot@lists.denx.de
arch/mips/lib/cache.c

index 8e5b028c66c7abdb75815c2744c70c1929d3ffb6..e305f3207a726e7dd60254a5fc8d18ac44f0996f 100644 (file)
@@ -98,6 +98,9 @@ static inline unsigned long scache_line_size(void)
        const unsigned int cache_ops[] = { ops };                       \
        unsigned int i;                                                 \
                                                                        \
+       if (!lsize)                                                     \
+               break;                                                  \
+                                                                       \
        for (; addr <= aend; addr += lsize) {                           \
                for (i = 0; i < ARRAY_SIZE(cache_ops); i++)             \
                        mips_cache(cache_ops[i], addr);                 \
@@ -125,9 +128,7 @@ void flush_cache(ulong start_addr, ulong size)
        cache_loop(start_addr, start_addr + size, dlsize, HIT_WRITEBACK_INV_D);
 
        /* flush L2 cache */
-       if (slsize)
-               cache_loop(start_addr, start_addr + size, slsize,
-                          HIT_WRITEBACK_INV_SD);
+       cache_loop(start_addr, start_addr + size, slsize, HIT_WRITEBACK_INV_SD);
 
        /* flush I-cache */
        cache_loop(start_addr, start_addr + size, ilsize, HIT_INVALIDATE_I);
@@ -152,8 +153,7 @@ void flush_dcache_range(ulong start_addr, ulong stop)
        cache_loop(start_addr, stop, lsize, HIT_WRITEBACK_INV_D);
 
        /* flush L2 cache */
-       if (slsize)
-               cache_loop(start_addr, stop, slsize, HIT_WRITEBACK_INV_SD);
+       cache_loop(start_addr, stop, slsize, HIT_WRITEBACK_INV_SD);
 
        /* ensure cache ops complete before any further memory accesses */
        sync();
@@ -169,8 +169,7 @@ void invalidate_dcache_range(ulong start_addr, ulong stop)
                return;
 
        /* invalidate L2 cache */
-       if (slsize)
-               cache_loop(start_addr, stop, slsize, HIT_INVALIDATE_SD);
+       cache_loop(start_addr, stop, slsize, HIT_INVALIDATE_SD);
 
        cache_loop(start_addr, stop, lsize, HIT_INVALIDATE_D);