summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2021-03-04 11:32:06 -0500
committerSolomon Peachy <pizza@shaftnet.org>2021-03-04 12:00:15 -0500
commitcbace906c6c17bf4912d838385d7c1ee7fb81b25 (patch)
tree2b7f99fd2d072417156cc6174d8de4f955382086
parentbcee95516939f636a676f1521a90bc8a6e1e4692 (diff)
mips: Revert to commiting the cache when we're told to discard an unaligned block.
The filesystem API often passes in unaligned receive buffers, and some code (eg BMP reader) processes data in-place, leading to data loss when we dropped the cache. (And document exactly what we're doing, so we don't go through this again at $future_date) Change-Id: If47a7f2148a5a1a43777f0bd3be1bdfe8239e91e
-rw-r--r--firmware/target/mips/mmu-mips.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/firmware/target/mips/mmu-mips.c b/firmware/target/mips/mmu-mips.c
index 35c47207dd..4f2de528bd 100644
--- a/firmware/target/mips/mmu-mips.c
+++ b/firmware/target/mips/mmu-mips.c
@@ -222,6 +222,22 @@ void discard_dcache_range(const void *base, unsigned int size)
char *ptr = CACHEALIGN_DOWN((char*)base);
char *end = CACHEALIGN_UP((char*)base + size);
+ /* If the start of the buffer is unaligned, write
+ back that cacheline and shrink up the region
+ to discard. */
+ if (base != ptr) {
+ __CACHE_OP(DCHitWBInv, ptr);
+ ptr += CACHEALIGN_SIZE;
+ }
+
+ /* If the end of the buffer is unaligned, write back that
+ cacheline and shrink down the region to discard. */
+ if (ptr != end && (end !=((char*)base + size))) {
+ end -= CACHEALIGN_SIZE;
+ __CACHE_OP(DCHitWBInv, ptr);
+ }
+
+ /* Finally, discard whatever is left */
for(; ptr != end; ptr += CACHEALIGN_SIZE)
__CACHE_OP(DCHitInv, ptr);