xref: /netbsd/sys/arch/mips/mips/cache_tx39.c (revision bf9ec67e)
1 /*	$NetBSD: cache_tx39.c,v 1.2 2001/11/14 18:26:23 thorpej Exp $	*/
2 
3 /*
4  * Copyright 2001 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed for the NetBSD Project by
20  *	Wasabi Systems, Inc.
21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22  *    or promote products derived from this software without specific prior
23  *    written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include <sys/param.h>
39 
40 #include <mips/cache.h>
41 #include <mips/cache_tx39.h>
42 #include <mips/locore.h>
43 
44 /*
45  * Cache operations for TX3900/TX3920-style caches:
46  *
47  *	- I-cache direct-mapped (TX3900) or 2-way set-associative (TX3920)
48  *	- D-cache 2-way set-associative
49  *	- Write-through (TX3900, TX3920) or write-back (TX3920)
50  *	- Physically indexed, phyiscally tagged
51  *
52  * XXX THIS IS NOT YET COMPLETE.
53  */
54 
55 #define	round_line(x)		(((x) + 15) & ~15)
56 #define	trunc_line(x)		((x) & ~15)
57 
58 void
59 tx3900_icache_sync_all_16(void)
60 {
61 
62 	tx3900_icache_do_inv_index_16(MIPS_PHYS_TO_KSEG0(0),
63 	    MIPS_PHYS_TO_KSEG0(mips_picache_size));
64 }
65 
66 void
67 tx3900_icache_sync_range_16(vaddr_t va, vsize_t size)
68 {
69 	vaddr_t eva = round_line(va + size);
70 
71 	va = trunc_line(va);
72 
73 	if ((eva - va) >= mips_picache_size) {
74 		/* Just hit the whole thing. */
75 		va = MIPS_PHYS_TO_KSEG0(0);
76 		eva = MIPS_PHYS_TO_KSEG0(mips_picache_size);
77 	}
78 
79 	tx3900_icache_do_inv_index_16(va, eva);
80 }
81 
82 #undef round_line
83 #undef trunc_line
84 
85 #define	round_line(x)		(((x) + 3) & ~3)
86 #define	trunc_line(x)		((x) & ~3)
87 
88 static int tx3900_dummy_buffer[R3900_C_SIZE_MAX / sizeof(int)];
89 
90 void
91 tx3900_pdcache_wbinv_all_4(void)
92 {
93 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
94 	vaddr_t eva = va + mips_pdcache_size;
95 	__volatile int *p;
96 
97 	/*
98 	 * No Index Invalidate for the TX3900 -- have to execute a
99 	 * series of load instructions from the dummy buffer, instead.
100 	 */
101 
102 	p = tx3900_dummy_buffer;
103 	while (va < eva) {
104 		(void) *p++; (void) *p++; (void) *p++; (void) *p++;
105 		(void) *p++; (void) *p++; (void) *p++; (void) *p++;
106 		(void) *p++; (void) *p++; (void) *p++; (void) *p++;
107 		(void) *p++; (void) *p++; (void) *p++; (void) *p++;
108 		(void) *p++; (void) *p++; (void) *p++; (void) *p++;
109 		(void) *p++; (void) *p++; (void) *p++; (void) *p++;
110 		(void) *p++; (void) *p++; (void) *p++; (void) *p++;
111 		(void) *p++; (void) *p++; (void) *p++; (void) *p++;
112 		va += (32 * 4);
113 	}
114 }
115 
116 void
117 tx3900_pdcache_inv_range_4(vaddr_t va, vsize_t size)
118 {
119 	vaddr_t eva = round_line(va + size);
120 
121 	va = trunc_line(va);
122 
123 	while ((eva - va) >= (32 * 4)) {
124 		cache_tx39_op_32lines_4(va,
125 		    CACHE_TX39_D|CACHEOP_TX3900_HIT_INV);
126 		va += (32 * 4);
127 	};
128 
129 	while (va < eva) {
130 		cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3900_HIT_INV);
131 		va += 4;
132 	}
133 }
134 
135 void
136 tx3900_pdcache_wb_range_4(vaddr_t va, vsize_t size)
137 {
138 
139 	/* Cache is write-through. */
140 }
141 
142 #undef round_line
143 #undef trunc_line
144 
145 #define	round_line(x)		(((x) + 15) & ~15)
146 #define	trunc_line(x)		((x) & ~15)
147 
148 void
149 tx3920_icache_sync_all_16wb(void)
150 {
151 
152 	mips_dcache_wbinv_all();
153 
154 	__asm __volatile("sync");
155 
156 	tx3920_icache_do_inv_16(MIPS_PHYS_TO_KSEG0(0),
157 	    MIPS_PHYS_TO_KSEG0(mips_picache_size));
158 }
159 
160 void
161 tx3920_icache_sync_range_16wt(vaddr_t va, vsize_t size)
162 {
163 	vaddr_t eva = round_line(va + size);
164 
165 	va = trunc_line(va);
166 
167 	tx3920_icache_do_inv_16(va, eva);
168 }
169 
170 void
171 tx3920_icache_sync_range_16wb(vaddr_t va, vsize_t size)
172 {
173 	vaddr_t eva = round_line(va + size);
174 
175 	va = trunc_line(va);
176 
177 	mips_dcache_wb_range(va, (eva - va));
178 
179 	__asm __volatile("sync");
180 
181 	tx3920_icache_do_inv_16(va, eva);
182 }
183 
184 void
185 tx3920_pdcache_wbinv_all_16wt(void)
186 {
187 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
188 	vaddr_t eva = va + mips_pdcache_size;
189 
190 	/*
191 	 * Since we're hitting the whole thing, we don't have to
192 	 * worry about the 2 different "ways".
193 	 */
194 
195 	while (va < eva) {
196 		cache_tx39_op_32lines_16(va,
197 		    CACHE_TX39_D|CACHEOP_TX3920_INDEX_INV);
198 		va += (32 * 16);
199 	}
200 }
201 
202 void
203 tx3920_pdcache_wbinv_all_16wb(void)
204 {
205 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
206 	vaddr_t eva = va + mips_pdcache_size;
207 
208 	/*
209 	 * Since we're hitting the whole thing, we don't have to
210 	 * worry about the 2 different "ways".
211 	 */
212 
213 	while (va < eva) {
214 		cache_tx39_op_32lines_16(va,
215 		    CACHE_TX39_D|CACHEOP_TX3920_INDEX_WB_INV);
216 		va += (32 * 16);
217 	}
218 }
219 
220 void
221 tx3920_pdcache_wbinv_range_16wb(vaddr_t va, vsize_t size)
222 {
223 	vaddr_t eva = round_line(va + size);
224 
225 	va = trunc_line(va);
226 
227 	while ((eva - va) >= (32 * 16)) {
228 		cache_tx39_op_32lines_16(va,
229 		    CACHE_TX39_D|CACHEOP_TX3920_HIT_WB_INV);
230 		va += (32 * 16);
231 	}
232 
233 	while (va < eva) {
234 		cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3920_HIT_WB_INV);
235 		va += 16;
236 	}
237 }
238 
239 void
240 tx3920_pdcache_inv_range_16(vaddr_t va, vsize_t size)
241 {
242 	vaddr_t eva = round_line(va + size);
243 
244 	va = trunc_line(va);
245 
246 	while ((eva - va) >= (32 * 16)) {
247 		cache_tx39_op_32lines_16(va,
248 		    CACHE_TX39_D|CACHEOP_TX3920_HIT_INV);
249 		va += (32 * 16);
250 	}
251 
252 	while (va < eva) {
253 		cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3920_HIT_INV);
254 		va += 16;
255 	}
256 }
257 
258 void
259 tx3920_pdcache_wb_range_16wt(vaddr_t va, vsize_t size)
260 {
261 
262 	/* Cache is write-through. */
263 }
264 
265 void
266 tx3920_pdcache_wb_range_16wb(vaddr_t va, vsize_t size)
267 {
268 	vaddr_t eva = round_line(va + size);
269 
270 	va = trunc_line(va);
271 
272 	while ((eva - va) >= (32 * 16)) {
273 		cache_tx39_op_32lines_16(va,
274 		    CACHE_TX39_D|CACHEOP_TX3920_HIT_WB);
275 		va += (32 * 16);
276 	}
277 
278 	while (va < eva) {
279 		cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3920_HIT_WB);
280 		va += 16;
281 	}
282 }
283