[U-Boot] [PATCH 18/18] ARC: cache: add missing cache cleanup before cache disable

Eugeniy Paltsev Eugeniy.Paltsev at synopsys.com
Tue Feb 13 17:34:51 UTC 2018


Add missing cache cleanup before cache disable:
 * Flush and invalidate L1 D$ before disabling. Otherwise we can
   lose some data when we disable L1 D$ if this data isn't flushed to
   next level cache. Or we can get wrong data if L1 D$ has some entries
   after enable which we modified when the L1 D$ was disabled.
 * Invalidate L1 I$ before disabling. Otherwise we can execute wrong
   instructions after L1 I$ enable if we modified any code when
   L1 I$ was disabled.

Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev at synopsys.com>
---
 arch/arc/lib/cache.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index 907e9e3..ba442fb 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -15,6 +15,9 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static inline void __ic_entire_invalidate(void);
+static inline void __dc_entire_op(const int cacheop);
+
 /* Bit values in IC_CTRL */
 #define IC_CTRL_CACHE_DISABLE	BIT(0)
 
@@ -299,9 +302,13 @@ void icache_enable(void)
 
 void icache_disable(void)
 {
-	if (icache_exists())
-		write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
-			      IC_CTRL_CACHE_DISABLE);
+	if (!icache_exists())
+		return;
+
+	__ic_entire_invalidate();
+
+	write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
+		      IC_CTRL_CACHE_DISABLE);
 }
 
 /* IC supports only invalidation */
@@ -358,6 +365,8 @@ void dcache_disable(void)
 	if (!dcache_exists())
 		return;
 
+	__dc_entire_op(OP_FLUSH_N_INV);
+
 	write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |
 		      DC_CTRL_CACHE_DISABLE);
 }
-- 
2.9.3



More information about the U-Boot mailing list