From mboxrd@z Thu Jan 1 00:00:00 1970 From: Albert ARIBAUD Date: Mon, 8 Jul 2013 12:22:57 +0200 Subject: [U-Boot] [RFC PATCH] arm: arm926ejs: flush cache before disable it In-Reply-To: <51D9FABE.7000705@gmail.com> References: <1372768555-12477-1-git-send-email-voice.shen@gmail.com> <20130705230200.5c64c39c@lilith> <51D9FABE.7000705@gmail.com> Message-ID: <20130708122257.5f0100ec@lilith> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Bo, On Mon, 08 Jul 2013 07:33:18 +0800, Bo Shen wrote: > Hi Albert, > > ? 7/6/2013 5:02 AM, Albert ARIBAUD ??: > > Hi Bo, > > > > On Tue, 2 Jul 2013 12:35:54 +0000, Bo Shen > > wrote: > > > >> flush cache before disable it > >> > >> Signed-off-by: Bo Shen > >> --- > >> arch/arm/cpu/arm926ejs/cpu.c | 5 ++--- > >> 1 file changed, 2 insertions(+), 3 deletions(-) > >> > >> diff --git a/arch/arm/cpu/arm926ejs/cpu.c b/arch/arm/cpu/arm926ejs/cpu.c > >> index 626384c..10aa165 100644 > >> --- a/arch/arm/cpu/arm926ejs/cpu.c > >> +++ b/arch/arm/cpu/arm926ejs/cpu.c > >> @@ -46,15 +46,14 @@ int cleanup_before_linux (void) > >> > >> disable_interrupts (); > >> > >> + /* flush I/D-cache */ > >> + cache_flush(); > >> > >> /* turn off I/D-cache */ > >> icache_disable(); > >> dcache_disable(); > >> l2_cache_disable(); > >> > >> - /* flush I/D-cache */ > >> - cache_flush(); > >> - > >> return 0; > >> } > > > > What is this change supposed to fix? > > Actually, this is not a issue fix. Maybe my understanding wrong. I think > this is just a logic issue. If the cache is disable, then we flush it, > will the contents in the cache corrupted? > > > There is no need to flush before > > disabling, and actually, flushing before disabling runs the risk that > > between the two, some cache lines be dirtied again so that cache and > > memory won't be coherent any more. > > I am not fully understand this. In my mind, I think flush cache (writing > the dirty data back to memory) is used to keep the coherence. If my > understanding is not correct, please help give more explaination or some > reference document to me for understanding. Maybe you're thinking that "disabling" a cache means turning it off, losing all its content? Actually, disabling does not affect the cache lines' content or state; it only 'bypasses' the cache until enabled again. While the cache is disabled, all dirty lines remain dirty, and all non-empty lines remain non-empty. That being said, yes, flushing is used to keep cache and memory coherent, and this is precisely why the flush must happen after the cache is disabled, not before. It you flush first then disable, you leave a time window between the two where a write to the cache can happen (either because your code does one, or because the compiler optimized one in). If it happens, then you disable a cache which is still dirty -- IOW, your flushing has failed its mission, and your cache and memory are still not coherent. Now, if you disable then flush, then any write between the two will go straight to memory without dirtying the cache, and once it is flushed, you end up with coherent cache and memory. Note that the same time window reason, the cache must be invalidated before it is enabled, not after; invalidating after enabling could cause reads to take old, stale values from the cache rather than fetch the current, fresh ones from memory and caching them. > Thanks. You're welcome. > Best Regards, > Bo Shen Amicalement, -- Albert.