diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2019-02-19 17:18:50 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-02-20 08:20:13 -0800 |
commit | 153c90a2026f1ae56705e4880e2461354d1ac9af (patch) | |
tree | 9e6c9f177163c48fb1727bf7cf6749b61affcf5e | |
parent | 0ab7ffefc75159861c7e35d9e6eb673997358c14 (diff) | |
download | chrome-ec-153c90a2026f1ae56705e4880e2461354d1ac9af.tar.gz |
mt_scp: Add functions to clean/invalidated selected ranges of D-cache
The previous version could only work on single lines, let's add
functions to work on ranges.
BRANCH=none
BUG=b:123676508
TEST=fill; flush; fill to generate incoherent DRAM/cache content
TEST=flush 0x10000000 16 c => clean a single line
flush 0x10000020 32 c => clean a single line
flush 0x10000040 64 c => clean 2 lines
TEST=flush 0x10000080 16 i => invalidate 1 line
flush 0x100000a0 32 i => invalidate 1 line
flush 0x100000c0 64 i => invalidate 2 lines
Change-Id: Ib386eeb4ce5d2f64a23e558c7f562eba234e6b0d
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1475105
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Reviewed-by: Yilun Lin <yllin@chromium.org>
-rw-r--r-- | chip/mt_scp/memmap.c | 34 | ||||
-rw-r--r-- | chip/mt_scp/registers.h | 1 | ||||
-rw-r--r-- | core/cortex-m/cpu.h | 8 |
3 files changed, 28 insertions, 15 deletions
diff --git a/chip/mt_scp/memmap.c b/chip/mt_scp/memmap.c index ef86c175c9..8250b4f6ec 100644 --- a/chip/mt_scp/memmap.c +++ b/chip/mt_scp/memmap.c @@ -73,11 +73,17 @@ void cpu_invalidate_dcache(void) asm volatile("dsb;"); } -void cpu_invalidate_dcache_address(uintptr_t address) +void cpu_invalidate_dcache_range(uintptr_t base, unsigned int length) { - SCP_CACHE_OP(CACHE_DCACHE) = (address & SCP_CACHE_OP_TADDR_MASK); - SCP_CACHE_OP(CACHE_DCACHE) |= - OP_INVALIDATE_ONE_LINE_BY_ADDRESS | SCP_CACHE_OP_EN; + size_t pos; + uintptr_t addr; + + for (pos = 0; pos < length; pos += SCP_CACHE_LINE_SIZE) { + addr = base + pos; + SCP_CACHE_OP(CACHE_DCACHE) = addr & SCP_CACHE_OP_TADDR_MASK; + SCP_CACHE_OP(CACHE_DCACHE) |= + OP_INVALIDATE_ONE_LINE_BY_ADDRESS | SCP_CACHE_OP_EN; + } asm volatile("dsb;"); } @@ -92,14 +98,20 @@ void cpu_clean_invalidate_dcache(void) asm volatile("dsb;"); } -void cpu_clean_invalidate_dcache_address(uintptr_t address) +void cpu_clean_invalidate_dcache_range(uintptr_t base, unsigned int length) { - SCP_CACHE_OP(CACHE_DCACHE) = (address & SCP_CACHE_OP_TADDR_MASK); - SCP_CACHE_OP(CACHE_DCACHE) |= - OP_CACHE_FLUSH_ONE_LINE_BY_ADDRESS | SCP_CACHE_OP_EN; - SCP_CACHE_OP(CACHE_DCACHE) = (address & SCP_CACHE_OP_TADDR_MASK); - SCP_CACHE_OP(CACHE_DCACHE) |= - OP_INVALIDATE_ONE_LINE_BY_ADDRESS | SCP_CACHE_OP_EN; + size_t pos; + uintptr_t addr; + + for (pos = 0; pos < length; pos += SCP_CACHE_LINE_SIZE) { + addr = base + pos; + SCP_CACHE_OP(CACHE_DCACHE) = addr & SCP_CACHE_OP_TADDR_MASK; + SCP_CACHE_OP(CACHE_DCACHE) |= + OP_CACHE_FLUSH_ONE_LINE_BY_ADDRESS | SCP_CACHE_OP_EN; + SCP_CACHE_OP(CACHE_DCACHE) = addr & SCP_CACHE_OP_TADDR_MASK; + SCP_CACHE_OP(CACHE_DCACHE) |= + OP_INVALIDATE_ONE_LINE_BY_ADDRESS | SCP_CACHE_OP_EN; + } asm volatile("dsb;"); } diff --git a/chip/mt_scp/registers.h b/chip/mt_scp/registers.h index 25368290a6..9c61a5dd2e 100644 --- a/chip/mt_scp/registers.h +++ b/chip/mt_scp/registers.h @@ -419,6 +419,7 @@ #define SCP_CACHE_OP_TADDR_SHIFT 5 #define SCP_CACHE_OP_TADDR_MASK (0x7ffffff << SCP_CACHE_OP_TADDR_SHIFT) +#define SCP_CACHE_LINE_SIZE (1 << SCP_CACHE_OP_TADDR_SHIFT) /* Cache statistics */ #define SCP_CACHE_HCNT0L(x) REG32(SCP_CACHE_SEL(x) + 0x08) diff --git a/core/cortex-m/cpu.h b/core/cortex-m/cpu.h index 7f91b33179..87e0631787 100644 --- a/core/cortex-m/cpu.h +++ b/core/cortex-m/cpu.h @@ -71,9 +71,9 @@ void cpu_invalidate_dcache(void); /* Clean and Invalidate the D-cache to the Point of Coherency */ void cpu_clean_invalidate_dcache(void); -/* Invalidate a single address of the D-cache */ -void cpu_invalidate_dcache_address(uintptr_t address); -/* Clean and Invalidate a single address of the D-cache */ -void cpu_clean_invalidate_dcache_address(uintptr_t address); +/* Invalidate a single range of the D-cache */ +void cpu_invalidate_dcache_range(uintptr_t base, unsigned int length); +/* Clean and Invalidate a single range of the D-cache */ +void cpu_clean_invalidate_dcache_range(uintptr_t base, unsigned int length); #endif /* __CROS_EC_CPU_H */ |