Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
flush-sh4.c
Go to the documentation of this file.
1 #include <linux/mm.h>
2 #include <asm/mmu_context.h>
3 #include <asm/cache_insns.h>
4 #include <asm/cacheflush.h>
5 #include <asm/traps.h>
6 
7 /*
8  * Write back the dirty D-caches, but not invalidate them.
9  *
10  * START: Virtual Address (U0, P1, or P3)
11  * SIZE: Size of the region.
12  */
13 static void sh4__flush_wback_region(void *start, int size)
14 {
15  reg_size_t aligned_start, v, cnt, end;
16 
17  aligned_start = register_align(start);
18  v = aligned_start & ~(L1_CACHE_BYTES-1);
19  end = (aligned_start + size + L1_CACHE_BYTES-1)
20  & ~(L1_CACHE_BYTES-1);
21  cnt = (end - v) / L1_CACHE_BYTES;
22 
23  while (cnt >= 8) {
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  __ocbwb(v); v += L1_CACHE_BYTES;
32  cnt -= 8;
33  }
34 
35  while (cnt) {
36  __ocbwb(v); v += L1_CACHE_BYTES;
37  cnt--;
38  }
39 }
40 
41 /*
42  * Write back the dirty D-caches and invalidate them.
43  *
44  * START: Virtual Address (U0, P1, or P3)
45  * SIZE: Size of the region.
46  */
47 static void sh4__flush_purge_region(void *start, int size)
48 {
49  reg_size_t aligned_start, v, cnt, end;
50 
51  aligned_start = register_align(start);
52  v = aligned_start & ~(L1_CACHE_BYTES-1);
53  end = (aligned_start + size + L1_CACHE_BYTES-1)
54  & ~(L1_CACHE_BYTES-1);
55  cnt = (end - v) / L1_CACHE_BYTES;
56 
57  while (cnt >= 8) {
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  __ocbp(v); v += L1_CACHE_BYTES;
66  cnt -= 8;
67  }
68  while (cnt) {
69  __ocbp(v); v += L1_CACHE_BYTES;
70  cnt--;
71  }
72 }
73 
74 /*
75  * No write back please
76  */
77 static void sh4__flush_invalidate_region(void *start, int size)
78 {
79  reg_size_t aligned_start, v, cnt, end;
80 
81  aligned_start = register_align(start);
82  v = aligned_start & ~(L1_CACHE_BYTES-1);
83  end = (aligned_start + size + L1_CACHE_BYTES-1)
84  & ~(L1_CACHE_BYTES-1);
85  cnt = (end - v) / L1_CACHE_BYTES;
86 
87  while (cnt >= 8) {
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  __ocbi(v); v += L1_CACHE_BYTES;
96  cnt -= 8;
97  }
98 
99  while (cnt) {
100  __ocbi(v); v += L1_CACHE_BYTES;
101  cnt--;
102  }
103 }
104 
106 {
107  __flush_wback_region = sh4__flush_wback_region;
108  __flush_invalidate_region = sh4__flush_invalidate_region;
109  __flush_purge_region = sh4__flush_purge_region;
110 }