[U-Boot] [RFC PATCH 0/2] Fix armv8 cache flushing

I have been puzzled by the need to flush external L3 cache for Freescale Layerscape series SoCs. Flushing L3 requires EL3. It is the case now, but this may change in the future. Implementing a SMC call to perform this task is possible but only if necessary. Recent investigation shows we can flush by virtual address most of the time. The only exception is when dcache_disable() is called. I think this can be addressed by flushing the stack U-Boot is using and skip flushing L3 totally.
Once this is proved to work, we can drop flushing L3 all together.
During this investigation, I found the procedure of turning off d-cache seems wrong. The data is lost if d-cache is off first. I am not sure if this only happens to Freescale Layerscape SoCs. Wondering why no one else reports any issue, expecially those SoCs without L3 cache.
York Sun (2): armv8: Fix dcache disable function armv8: Fix flush_dcache_all function
arch/arm/cpu/armv8/cache_v8.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)

Current code turns off d-cache first, then flush all levels of cache. This results data loss. As soon as d-cache is off, the dirty cache is discarded according to the test on LS2080A. This issue was not seen as long as external L3 cache was flushed to push the data to main memory. However, external L3 cache is not guaranteed to have the data. To fix this, flush the d-cache by way/set first to make sure cache is clean before turning it off.
Signed-off-by: York Sun york.sun@nxp.com CC: David Feng fenghua@phytium.com.cn ---
arch/arm/cpu/armv8/cache_v8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index cd3f6c1..92d6277 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -478,9 +478,9 @@ void dcache_disable(void) if (!(sctlr & CR_C)) return;
+ flush_dcache_all(); set_sctlr(sctlr & ~(CR_C|CR_M));
- flush_dcache_all(); __asm_invalidate_tlb_all(); }

Previously it was believed L3 cache has to be flushed in order to guarantee data integrity in main memory. However, flushing L3 cache may require EL3, depending on SoC implementation. Flushing with virtual address can also put data into main memory. The trick is to find the correct address range. For U-Boot to function correctly, the stack needs to be flushed, up to the top of ram used by U-Boot.
Signed-off-by: York Sun york.sun@nxp.com
Thierry Reding treding@nvidia.com, Radha Mohan Chintakuntla rchintakuntla@cavium.com, Alison Wang b18965@freescale.com, Albert Aribaud albert.u.boot@aribaud.net, Sergey Temerkhanov s.temerkhanov@gmail.com, Stephen Warren swarren@nvidia.com
--- Stephen Warren, your recently added flushing L3 cache for tegra (8e5d804). Can you check if your board still works with this proposed change?
arch/arm/cpu/armv8/cache_v8.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 92d6277..f5494f8 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -430,14 +430,13 @@ void invalidate_dcache_all(void) */ inline void flush_dcache_all(void) { - int ret; + ulong sp;
+ asm("mov %0, sp" : "=r"(sp) : ); + /* Flush stack to the top of ram */ + __asm_flush_dcache_range(sp, gd->ram_top); + /* Flush cache by way/set */ __asm_flush_dcache_all(); - ret = __asm_flush_l3_cache(); - if (ret) - debug("flushing dcache returns 0x%x\n", ret); - else - debug("flushing dcache successfully.\n"); }
/*

On 10/14/2016 01:01 PM, York Sun wrote:
Previously it was believed L3 cache has to be flushed in order to guarantee data integrity in main memory. However, flushing L3 cache may require EL3, depending on SoC implementation. Flushing with virtual address can also put data into main memory. The trick is to find the correct address range. For U-Boot to function correctly, the stack needs to be flushed, up to the top of ram used by U-Boot.
Signed-off-by: York Sun york.sun@nxp.com
Pardon me for this mess up. I thought I put the following addresses in Series-cc. But evidentially I did it wrong.
York
Thierry Reding treding@nvidia.com, Radha Mohan Chintakuntla rchintakuntla@cavium.com, Alison Wang b18965@freescale.com, Albert Aribaud albert.u.boot@aribaud.net, Sergey Temerkhanov s.temerkhanov@gmail.com, Stephen Warren swarren@nvidia.com
participants (2)
-
York Sun
-
york sun