diff --git a/arch/arm/src/arm/arm_cache.S b/arch/arm/src/arm/arm_cache.S index 92c32d9a9e..53dd580f54 100644 --- a/arch/arm/src/arm/arm_cache.S +++ b/arch/arm/src/arm/arm_cache.S @@ -123,7 +123,16 @@ up_invalidate_icache_all: .type up_invalidate_dcache, function up_invalidate_dcache: - bic r0, r0, #CACHE_DLINESIZE - 1 + mov r2, #CACHE_DLINESIZE - 1 + + tst r0, r2 + bic r0, r0, r2 /* R0=aligned start address */ + mcrne p15, 0, r0, c7, c14, 1 /* Clean & invalidate D entry */ + + tst r1, r2 + bic r1, r1, r2 /* R1=aligned end address */ + mcrne p15, 0, r1, c7, c14, 1 /* Clean & invalidate D entry */ + 1: mcr p15, 0, r0, c7, c6, 1 /* Invalidate D entry */ add r0, r0, #CACHE_DLINESIZE cmp r0, r1 diff --git a/arch/arm/src/armv7-m/arm_cache.c b/arch/arm/src/armv7-m/arm_cache.c index f1629bbc7b..f6402862ed 100644 --- a/arch/arm/src/armv7-m/arm_cache.c +++ b/arch/arm/src/armv7-m/arm_cache.c @@ -404,10 +404,16 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end) * (ssize - 1) = 0x007f : Mask of the set field */ - start &= ~(ssize - 1); ARM_DSB(); - do + if (start & (ssize - 1)) + { + start &= ~(ssize - 1); + putreg32(start, NVIC_DCCIMVAC); + start += ssize; + } + + while (start + ssize <= end) { /* The below store causes the cache to check its directory and * determine if this address is contained in the cache. If so, it @@ -422,7 +428,11 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end) start += ssize; } - while (start < end); + + if (start < end) + { + putreg32(start, NVIC_DCCIMVAC); + } ARM_DSB(); ARM_ISB(); diff --git a/arch/arm/src/armv8-m/arm_cache.c b/arch/arm/src/armv8-m/arm_cache.c index 56b963ef0f..4b0e67dda0 100644 --- a/arch/arm/src/armv8-m/arm_cache.c +++ b/arch/arm/src/armv8-m/arm_cache.c @@ -404,10 +404,16 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end) * (ssize - 1) = 0x007f : Mask of the set field */ - start &= ~(ssize - 1); ARM_DSB(); - do + if (start & (ssize - 1)) + { + start &= ~(ssize - 1); + putreg32(start, NVIC_DCCIMVAC); + start += ssize; + } + + while (start + ssize <= end) { /* The below store causes the cache to check its directory and * determine if this address is contained in the cache. If so, it @@ -422,7 +428,11 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end) start += ssize; } - while (start < end); + + if (start < end) + { + putreg32(start, NVIC_DCCIMVAC); + } ARM_DSB(); ARM_ISB(); diff --git a/arch/xtensa/src/common/xtensa_cache.c b/arch/xtensa/src/common/xtensa_cache.c index 5a0b1233d6..3ad30ced2e 100644 --- a/arch/xtensa/src/common/xtensa_cache.c +++ b/arch/xtensa/src/common/xtensa_cache.c @@ -116,11 +116,11 @@ void up_invalidate_icache(uintptr_t start, uintptr_t end) { /* align to XCHAL_ICACHE_LINESIZE */ - uint32_t addr = start - (start & (XCHAL_ICACHE_LINESIZE - 1)); + start &= ~(XCHAL_ICACHE_LINESIZE - 1); - for (; addr < end; addr += XCHAL_ICACHE_LINESIZE) + for (; start < end; start += XCHAL_ICACHE_LINESIZE) { - __asm__ __volatile__ ("ihi %0, 0\n" : : "r"(addr)); + __asm__ __volatile__ ("ihi %0, 0\n" : : "r"(start)); } __asm__ __volatile__ ("isync\n"); @@ -175,11 +175,11 @@ void up_lock_icache(uintptr_t start, uintptr_t end) { /* align to XCHAL_ICACHE_LINESIZE */ - uint32_t addr = start - (start & (XCHAL_ICACHE_LINESIZE - 1)); + start &= ~(XCHAL_ICACHE_LINESIZE - 1); - for (; addr < end; addr += XCHAL_ICACHE_LINESIZE) + for (; start < end; start += XCHAL_ICACHE_LINESIZE) { - __asm__ __volatile__ ("ipfl %0, 0\n": : "r"(addr)); + __asm__ __volatile__ ("ipfl %0, 0\n": : "r"(start)); }; __asm__ __volatile__ ("isync\n"); @@ -206,11 +206,11 @@ void up_unlock_icache(uintptr_t start, uintptr_t end) { /* align to XCHAL_ICACHE_LINESIZE */ - uint32_t addr = start - (start & (XCHAL_ICACHE_LINESIZE - 1)); + start &= ~(XCHAL_ICACHE_LINESIZE - 1); - for (; addr < end; addr += XCHAL_ICACHE_LINESIZE) + for (; start < end; start += XCHAL_ICACHE_LINESIZE) { - __asm__ __volatile__ ("ihu %0, 0\n": : "r"(addr)); + __asm__ __volatile__ ("ihu %0, 0\n": : "r"(start)); }; __asm__ __volatile__ ("isync\n"); @@ -335,13 +335,24 @@ void up_disable_dcache(void) #ifdef CONFIG_XTENSA_DCACHE void up_invalidate_dcache(uintptr_t start, uintptr_t end) { - /* Align to XCHAL_DCACHE_LINESIZE */ - - uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1)); - - for (; addr < end; addr += XCHAL_DCACHE_LINESIZE) + if (start & (XCHAL_DCACHE_LINESIZE - 1)) { - __asm__ __volatile__ ("dhi %0, 0\n" : : "r"(addr)); + /* Align to XCHAL_DCACHE_LINESIZE */ + + start &= ~(XCHAL_DCACHE_LINESIZE - 1); + __asm__ __volatile__ ("dhwbi %0, 0\n" : : "r"(start)); + start += XCHAL_DCACHE_LINESIZE; + } + + for (; start + XCHAL_DCACHE_LINESIZE <= end; + start += XCHAL_DCACHE_LINESIZE) + { + __asm__ __volatile__ ("dhi %0, 0\n" : : "r"(start)); + } + + if (start != end) + { + __asm__ __volatile__ ("dhwbi %0, 0\n" : : "r"(start)); } __asm__ __volatile__ ("dsync\n"); @@ -405,11 +416,11 @@ void up_clean_dcache(uintptr_t start, uintptr_t end) { /* Align to XCHAL_DCACHE_SIZE */ - uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1)); + start &= ~(XCHAL_DCACHE_LINESIZE - 1); - for (; addr < end; addr += XCHAL_DCACHE_LINESIZE) + for (; start < end; start += XCHAL_DCACHE_LINESIZE) { - __asm__ __volatile__ ("dhwb %0, 0\n" : : "r"(addr)); + __asm__ __volatile__ ("dhwb %0, 0\n" : : "r"(start)); } __asm__ __volatile__ ("dsync\n"); @@ -482,11 +493,11 @@ void up_flush_dcache(uintptr_t start, uintptr_t end) { /* Align to XCHAL_DCACHE_LINESIZE */ - uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1)); + start &= ~(XCHAL_DCACHE_LINESIZE - 1); - for (; addr < end; addr += XCHAL_DCACHE_LINESIZE) + for (; start < end; start += XCHAL_DCACHE_LINESIZE) { - __asm__ __volatile__ ("dhwbi %0, 0\n" : : "r"(addr)); + __asm__ __volatile__ ("dhwbi %0, 0\n" : : "r"(start)); } __asm__ __volatile__ ("dsync\n"); @@ -549,11 +560,11 @@ void up_lock_dcache(uintptr_t start, uintptr_t end) { /* align to XCHAL_DCACHE_LINESIZE */ - uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1)); + start &= ~(XCHAL_DCACHE_LINESIZE - 1); - for (; addr < end; addr += XCHAL_DCACHE_LINESIZE) + for (; start < end; start += XCHAL_DCACHE_LINESIZE) { - __asm__ __volatile__ ("dpfl %0, 0\n": : "r"(addr)); + __asm__ __volatile__ ("dpfl %0, 0\n": : "r"(start)); }; __asm__ __volatile__ ("dsync\n"); @@ -580,11 +591,11 @@ void up_unlock_dcache(uintptr_t start, uintptr_t end) { /* align to XCHAL_DCACHE_LINESIZE */ - uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1)); + start &= ~(XCHAL_DCACHE_LINESIZE - 1); - for (; addr < end; addr += XCHAL_DCACHE_LINESIZE) + for (; start < end; start += XCHAL_DCACHE_LINESIZE) { - __asm__ __volatile__ ("dhu %0, 0\n": : "r"(addr)); + __asm__ __volatile__ ("dhu %0, 0\n": : "r"(start)); }; __asm__ __volatile__ ("dsync\n");