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.palt...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot