Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / sh / mm / flush-sh4.c
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
105 void __init sh4__flush_region_init(void)
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 }