xref: /plan9/sys/src/9/teg2/caches.c (revision 3de6a9c0b3d5cf34fc4090d0bf1930d83799a7fd)
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