@@ -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);
}
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@synopsys.com> --- arch/arc/lib/cache.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)