Skip to content
Snippets Groups Projects
Commit 219c2db3 authored by Paul Burton's avatar Paul Burton Committed by Daniel Schwierzeck
Browse files

MIPS: Ensure cache ops complete in cache maintenance functions


A typical use of cache maintenance functions is to force writeback of
data which a device is about to read using DMA - for example a
descriptor or command structure. Such users of cache maintenance
functions require that operations on the cache have completed before
they proceed to instruct a device to read memory. This requires that we
place a completion barrier (ie. sync instruction) between the cache ops
and whatever write informs the device to perform DMA.

Whilst strictly speaking this isn't all users of the cache maintenance
functions & we could instead place the barriers in the drivers that
require them, it would be much more invasive to do so than to just have
the barrier be the default by placing it in the cache functions
themselves. The cost is low enough that it shouldn't matter to us in any
rare cases that we use the cache functions when not performing DMA.

Signed-off-by: default avatarPaul Burton <paul.burton@mips.com>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: u-boot@lists.denx.de
parent c5bf161f
No related branches found
No related tags found
No related merge requests found
......@@ -10,6 +10,7 @@
#ifdef CONFIG_MIPS_L2_CACHE
#include <asm/cm.h>
#endif
#include <asm/io.h>
#include <asm/mipsregs.h>
DECLARE_GLOBAL_DATA_PTR;
......@@ -116,7 +117,7 @@ void flush_cache(ulong start_addr, ulong size)
/* flush I-cache & D-cache simultaneously */
cache_loop(start_addr, start_addr + size, ilsize,
HIT_WRITEBACK_INV_D, HIT_INVALIDATE_I);
return;
goto ops_done;
}
/* flush D-cache */
......@@ -129,6 +130,10 @@ void flush_cache(ulong start_addr, ulong size)
/* flush I-cache */
cache_loop(start_addr, start_addr + size, ilsize, HIT_INVALIDATE_I);
ops_done:
/* ensure cache ops complete before any further memory accesses */
sync();
}
void flush_dcache_range(ulong start_addr, ulong stop)
......@@ -145,6 +150,9 @@ void flush_dcache_range(ulong start_addr, ulong stop)
/* flush L2 cache */
if (slsize)
cache_loop(start_addr, stop, slsize, HIT_WRITEBACK_INV_SD);
/* ensure cache ops complete before any further memory accesses */
sync();
}
void invalidate_dcache_range(ulong start_addr, ulong stop)
......@@ -161,4 +169,7 @@ void invalidate_dcache_range(ulong start_addr, ulong stop)
cache_loop(start_addr, stop, slsize, HIT_INVALIDATE_SD);
cache_loop(start_addr, stop, lsize, HIT_INVALIDATE_D);
/* ensure cache ops complete before any further memory accesses */
sync();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment