1 /*
2 * operations on all memory data or unified caches, a no-op cache,
3 * and an l1-only cache ops cache.
4 * i-caches are not handled here.
5 *
6 * there are only three cache operations that we care about:
7 * force cache contents to memory (before dma out or shutdown),
8 * ignore cache contents in favour of memory (initialisation, after dma in),
9 * both (update page tables and force cpu to read new contents).
10 */
11
12 #include "u.h"
13 #include "../port/lib.h"
14 #include "mem.h"
15 #include "dat.h"
16 #include "fns.h"
17 #include "io.h"
18 #include "../port/error.h"
19
20 static Cacheimpl allcaches, nullcaches, l1caches;
21
22 void
cachesinfo(Memcache * cp)23 cachesinfo(Memcache *cp)
24 {
25 memset(cp, 0, sizeof *cp);
26 cp->setsways = Cara | Cawa | Cawt | Cawb;
27 cp->l1ip = 3<<14; /* PIPT */
28 cp->log2linelen = log2(CACHELINESZ);
29 }
30
31 void
allcacheson(void)32 allcacheson(void)
33 {
34 l2pl310init();
35 allcache = &allcaches;
36 nocache = &nullcaches;
37 l1cache = &l1caches;
38 }
39
40 void
cachesoff(void)41 cachesoff(void)
42 {
43 l2cache->off();
44 }
45
46 void
cachesinvse(void * va,int bytes)47 cachesinvse(void *va, int bytes)
48 {
49 int s;
50
51 s = splhi();
52 l2cache->invse(va, bytes);
53 cachedinvse(va, bytes);
54 splx(s);
55 }
56
57 void
cacheswbse(void * va,int bytes)58 cacheswbse(void *va, int bytes)
59 {
60 int s;
61
62 s = splhi();
63 cachedwbse(va, bytes);
64 l2cache->wbse(va, bytes);
65 splx(s);
66 }
67
68 void
cacheswbinvse(void * va,int bytes)69 cacheswbinvse(void *va, int bytes)
70 {
71 int s;
72
73 s = splhi();
74 cachedwbse(va, bytes);
75 l2cache->wbinvse(va, bytes);
76 cachedwbinvse(va, bytes);
77 splx(s);
78 }
79
80
81 void
cachesinv(void)82 cachesinv(void)
83 {
84 int s;
85
86 s = splhi();
87 l2cache->inv();
88 cachedinv();
89 splx(s);
90 }
91
92 void
cacheswb(void)93 cacheswb(void)
94 {
95 int s;
96
97 s = splhi();
98 cachedwb();
99 l2cache->wb();
100 splx(s);
101 }
102
103 void
cacheswbinv(void)104 cacheswbinv(void)
105 {
106 int s;
107
108 s = splhi();
109 cachedwb();
110 l2cache->wbinv();
111 cachedwbinv();
112 splx(s);
113 }
114
115 static Cacheimpl allcaches = {
116 .info = cachesinfo,
117 .on = allcacheson,
118 .off = cachesoff,
119
120 .inv = cachesinv,
121 .wb = cacheswb,
122 .wbinv = cacheswbinv,
123
124 .invse = cachesinvse,
125 .wbse = cacheswbse,
126 .wbinvse= cacheswbinvse,
127 };
128
129
130 /*
131 * null cache ops
132 */
133
134 void
nullinfo(Memcache * cp)135 nullinfo(Memcache *cp)
136 {
137 memset(cp, 0, sizeof *cp);
138 cp->log2linelen = 2;
139 }
140
141 void
nullon(void)142 nullon(void)
143 {
144 nocache = &nullcaches;
145 }
146
147 void
nullop(void)148 nullop(void)
149 {
150 }
151
152 void
nullse(void *,int)153 nullse(void *, int)
154 {
155 }
156
157 static Cacheimpl nullcaches = {
158 .info = nullinfo,
159 .on = nullon,
160 .off = nullop,
161
162 .inv = nullop,
163 .wb = nullop,
164 .wbinv = nullop,
165
166 .invse = nullse,
167 .wbse = nullse,
168 .wbinvse= nullse,
169 };
170
171 /*
172 * l1-only ops
173 */
174
175 void
l1cachesinfo(Memcache *)176 l1cachesinfo(Memcache *)
177 {
178 }
179
180 void
l1cacheson(void)181 l1cacheson(void)
182 {
183 l1cache = &l1caches;
184 }
185
186 static Cacheimpl l1caches = {
187 .info = l1cachesinfo,
188 .on = l1cacheson,
189 .off = nullop,
190
191 .inv = cachedinv,
192 .wb = cachedwb,
193 .wbinv = cachedwbinv,
194
195 .invse = cachedinvse,
196 .wbse = cachedwbse,
197 .wbinvse= cachedwbinvse,
198 };
199