1 #include <linux/mm.h> 2 #include <asm/mmu_context.h> 3 #include <asm/cacheflush.h> 4 #include <asm/traps.h> 5 6 /* 7 * Write back the dirty D-caches, but not invalidate them. 8 * 9 * START: Virtual Address (U0, P1, or P3) 10 * SIZE: Size of the region. 11 */ 12 static void sh4__flush_wback_region(void *start, int size) 13 { 14 reg_size_t aligned_start, v, cnt, end; 15 16 aligned_start = register_align(start); 17 v = aligned_start & ~(L1_CACHE_BYTES-1); 18 end = (aligned_start + size + L1_CACHE_BYTES-1) 19 & ~(L1_CACHE_BYTES-1); 20 cnt = (end - v) / L1_CACHE_BYTES; 21 22 while (cnt >= 8) { 23 __ocbwb(v); v += L1_CACHE_BYTES; 24 __ocbwb(v); v += L1_CACHE_BYTES; 25 __ocbwb(v); v += L1_CACHE_BYTES; 26 __ocbwb(v); v += L1_CACHE_BYTES; 27 __ocbwb(v); v += L1_CACHE_BYTES; 28 __ocbwb(v); v += L1_CACHE_BYTES; 29 __ocbwb(v); v += L1_CACHE_BYTES; 30 __ocbwb(v); v += L1_CACHE_BYTES; 31 cnt -= 8; 32 } 33 34 while (cnt) { 35 __ocbwb(v); v += L1_CACHE_BYTES; 36 cnt--; 37 } 38 } 39 40 /* 41 * Write back the dirty D-caches and invalidate them. 42 * 43 * START: Virtual Address (U0, P1, or P3) 44 * SIZE: Size of the region. 45 */ 46 static void sh4__flush_purge_region(void *start, int size) 47 { 48 reg_size_t aligned_start, v, cnt, end; 49 50 aligned_start = register_align(start); 51 v = aligned_start & ~(L1_CACHE_BYTES-1); 52 end = (aligned_start + size + L1_CACHE_BYTES-1) 53 & ~(L1_CACHE_BYTES-1); 54 cnt = (end - v) / L1_CACHE_BYTES; 55 56 while (cnt >= 8) { 57 __ocbp(v); v += L1_CACHE_BYTES; 58 __ocbp(v); v += L1_CACHE_BYTES; 59 __ocbp(v); v += L1_CACHE_BYTES; 60 __ocbp(v); v += L1_CACHE_BYTES; 61 __ocbp(v); v += L1_CACHE_BYTES; 62 __ocbp(v); v += L1_CACHE_BYTES; 63 __ocbp(v); v += L1_CACHE_BYTES; 64 __ocbp(v); v += L1_CACHE_BYTES; 65 cnt -= 8; 66 } 67 while (cnt) { 68 __ocbp(v); v += L1_CACHE_BYTES; 69 cnt--; 70 } 71 } 72 73 /* 74 * No write back please 75 */ 76 static void sh4__flush_invalidate_region(void *start, int size) 77 { 78 reg_size_t aligned_start, v, cnt, end; 79 80 aligned_start = register_align(start); 81 v = aligned_start & ~(L1_CACHE_BYTES-1); 82 end = (aligned_start + size + L1_CACHE_BYTES-1) 83 & ~(L1_CACHE_BYTES-1); 84 cnt = (end - v) / L1_CACHE_BYTES; 85 86 while (cnt >= 8) { 87 __ocbi(v); v += L1_CACHE_BYTES; 88 __ocbi(v); v += L1_CACHE_BYTES; 89 __ocbi(v); v += L1_CACHE_BYTES; 90 __ocbi(v); v += L1_CACHE_BYTES; 91 __ocbi(v); v += L1_CACHE_BYTES; 92 __ocbi(v); v += L1_CACHE_BYTES; 93 __ocbi(v); v += L1_CACHE_BYTES; 94 __ocbi(v); v += L1_CACHE_BYTES; 95 cnt -= 8; 96 } 97 98 while (cnt) { 99 __ocbi(v); v += L1_CACHE_BYTES; 100 cnt--; 101 } 102 } 103 104 void __init sh4__flush_region_init(void) 105 { 106 __flush_wback_region = sh4__flush_wback_region; 107 __flush_invalidate_region = sh4__flush_invalidate_region; 108 __flush_purge_region = sh4__flush_purge_region; 109 } 110