From 1b08f607beeaeede78ad4912ed42062c2fa56771 Mon Sep 17 00:00:00 2001 From: zhuyanlin Date: Thu, 13 Jan 2022 21:02:22 +0800 Subject: [PATCH] arm/xtensa:cache: flush/clean dcache all if size large than cache size For performance, if size large than cache size, use xxx_all instead Signed-off-by: zhuyanlin --- arch/arm/src/armv7-m/arm_cache.c | 20 ++++++++++++++++++++ arch/arm/src/armv8-m/arm_cache.c | 20 ++++++++++++++++++++ arch/xtensa/src/common/xtensa_cache.c | 10 ++++++++++ 3 files changed, 50 insertions(+) diff --git a/arch/arm/src/armv7-m/arm_cache.c b/arch/arm/src/armv7-m/arm_cache.c index f6402862ed..f4153ea1d4 100644 --- a/arch/arm/src/armv7-m/arm_cache.c +++ b/arch/arm/src/armv7-m/arm_cache.c @@ -536,15 +536,25 @@ void up_clean_dcache(uintptr_t start, uintptr_t end) uint32_t ccsidr; uint32_t sshift; uint32_t ssize; + uint32_t sets; + uint32_t ways; /* Get the characteristics of the D-Cache */ ccsidr = getreg32(NVIC_CCSIDR); sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + sets = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ /* Clean the D-Cache over the range of addresses */ ssize = (1 << sshift); + + if ((end - start) >= ssize * (sets + 1) * (ways + 1)) + { + return up_clean_dcache_all(); + } + start &= ~(ssize - 1); ARM_DSB(); @@ -679,15 +689,25 @@ void up_flush_dcache(uintptr_t start, uintptr_t end) uint32_t ccsidr; uint32_t sshift; uint32_t ssize; + uint32_t sets; + uint32_t ways; /* Get the characteristics of the D-Cache */ ccsidr = getreg32(NVIC_CCSIDR); sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + sets = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ /* Clean and invalidate the D-Cache over the range of addresses */ ssize = (1 << sshift); + + if ((end - start) >= ssize * (sets + 1) * (ways + 1)) + { + return up_flush_dcache_all(); + } + start &= ~(ssize - 1); ARM_DSB(); diff --git a/arch/arm/src/armv8-m/arm_cache.c b/arch/arm/src/armv8-m/arm_cache.c index 4b0e67dda0..c7814a8104 100644 --- a/arch/arm/src/armv8-m/arm_cache.c +++ b/arch/arm/src/armv8-m/arm_cache.c @@ -536,15 +536,25 @@ void up_clean_dcache(uintptr_t start, uintptr_t end) uint32_t ccsidr; uint32_t sshift; uint32_t ssize; + uint32_t sets; + uint32_t ways; /* Get the characteristics of the D-Cache */ ccsidr = getreg32(NVIC_CCSIDR); sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + sets = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ /* Clean the D-Cache over the range of addresses */ ssize = (1 << sshift); + + if ((end - start) >= ssize * (sets + 1) * (ways + 1)) + { + return up_clean_dcache_all(); + } + start &= ~(ssize - 1); ARM_DSB(); @@ -679,15 +689,25 @@ void up_flush_dcache(uintptr_t start, uintptr_t end) uint32_t ccsidr; uint32_t sshift; uint32_t ssize; + uint32_t sets; + uint32_t ways; /* Get the characteristics of the D-Cache */ ccsidr = getreg32(NVIC_CCSIDR); sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + sets = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ /* Clean and invalidate the D-Cache over the range of addresses */ ssize = (1 << sshift); + + if ((end - start) >= ssize * (sets + 1) * (ways + 1)) + { + return up_flush_dcache_all(); + } + start &= ~(ssize - 1); ARM_DSB(); diff --git a/arch/xtensa/src/common/xtensa_cache.c b/arch/xtensa/src/common/xtensa_cache.c index 3ad30ced2e..eee53b4739 100644 --- a/arch/xtensa/src/common/xtensa_cache.c +++ b/arch/xtensa/src/common/xtensa_cache.c @@ -418,6 +418,11 @@ void up_clean_dcache(uintptr_t start, uintptr_t end) start &= ~(XCHAL_DCACHE_LINESIZE - 1); + if ((end - start) >= XCHAL_DCACHE_SIZE) + { + return up_clean_dcache_all(); + } + for (; start < end; start += XCHAL_DCACHE_LINESIZE) { __asm__ __volatile__ ("dhwb %0, 0\n" : : "r"(start)); @@ -495,6 +500,11 @@ void up_flush_dcache(uintptr_t start, uintptr_t end) start &= ~(XCHAL_DCACHE_LINESIZE - 1); + if ((end - start) >= XCHAL_DCACHE_SIZE) + { + return up_clean_dcache_all(); + } + for (; start < end; start += XCHAL_DCACHE_LINESIZE) { __asm__ __volatile__ ("dhwbi %0, 0\n" : : "r"(start));