From 69fd539886eb529695557a4b46baccebfa86b82f Mon Sep 17 00:00:00 2001 From: zhangyuan21 Date: Tue, 18 Apr 2023 06:54:43 +0800 Subject: [PATCH] arch/armv7ar: use robust code sequences for cache maintenance Invalidate operations at DDI0246H_l2c310_r3p3_trm: If there is a stale entry in the L2 cache, the system enables the invalidation of the L1 cache. But before the controller invalidates the L2 cache, it allocates a line from the L2 cache to an L1 cache. The robust code sequence for invalidation with a non-exclusive cache arrangement is: 1. InvalLevel2 Address ; forces the address out past level 2 2. CACHE SYNC ; Ensures completion of the L2 inval 3. InvalLevel1 Address ; This is broadcast within the cluster 4. DSB ; Ensure completion of the inval as far as Level 2. This sequence ensures that, if there is an allocation to L1 after the L1 invalidation, the data picked up is the new data and not stale data from the L2 Signed-off-by: zhangyuan21 --- arch/arm/src/armv7-a/arm_cache.c | 12 +++++++----- arch/arm/src/armv7-r/arm_cache.c | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/arch/arm/src/armv7-a/arm_cache.c b/arch/arm/src/armv7-a/arm_cache.c index 95eb5ebae3b..83cc2180bdc 100644 --- a/arch/arm/src/armv7-a/arm_cache.c +++ b/arch/arm/src/armv7-a/arm_cache.c @@ -216,8 +216,8 @@ size_t up_get_dcache_linesize(void) void up_invalidate_dcache(uintptr_t start, uintptr_t end) { - cp15_invalidate_dcache(start, end); l2cc_invalidate(start, end); + cp15_invalidate_dcache(start, end); } /**************************************************************************** @@ -241,8 +241,8 @@ void up_invalidate_dcache_all(void) { #ifdef CONFIG_ARCH_L2CACHE irqstate_t flags = enter_critical_section(); - cp15_invalidate_dcache_all(); l2cc_invalidate_all(); + cp15_invalidate_dcache_all(); leave_critical_section(flags); #else cp15_invalidate_dcache_all(); @@ -338,14 +338,15 @@ void up_flush_dcache(uintptr_t start, uintptr_t end) { if ((end - start) < cp15_cache_size()) { - cp15_flush_dcache(start, end); + cp15_clean_dcache(start, end); } else { - cp15_flush_dcache_all(); + cp15_clean_dcache_all(); } l2cc_flush(start, end); + cp15_invalidate_dcache(start, end); } /**************************************************************************** @@ -372,8 +373,9 @@ void up_flush_dcache(uintptr_t start, uintptr_t end) void up_flush_dcache_all(void) { - cp15_flush_dcache_all(); + cp15_clean_dcache_all(); l2cc_flush_all(); + cp15_invalidate_dcache_all(); } /**************************************************************************** diff --git a/arch/arm/src/armv7-r/arm_cache.c b/arch/arm/src/armv7-r/arm_cache.c index 0163f176cb0..42b048102b3 100644 --- a/arch/arm/src/armv7-r/arm_cache.c +++ b/arch/arm/src/armv7-r/arm_cache.c @@ -216,8 +216,8 @@ size_t up_get_dcache_linesize(void) void up_invalidate_dcache(uintptr_t start, uintptr_t end) { - cp15_invalidate_dcache(start, end); l2cc_invalidate(start, end); + cp15_invalidate_dcache(start, end); } /**************************************************************************** @@ -241,8 +241,8 @@ void up_invalidate_dcache_all(void) { #ifdef CONFIG_ARCH_L2CACHE irqstate_t flags = enter_critical_section(); - cp15_invalidate_dcache_all(); l2cc_invalidate_all(); + cp15_invalidate_dcache_all(); leave_critical_section(flags); #else cp15_invalidate_dcache_all(); @@ -338,14 +338,15 @@ void up_flush_dcache(uintptr_t start, uintptr_t end) { if ((end - start) < cp15_cache_size()) { - cp15_flush_dcache(start, end); + cp15_clean_dcache(start, end); } else { - cp15_flush_dcache_all(); + cp15_clean_dcache_all(); } l2cc_flush(start, end); + cp15_invalidate_dcache(start, end); } /**************************************************************************** @@ -372,8 +373,9 @@ void up_flush_dcache(uintptr_t start, uintptr_t end) void up_flush_dcache_all(void) { - cp15_flush_dcache_all(); + cp15_clean_dcache_all(); l2cc_flush_all(); + cp15_invalidate_dcache_all(); } /****************************************************************************