summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2019-02-19 17:18:50 +0800
committerchrome-bot <chrome-bot@chromium.org>2019-02-20 08:20:13 -0800
commit153c90a2026f1ae56705e4880e2461354d1ac9af (patch)
tree9e6c9f177163c48fb1727bf7cf6749b61affcf5e
parent0ab7ffefc75159861c7e35d9e6eb673997358c14 (diff)
downloadchrome-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.c34
-rw-r--r--chip/mt_scp/registers.h1
-rw-r--r--core/cortex-m/cpu.h8
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 */