summaryrefslogtreecommitdiff
path: root/firmware/target/mips/mmu-mips.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/mmu-mips.c')
-rw-r--r--firmware/target/mips/mmu-mips.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/firmware/target/mips/mmu-mips.c b/firmware/target/mips/mmu-mips.c
index eb7004952e..f4ffbfa6ee 100644
--- a/firmware/target/mips/mmu-mips.c
+++ b/firmware/target/mips/mmu-mips.c
@@ -192,10 +192,11 @@ void commit_discard_dcache(void)
192 */ 192 */
193void commit_discard_dcache_range(const void *base, unsigned int size) 193void commit_discard_dcache_range(const void *base, unsigned int size)
194{ 194{
195 register char *s; 195 char *ptr = CACHEALIGN_DOWN((char*)base);
196 char *end = CACHEALIGN_UP((char*)base + size);
196 197
197 for (s=(char *)base; s<(char *)base+size; s+=CACHEALIGN_SIZE) 198 for(; ptr != end; ptr += CACHEALIGN_SIZE)
198 __CACHE_OP(DCHitWBInv, s); 199 __CACHE_OP(DCHitWBInv, ptr);
199 200
200 SYNC_WB(); 201 SYNC_WB();
201} 202}
@@ -204,10 +205,11 @@ void commit_discard_dcache_range(const void *base, unsigned int size)
204 */ 205 */
205void commit_dcache_range(const void *base, unsigned int size) 206void commit_dcache_range(const void *base, unsigned int size)
206{ 207{
207 register char *s; 208 char *ptr = CACHEALIGN_DOWN((char*)base);
209 char *end = CACHEALIGN_UP((char*)base + size);
208 210
209 for (s=(char *)base; s<(char *)base+size; s+=CACHEALIGN_SIZE) 211 for(; ptr != end; ptr += CACHEALIGN_SIZE)
210 __CACHE_OP(DCHitWB, s); 212 __CACHE_OP(DCHitWB, ptr);
211 213
212 SYNC_WB(); 214 SYNC_WB();
213} 215}
@@ -217,17 +219,24 @@ void commit_dcache_range(const void *base, unsigned int size)
217 */ 219 */
218void discard_dcache_range(const void *base, unsigned int size) 220void discard_dcache_range(const void *base, unsigned int size)
219{ 221{
220 register char *s; 222 char *ptr = CACHEALIGN_DOWN((char*)base);
223 char *end = CACHEALIGN_UP((char*)base + size);
221 224
222 if (((int)base & CACHEALIGN_SIZE - 1) || 225 if(ptr != base) {
223 (((int)base + size) & CACHEALIGN_SIZE - 1)) { 226 /* Start of region not cache aligned */
224 /* Overlapping sections, so we need to write back instead */ 227 __CACHE_OP(DCHitWBInv, ptr);
225 commit_discard_dcache_range(base, size); 228 ptr += CACHEALIGN_SIZE;
226 return; 229 }
227 }; 230
231 if(base+size != end) {
232 /* End of region not cache aligned */
233 end -= CACHEALIGN_SIZE;
234 __CACHE_OP(DCHitWBInv, end);
235 }
228 236
229 for (s=(char *)base; s<(char *)base+size; s+=CACHEALIGN_SIZE) 237 /* Interior of region is safe to discard */
230 __CACHE_OP(DCHitInv, s); 238 for(; ptr != end; ptr += CACHEALIGN_SIZE)
239 __CACHE_OP(DCHitInv, ptr);
231 240
232 SYNC_WB(); 241 SYNC_WB();
233} 242}