xref: /netbsd/sys/arch/mips/mips/cache.c (revision bf9ec67e)
1 /*	$NetBSD: cache.c,v 1.11 2002/04/03 03:55:07 simonb Exp $	*/
2 
3 /*
4  * Copyright 2001, 2002 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Jason R. Thorpe and Simon Burge 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 /*
39  * Copyright 2000, 2001
40  * Broadcom Corporation. All rights reserved.
41  *
42  * This software is furnished under license and may be used and copied only
43  * in accordance with the following terms and conditions.  Subject to these
44  * conditions, you may download, copy, install, use, modify and distribute
45  * modified or unmodified copies of this software in source and/or binary
46  * form. No title or ownership is transferred hereby.
47  *
48  * 1) Any source code used, modified or distributed must reproduce and
49  *    retain this copyright notice and list of conditions as they appear in
50  *    the source file.
51  *
52  * 2) No right is granted to use any trade name, trademark, or logo of
53  *    Broadcom Corporation. Neither the "Broadcom Corporation" name nor any
54  *    trademark or logo of Broadcom Corporation may be used to endorse or
55  *    promote products derived from this software without the prior written
56  *    permission of Broadcom Corporation.
57  *
58  * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
59  *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
60  *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
61  *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
62  *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
63  *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
64  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
65  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
66  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
67  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
68  *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69  */
70 
71 #include "opt_cputype.h"
72 
73 #include <sys/param.h>
74 
75 #include <uvm/uvm_extern.h>
76 
77 #include <mips/cache.h>
78 #include <mips/locore.h>
79 
80 #ifdef MIPS1
81 #include <mips/cache_r3k.h>
82 #endif
83 
84 #ifdef MIPS3_PLUS
85 #include <mips/cache_r4k.h>	/* includes r5k and greater */
86 #endif
87 
88 #if defined(MIPS32) || defined(MIPS64)
89 #include <mips/mipsNN.h>		/* MIPS32/MIPS64 registers */
90 #include <mips/cache_mipsNN.h>
91 #endif
92 
93 /* PRIMARY CACHE VARIABLES */
94 int mips_picache_size;
95 int mips_picache_line_size;
96 int mips_picache_ways;
97 int mips_picache_way_size;
98 int mips_picache_way_mask;
99 
100 int mips_pdcache_size;           /* and unified */
101 int mips_pdcache_line_size;
102 int mips_pdcache_ways;
103 int mips_pdcache_way_size;
104 int mips_pdcache_way_mask;
105 int mips_pdcache_write_through;
106 
107 int mips_pcache_unified;
108 
109 /* SECONDARY CACHE VARIABLES */
110 int mips_sicache_size;
111 int mips_sicache_line_size;
112 int mips_sicache_ways;
113 int mips_sicache_way_size;
114 int mips_sicache_way_mask;
115 
116 int mips_sdcache_size;           /* and unified */
117 int mips_sdcache_line_size;
118 int mips_sdcache_ways;
119 int mips_sdcache_way_size;
120 int mips_sdcache_way_mask;
121 int mips_sdcache_write_through;
122 
123 int mips_scache_unified;
124 
125 /* TERTIARY CACHE VARIABLES */
126 int mips_tcache_size;            /* always unified */
127 int mips_tcache_line_size;
128 int mips_tcache_ways;
129 int mips_tcache_way_size;
130 int mips_tcache_way_mask;
131 int mips_tcache_write_through;
132 
133 /*
134  * These two variables inform the rest of the kernel about the
135  * size of the largest D-cache line present in the system.  The
136  * mask can be used to determine if a region of memory is cache
137  * line size aligned.
138  *
139  * Whenever any code updates a data cache line size, it should
140  * call mips_dcache_compute_align() to recompute these values.
141  */
142 int mips_dcache_align;
143 int mips_dcache_align_mask;
144 
145 int mips_cache_alias_mask;	/* for virtually-indexed caches */
146 int mips_cache_prefer_mask;
147 
148 struct mips_cache_ops mips_cache_ops;
149 
150 #ifdef MIPS1
151 #ifdef ENABLE_MIPS_TX3900
152 #include <mips/cache_tx39.h>
153 void	tx3900_get_cache_config(void);
154 void	tx3920_get_cache_config(void);
155 void	tx39_cache_config_write_through(void);
156 #endif /* ENABLE_MIPS_TX3900 */
157 #endif /* MIPS1 */
158 
159 #if defined(MIPS3) || defined(MIPS4)
160 #ifdef MIPS3_5900
161 #include <mips/cache_r5900.h>
162 #endif /* MIPS3_5900 */
163 void	mips3_get_cache_config(int);
164 #endif /* MIPS3 || MIPS4 */
165 
166 #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4)
167 static void mips_config_cache_prehistoric(void);
168 #endif
169 #if defined(MIPS32) || defined(MIPS64)
170 static void mips_config_cache_modern(void);
171 #endif
172 
173 /*
174  * mips_dcache_compute_align:
175  *
176  *	Compute the D-cache alignment values.
177  */
178 void
179 mips_dcache_compute_align(void)
180 {
181 	int align;
182 
183 	align = mips_pdcache_line_size;
184 
185 	if (mips_sdcache_line_size > align)
186 		align = mips_sdcache_line_size;
187 
188 	if (mips_tcache_line_size > align)
189 		align = mips_tcache_line_size;
190 
191 	mips_dcache_align = align;
192 	mips_dcache_align_mask = align - 1;
193 }
194 
195 /*
196  * mips_config_cache:
197  *
198  *	Configure the cache for the system.
199  *
200  *	XXX DOES NOT HANDLE SPLIT SECONDARY CACHES.
201  */
202 void
203 mips_config_cache(void)
204 {
205 
206 #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4)
207 	if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC)
208 		mips_config_cache_prehistoric();
209 #endif
210 #if defined(MIPS32) || defined(MIPS64)
211 	if (MIPS_PRID_CID(cpu_id) != MIPS_PRID_CID_PREHISTORIC)
212 		mips_config_cache_modern();
213 #endif
214 
215 #ifdef DIAGNOSTIC
216 	/* Check that all cache ops are set up. */
217 	if (mips_picache_size || 1) {	/* XXX- must have primary Icache */
218 		if (!mips_cache_ops.mco_icache_sync_all)
219 			panic("no icache_sync_all cache op");
220 		if (!mips_cache_ops.mco_icache_sync_range)
221 			panic("no icache_sync_range cache op");
222 		if (!mips_cache_ops.mco_icache_sync_range_index)
223 			panic("no icache_sync_range_index cache op");
224 	}
225 	if (mips_pdcache_size || 1) {	/* XXX- must have primary Icache */
226 		if (!mips_cache_ops.mco_pdcache_wbinv_all)
227 			panic("no pdcache_wbinv_all");
228 		if (!mips_cache_ops.mco_pdcache_wbinv_range)
229 			panic("no pdcache_wbinv_range");
230 		if (!mips_cache_ops.mco_pdcache_wbinv_range_index)
231 			panic("no pdcache_wbinv_range_index");
232 		if (!mips_cache_ops.mco_pdcache_inv_range)
233 			panic("no pdcache_inv_range");
234 		if (!mips_cache_ops.mco_pdcache_wb_range)
235 			panic("no pdcache_wb_range");
236 	}
237 	if (mips_sdcache_size) {
238 		if (!mips_cache_ops.mco_sdcache_wbinv_all)
239 			panic("no sdcache_wbinv_all");
240 		if (!mips_cache_ops.mco_sdcache_wbinv_range)
241 			panic("no sdcache_wbinv_range");
242 		if (!mips_cache_ops.mco_sdcache_wbinv_range_index)
243 			panic("no sdcache_wbinv_range_index");
244 		if (!mips_cache_ops.mco_sdcache_inv_range)
245 			panic("no sdcache_inv_range");
246 		if (!mips_cache_ops.mco_sdcache_wb_range)
247 			panic("no sdcache_wb_range");
248 	}
249 #endif /* DIAGNOSTIC */
250 }
251 
252 #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4)
253 /*
254  *	XXX DOES NOT HANDLE SPLIT SECONDARY CACHES.
255  */
256 void
257 mips_config_cache_prehistoric(void)
258 {
259 #if defined(MIPS3) || defined(MIPS4)
260 	int csizebase = MIPS3_CONFIG_C_DEFBASE;
261 #endif
262 
263 	KASSERT(PAGE_SIZE != 0);
264 
265 	/*
266 	 * Configure primary caches.
267 	 */
268 	switch (MIPS_PRID_IMPL(cpu_id)) {
269 #ifdef MIPS1
270 	case MIPS_R2000:
271 	case MIPS_R3000:
272 		mips_picache_size = r3k_picache_size();
273 		mips_pdcache_size = r3k_pdcache_size();
274 
275 		mips_picache_line_size = 4;
276 		mips_pdcache_line_size = 4;
277 
278 		mips_picache_ways = 1;
279 		mips_pdcache_ways = 1;
280 
281 		mips_pdcache_write_through = 1;
282 
283 		mips_cache_ops.mco_icache_sync_all =
284 		    r3k_icache_sync_all;
285 		mips_cache_ops.mco_icache_sync_range =
286 		    r3k_icache_sync_range;
287 		mips_cache_ops.mco_icache_sync_range_index =
288 		    mips_cache_ops.mco_icache_sync_range;
289 
290 		mips_cache_ops.mco_pdcache_wbinv_all =
291 		    r3k_pdcache_wbinv_all;
292 		mips_cache_ops.mco_pdcache_wbinv_range =
293 		    r3k_pdcache_inv_range;
294 		mips_cache_ops.mco_pdcache_wbinv_range_index =
295 		    mips_cache_ops.mco_pdcache_wbinv_range;
296 		mips_cache_ops.mco_pdcache_inv_range =
297 		    r3k_pdcache_inv_range;
298 		mips_cache_ops.mco_pdcache_wb_range =
299 		    r3k_pdcache_wb_range;
300 
301 		uvmexp.ncolors = atop(mips_pdcache_size);
302 		break;
303 
304 #ifdef ENABLE_MIPS_TX3900
305 	case MIPS_TX3900:
306 		switch (MIPS_PRID_REV_MAJ(cpu_id)) {
307 		case 1:		/* TX3912 */
308 			mips_picache_ways = 1;
309 			mips_picache_line_size = 16;
310 			mips_pdcache_line_size = 4;
311 
312 			tx3900_get_cache_config();
313 
314 			mips_pdcache_write_through = 1;
315 
316 			mips_cache_ops.mco_icache_sync_all =
317 			    tx3900_icache_sync_all_16;
318 			mips_cache_ops.mco_icache_sync_range =
319 			    tx3900_icache_sync_range_16;
320 			mips_cache_ops.mco_icache_sync_range_index =
321 			    tx3900_icache_sync_range_16;
322 
323 			mips_cache_ops.mco_pdcache_wbinv_all =
324 			    tx3900_pdcache_wbinv_all_4;
325 			mips_cache_ops.mco_pdcache_wbinv_range =
326 			    tx3900_pdcache_inv_range_4;
327 			mips_cache_ops.mco_pdcache_wbinv_range_index =
328 			    tx3900_pdcache_inv_range_4;
329 			mips_cache_ops.mco_pdcache_inv_range =
330 			    tx3900_pdcache_inv_range_4;
331 			mips_cache_ops.mco_pdcache_wb_range =
332 			    tx3900_pdcache_wb_range_4;
333 			break;
334 
335 		case 3:		/* TX3922 */
336 			mips_picache_ways = 2;
337 			mips_picache_line_size = 16;
338 			mips_pdcache_line_size = 16;
339 
340 			tx3920_get_cache_config();
341 
342 			mips_cache_ops.mco_icache_sync_all =
343 			    mips_pdcache_write_through ?
344 			    tx3900_icache_sync_all_16 :
345 			    tx3920_icache_sync_all_16wb;
346 			mips_cache_ops.mco_icache_sync_range =
347 			    mips_pdcache_write_through ?
348 			    tx3920_icache_sync_range_16wt :
349 			    tx3920_icache_sync_range_16wb;
350 			mips_cache_ops.mco_icache_sync_range_index =
351 			    mips_cache_ops.mco_icache_sync_range;
352 
353 			mips_cache_ops.mco_pdcache_wbinv_all =
354 			    mips_pdcache_write_through ?
355 			    tx3920_pdcache_wbinv_all_16wt :
356 			    tx3920_pdcache_wbinv_all_16wb;
357 			mips_cache_ops.mco_pdcache_wbinv_range =
358 			    mips_pdcache_write_through ?
359 			    tx3920_pdcache_inv_range_16 :
360 			    tx3920_pdcache_wbinv_range_16wb;
361 			mips_cache_ops.mco_pdcache_wbinv_range_index =
362 			    mips_cache_ops.mco_pdcache_wbinv_range;
363 			mips_cache_ops.mco_pdcache_inv_range =
364 			    tx3920_pdcache_inv_range_16;
365 			mips_cache_ops.mco_pdcache_wb_range =
366 			    mips_pdcache_write_through ?
367 			    tx3920_pdcache_wb_range_16wt :
368 			    tx3920_pdcache_wb_range_16wb;
369 			break;
370 
371 		default:
372 			panic("mips_config_cache: unsupported TX3900");
373 		}
374 
375 		mips_pdcache_ways = 2;
376 		tx3900_get_cache_config();
377 		/* change to write-through mode */
378 		tx39_cache_config_write_through();
379 
380 		uvmexp.ncolors = atop(mips_pdcache_size) / mips_pdcache_ways;
381 		break;
382 #endif /* ENABLE_MIPS_TX3900 */
383 #endif /* MIPS1 */
384 
385 #if defined(MIPS3) || defined(MIPS4)
386 	case MIPS_R4100:
387 		/*
388 		 * R4100 (NEC VR series) revision number means:
389 		 *
390 		 *		MIPS_PRID_REV_MAJ	MIPS_PRID_REV_MIN
391 		 * VR4102	4			?
392 		 * VR4111	5			?
393 		 * VR4181	5			?
394 		 * VR4121	6			?
395 		 * VR4122	7			0 or 1
396 		 * VR4181A	7			3 <
397 		 * VR4131	8			?
398 		 */
399 		/* Vr4131 has R4600 style 2-way set-associative cache */
400 		if (MIPS_PRID_REV_MAJ(cpu_id) == 8)
401 			goto primary_cache_is_2way;
402 		/* FALLTHROUGH */
403 
404 	case MIPS_R4000:
405 	case MIPS_R4300:
406 		mips_picache_ways = 1;
407 		mips_pdcache_ways = 1;
408 		mips_sdcache_ways = 1;
409 
410 		mips3_get_cache_config(csizebase);
411 
412 		switch (mips_picache_line_size) {
413 		case 16:
414 			mips_cache_ops.mco_icache_sync_all =
415 			    r4k_icache_sync_all_16;
416 			mips_cache_ops.mco_icache_sync_range =
417 			    r4k_icache_sync_range_16;
418 			mips_cache_ops.mco_icache_sync_range_index =
419 			    r4k_icache_sync_range_index_16;
420 			break;
421 
422 		case 32:
423 			mips_cache_ops.mco_icache_sync_all =
424 			    r4k_icache_sync_all_32;
425 			mips_cache_ops.mco_icache_sync_range =
426 			    r4k_icache_sync_range_32;
427 			mips_cache_ops.mco_icache_sync_range_index =
428 			    r4k_icache_sync_range_index_32;
429 			break;
430 
431 		default:
432 			panic("r4k picache line size %d",
433 			    mips_picache_line_size);
434 		}
435 
436 		switch (mips_pdcache_line_size) {
437 		case 16:
438 			mips_cache_ops.mco_pdcache_wbinv_all =
439 			    r4k_pdcache_wbinv_all_16;
440 			mips_cache_ops.mco_pdcache_wbinv_range =
441 			    r4k_pdcache_wbinv_range_16;
442 			mips_cache_ops.mco_pdcache_wbinv_range_index =
443 			    r4k_pdcache_wbinv_range_index_16;
444 			mips_cache_ops.mco_pdcache_inv_range =
445 			    r4k_pdcache_inv_range_16;
446 			mips_cache_ops.mco_pdcache_wb_range =
447 			    r4k_pdcache_wb_range_16;
448 			break;
449 
450 		case 32:
451 			mips_cache_ops.mco_pdcache_wbinv_all =
452 			    r4k_pdcache_wbinv_all_32;
453 			mips_cache_ops.mco_pdcache_wbinv_range =
454 			    r4k_pdcache_wbinv_range_32;
455 			mips_cache_ops.mco_pdcache_wbinv_range_index =
456 			    r4k_pdcache_wbinv_range_index_32;
457 			mips_cache_ops.mco_pdcache_inv_range =
458 			    r4k_pdcache_inv_range_32;
459 			mips_cache_ops.mco_pdcache_wb_range =
460 			    r4k_pdcache_wb_range_32;
461 			break;
462 
463 		default:
464 			panic("r4k pdcache line size %d",
465 			    mips_pdcache_line_size);
466 		}
467 
468 		/* Virtually-indexed cache; no use for colors. */
469 		break;
470 
471 	case MIPS_R4600:
472 #ifdef ENABLE_MIPS_R4700
473 	case MIPS_R4700:
474 #endif
475 #ifndef ENABLE_MIPS_R3NKK
476 	case MIPS_R5000:
477 #endif
478 	case MIPS_RM5200:
479 primary_cache_is_2way:
480 		mips_picache_ways = 2;
481 		mips_pdcache_ways = 2;
482 
483 		mips3_get_cache_config(csizebase);
484 
485 		switch (mips_picache_line_size) {
486 		case 32:
487 			mips_cache_ops.mco_icache_sync_all =
488 			    r5k_icache_sync_all_32;
489 			mips_cache_ops.mco_icache_sync_range =
490 			    r5k_icache_sync_range_32;
491 			mips_cache_ops.mco_icache_sync_range_index =
492 			    r5k_icache_sync_range_index_32;
493 			break;
494 
495 		default:
496 			panic("r5k picache line size %d",
497 			    mips_picache_line_size);
498 		}
499 
500 		switch (mips_pdcache_line_size) {
501 		case 16:
502 			mips_cache_ops.mco_pdcache_wbinv_all =
503 			    r5k_pdcache_wbinv_all_16;
504 			mips_cache_ops.mco_pdcache_wbinv_range =
505 			    r5k_pdcache_wbinv_range_16;
506 			mips_cache_ops.mco_pdcache_wbinv_range_index =
507 			    r5k_pdcache_wbinv_range_index_16;
508 			mips_cache_ops.mco_pdcache_inv_range =
509 			    r5k_pdcache_inv_range_16;
510 			mips_cache_ops.mco_pdcache_wb_range =
511 			    r5k_pdcache_wb_range_16;
512 			break;
513 
514 		case 32:
515 			mips_cache_ops.mco_pdcache_wbinv_all =
516 			    r5k_pdcache_wbinv_all_32;
517 			mips_cache_ops.mco_pdcache_wbinv_range =
518 			    r5k_pdcache_wbinv_range_32;
519 			mips_cache_ops.mco_pdcache_wbinv_range_index =
520 			    r5k_pdcache_wbinv_range_index_32;
521 			mips_cache_ops.mco_pdcache_inv_range =
522 			    r5k_pdcache_inv_range_32;
523 			mips_cache_ops.mco_pdcache_wb_range =
524 			    r5k_pdcache_wb_range_32;
525 			break;
526 
527 		default:
528 			panic("r5k pdcache line size %d",
529 			    mips_pdcache_line_size);
530 		}
531 
532 		/*
533 		 * Deal with R4600 chip bugs.
534 		 */
535 		if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4600 &&
536 		    MIPS_PRID_REV_MAJ(cpu_id) == 1) {
537 			KASSERT(mips_pdcache_line_size == 32);
538 			mips_cache_ops.mco_pdcache_wbinv_range =
539 			    r4600v1_pdcache_wbinv_range_32;
540 			mips_cache_ops.mco_pdcache_inv_range =
541 			    r4600v1_pdcache_inv_range_32;
542 			mips_cache_ops.mco_pdcache_wb_range =
543 			    r4600v1_pdcache_wb_range_32;
544 		} else if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4600 &&
545 			   MIPS_PRID_REV_MAJ(cpu_id) == 2) {
546 			KASSERT(mips_pdcache_line_size == 32);
547 			mips_cache_ops.mco_pdcache_wbinv_range =
548 			    r4600v2_pdcache_wbinv_range_32;
549 			mips_cache_ops.mco_pdcache_inv_range =
550 			    r4600v2_pdcache_inv_range_32;
551 			mips_cache_ops.mco_pdcache_wb_range =
552 			    r4600v2_pdcache_wb_range_32;
553 		}
554 
555 		/*
556 		 * Deal with VR4131 chip bugs.
557 		 */
558 		if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4100 &&
559 		    MIPS_PRID_REV_MAJ(cpu_id) == 8) {
560 			KASSERT(mips_pdcache_line_size == 16);
561 			mips_cache_ops.mco_pdcache_wbinv_range =
562 			    vr4131v1_pdcache_wbinv_range_16;
563 		}
564 
565 		/* Virtually-indexed cache; no use for colors. */
566 		break;
567 #ifdef MIPS3_5900
568 	case MIPS_R5900:
569 		/* cache spec */
570 		mips_picache_ways = 2;
571 		mips_pdcache_ways = 2;
572 		mips_picache_size = CACHE_R5900_SIZE_I;
573 		mips_picache_line_size = CACHE_R5900_LSIZE_I;
574 		mips_pdcache_size = CACHE_R5900_SIZE_D;
575 		mips_pdcache_line_size = CACHE_R5900_LSIZE_D;
576 		mips_cache_alias_mask =
577 		    ((mips_pdcache_size / mips_pdcache_ways) - 1) &
578 		    ~(PAGE_SIZE - 1);
579 		mips_cache_prefer_mask =
580 		    max(mips_pdcache_size, mips_picache_size) - 1;
581 		/* cache ops */
582 		mips_cache_ops.mco_icache_sync_all =
583 		    r5900_icache_sync_all_64;
584 		mips_cache_ops.mco_icache_sync_range =
585 		    r5900_icache_sync_range_64;
586 		mips_cache_ops.mco_icache_sync_range_index =
587 		    r5900_icache_sync_range_index_64;
588 		mips_cache_ops.mco_pdcache_wbinv_all =
589 		    r5900_pdcache_wbinv_all_64;
590 		mips_cache_ops.mco_pdcache_wbinv_range =
591 		    r5900_pdcache_wbinv_range_64;
592 		mips_cache_ops.mco_pdcache_wbinv_range_index =
593 		    r5900_pdcache_wbinv_range_index_64;
594 		mips_cache_ops.mco_pdcache_inv_range =
595 		    r5900_pdcache_inv_range_64;
596 		mips_cache_ops.mco_pdcache_wb_range =
597 		    r5900_pdcache_wb_range_64;
598 		break;
599 #endif /* MIPS3_5900 */
600 #endif /* MIPS3 || MIPS4 */
601 
602 	default:
603 		panic("can't handle primary cache on impl 0x%x\n",
604 		    MIPS_PRID_IMPL(cpu_id));
605 	}
606 
607 	/*
608 	 * Compute the "way mask" for each cache.
609 	 */
610 	if (mips_picache_size) {
611 		KASSERT(mips_picache_ways != 0);
612 		mips_picache_way_size = (mips_picache_size / mips_picache_ways);
613 		mips_picache_way_mask = mips_picache_way_size - 1;
614 	}
615 	if (mips_pdcache_size) {
616 		KASSERT(mips_pdcache_ways != 0);
617 		mips_pdcache_way_size = (mips_pdcache_size / mips_pdcache_ways);
618 		mips_pdcache_way_mask = mips_pdcache_way_size - 1;
619 	}
620 
621 	mips_dcache_compute_align();
622 
623 	if (mips_sdcache_line_size == 0)
624 		return;
625 
626 	/*
627 	 * Configure the secondary cache.
628 	 */
629 	switch (MIPS_PRID_IMPL(cpu_id)) {
630 #if defined(MIPS3) || defined(MIPS4)
631 	case MIPS_R4000:
632 		/*
633 		 * R4000/R4400 always detects virtual alias as if
634 		 * primary cache size is 32KB. Actual primary cache size
635 		 * is ignored wrt VCED/VCEI.
636 		 */
637 		mips_cache_alias_mask =
638 			(MIPS3_MAX_PCACHE_SIZE - 1) & ~(PAGE_SIZE - 1);
639 		mips_cache_prefer_mask = MIPS3_MAX_PCACHE_SIZE - 1;
640 		/* FALLTHROUGH */
641 	case MIPS_R4100:
642 	case MIPS_R4300:
643 	case MIPS_R4600:
644 #ifdef ENABLE_MIPS_R4700
645 	case MIPS_R4700:
646 #endif
647 #ifndef ENABLE_MIPS_R3NKK
648 	case MIPS_R5000:
649 #endif
650 	case MIPS_RM5200:
651 		switch (mips_sdcache_ways) {
652 		case 1:
653 			switch (mips_sdcache_line_size) {
654 			case 32:
655 				mips_cache_ops.mco_sdcache_wbinv_all =
656 				    r4k_sdcache_wbinv_all_32;
657 				mips_cache_ops.mco_sdcache_wbinv_range =
658 				    r4k_sdcache_wbinv_range_32;
659 				mips_cache_ops.mco_sdcache_wbinv_range_index =
660 				    r4k_sdcache_wbinv_range_index_32;
661 				mips_cache_ops.mco_sdcache_inv_range =
662 				    r4k_sdcache_inv_range_32;
663 				mips_cache_ops.mco_sdcache_wb_range =
664 				    r4k_sdcache_wb_range_32;
665 				break;
666 
667 			case 16:
668 			case 64:
669 				mips_cache_ops.mco_sdcache_wbinv_all =
670 				    r4k_sdcache_wbinv_all_generic;
671 				mips_cache_ops.mco_sdcache_wbinv_range =
672 				    r4k_sdcache_wbinv_range_generic;
673 				mips_cache_ops.mco_sdcache_wbinv_range_index =
674 				    r4k_sdcache_wbinv_range_index_generic;
675 				mips_cache_ops.mco_sdcache_inv_range =
676 				    r4k_sdcache_inv_range_generic;
677 				mips_cache_ops.mco_sdcache_wb_range =
678 				    r4k_sdcache_wb_range_generic;
679 				break;
680 
681 			case 128:
682 				mips_cache_ops.mco_sdcache_wbinv_all =
683 				    r4k_sdcache_wbinv_all_128;
684 				mips_cache_ops.mco_sdcache_wbinv_range =
685 				    r4k_sdcache_wbinv_range_128;
686 				mips_cache_ops.mco_sdcache_wbinv_range_index =
687 				    r4k_sdcache_wbinv_range_index_128;
688 				mips_cache_ops.mco_sdcache_inv_range =
689 				    r4k_sdcache_inv_range_128;
690 				mips_cache_ops.mco_sdcache_wb_range =
691 				    r4k_sdcache_wb_range_128;
692 				break;
693 
694 			default:
695 				panic("r4k sdcache %d way line size %d\n",
696 				    mips_sdcache_ways, mips_sdcache_line_size);
697 			}
698 			break;
699 
700 		default:
701 			panic("r4k sdcache %d way line size %d\n",
702 			    mips_sdcache_ways, mips_sdcache_line_size);
703 		}
704 		break;
705 #endif /* MIPS3 || MIPS4 */
706 
707 	default:
708 		panic("can't handle secondary cache on impl 0x%x\n",
709 		    MIPS_PRID_IMPL(cpu_id));
710 	}
711 
712 	/*
713 	 * Compute the "way mask" for each secondary cache.
714 	 */
715 	if (mips_sdcache_size) {
716 		KASSERT(mips_sdcache_ways != 0);
717 		mips_sdcache_way_size = (mips_sdcache_size / mips_sdcache_ways);
718 		mips_sdcache_way_mask = mips_sdcache_way_size - 1;
719 	}
720 
721 	mips_dcache_compute_align();
722 }
723 
724 #ifdef MIPS1
725 #ifdef ENABLE_MIPS_TX3900
726 /*
727  * tx3900_get_cache_config:
728  *
729  *	Fetch cache size information for the TX3900.
730  */
731 void
732 tx3900_get_cache_config(void)
733 {
734 	uint32_t config;
735 
736 	config = tx3900_cp0_config_read();
737 
738 	mips_picache_size = R3900_C_SIZE_MIN <<
739 	    ((config & R3900_CONFIG_ICS_MASK) >> R3900_CONFIG_ICS_SHIFT);
740 
741 	mips_pdcache_size = R3900_C_SIZE_MIN <<
742 	    ((config & R3900_CONFIG_DCS_MASK) >> R3900_CONFIG_DCS_SHIFT);
743 }
744 
745 /*
746  * tx3920_get_cache_config:
747  *
748  *	Fetch cache size information for the TX3920.
749  */
750 void
751 tx3920_get_cache_config(void)
752 {
753 
754 	/* Size is the same as TX3900. */
755 	tx3900_get_cache_config();
756 
757 	/* Now determine write-through/write-back mode. */
758 	if ((tx3900_cp0_config_read() & R3900_CONFIG_WBON) == 0)
759 		mips_pdcache_write_through = 1;
760 }
761 
762 /*
763  * tx39_cache_config_write_through:
764  *
765  *	TX3922 write-through D-cache mode.
766  *	for TX3912, no meaning. (no write-back mode)
767  */
768 void
769 tx39_cache_config_write_through(void)
770 {
771 	u_int32_t r;
772 
773 	mips_dcache_wbinv_all();
774 
775 	__asm__ __volatile__("mfc0 %0, $3" : "=r"(r));
776 	r &= 0xffffdfff;
777 	__asm__ __volatile__("mtc0 %0, $3" : : "r"(r));
778 }
779 
780 #endif /* ENABLE_MIPS_TX3900 */
781 #endif /* MIPS1 */
782 
783 #if defined(MIPS3) || defined(MIPS4)
784 /*
785  * mips3_get_cache_config:
786  *
787  *	Fetch the cache config information for a MIPS-3 or MIPS-4
788  *	processor (virtually-indexed cache).
789  *
790  *	NOTE: Fetching the size of the secondary cache is something
791  *	that platform specific code has to do.  We'd appreciate it
792  *	if they initialized the size before now.
793  *
794  *	ALSO NOTE: The number of ways in the cache must already be
795  *	initialized.
796  */
797 void
798 mips3_get_cache_config(int csizebase)
799 {
800 	uint32_t config = mips3_cp0_config_read();
801 
802 	mips_picache_size = MIPS3_CONFIG_CACHE_SIZE(config,
803 	    MIPS3_CONFIG_IC_MASK, csizebase, MIPS3_CONFIG_IC_SHIFT);
804 	mips_picache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config,
805 	    MIPS3_CONFIG_IB);
806 
807 	mips_pdcache_size = MIPS3_CONFIG_CACHE_SIZE(config,
808 	    MIPS3_CONFIG_DC_MASK, csizebase, MIPS3_CONFIG_DC_SHIFT);
809 	mips_pdcache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config,
810 	    MIPS3_CONFIG_DB);
811 
812 	mips_cache_alias_mask =
813 	    ((mips_pdcache_size / mips_pdcache_ways) - 1) & ~(PAGE_SIZE - 1);
814 	mips_cache_prefer_mask =
815 	    max(mips_pdcache_size, mips_picache_size) - 1;
816 
817 	if ((config & MIPS3_CONFIG_SC) == 0) {
818 		mips_sdcache_line_size = MIPS3_CONFIG_CACHE_L2_LSIZE(config);
819 		if ((config & MIPS3_CONFIG_SS) == 0)
820 			mips_scache_unified = 1;
821 	}
822 }
823 #endif /* MIPS3 || MIPS4 */
824 #endif /* MIPS1 || MIPS3 || MIPS4 */
825 
826 #if defined(MIPS32) || defined(MIPS64)
827 
828 #ifdef MIPS_DISABLE_L1_CACHE
829 static void cache_noop(void);
830 static void cache_noop(void) {}
831 #endif
832 
833 static void
834 mips_config_cache_modern(void)
835 {
836 	/* MIPS32/MIPS64, use coprocessor 0 config registers */
837 	uint32_t cfg, cfg1;
838 
839 	cfg = mips3_cp0_config_read();
840 	cfg1 = mipsNN_cp0_config1_read();
841 
842 #ifdef MIPS_DISABLE_L1_CACHE
843 	cfg1 &= ~MIPSNN_CFG1_IL_MASK;
844 	cfg1 &= ~MIPSNN_CFG1_DL_MASK;
845 	mipsNN_cp0_config1_write(cfg1);
846 #endif
847 
848 	/* figure out Dcache params. */
849 	switch (MIPSNN_GET(CFG1_DL, cfg1)) {
850 	case MIPSNN_CFG1_DL_NONE:
851 		mips_pdcache_line_size = mips_pdcache_way_size =
852 		    mips_pdcache_ways = 0;
853 		break;
854 	case MIPSNN_CFG1_DL_RSVD:
855 		panic("reserved MIPS32/64 Dcache line size");
856 		break;
857 	default:
858 		if (MIPSNN_GET(CFG1_DS, cfg1) == MIPSNN_CFG1_DS_RSVD)
859 			panic("reserved MIPS32/64 Dcache sets per way");
860 		mips_pdcache_line_size = MIPSNN_CFG1_DL(cfg1);
861 		mips_pdcache_way_size =
862 		    mips_pdcache_line_size * MIPSNN_CFG1_DS(cfg1);
863 		mips_pdcache_ways = MIPSNN_CFG1_DA(cfg1) + 1;
864 
865 		/*
866 		 * Compute the total size and "way mask" for the
867 		 * primary Icache.
868 		 */
869 		mips_pdcache_size =
870 		    mips_pdcache_way_size * mips_pdcache_ways;
871 		mips_pdcache_way_mask = mips_pdcache_way_size - 1;
872 		break;
873 	}
874 
875 	/* figure out Icache params. */
876 	switch (MIPSNN_GET(CFG1_IL, cfg1)) {
877 	case MIPSNN_CFG1_IL_NONE:
878 		mips_picache_line_size = mips_picache_way_size =
879 		    mips_picache_ways = 0;
880 		break;
881 	case MIPSNN_CFG1_IL_RSVD:
882 		panic("reserved MIPS32/64 Icache line size");
883 		break;
884 	default:
885 		if (MIPSNN_GET(CFG1_IS, cfg1) == MIPSNN_CFG1_IS_RSVD)
886 			panic("reserved MIPS32/64 Icache sets per way");
887 		mips_picache_line_size = MIPSNN_CFG1_IL(cfg1);
888 		mips_picache_way_size =
889 		    mips_picache_line_size * MIPSNN_CFG1_IS(cfg1);
890 		mips_picache_ways = MIPSNN_CFG1_IA(cfg1) + 1;
891 
892 		/*
893 		 * Compute the total size and "way mask" for the
894 		 * primary Dcache.
895 		 */
896 		mips_picache_size =
897 		    mips_picache_way_size * mips_picache_ways;
898 		mips_picache_way_mask = mips_picache_way_size - 1;
899 		break;
900 	}
901 
902 #define CACHE_DEBUG
903 #ifdef CACHE_DEBUG
904 	printf("MIPS32/64 params: cpu arch: %d\n", cpu_arch);
905 	printf("MIPS32/64 params: TLB entries: %d\n", mips_num_tlb_entries);
906 	if (mips_picache_line_size == 0)
907 		printf("MIPS32/64 params: no Icache\n");
908 	else {
909 		printf("MIPS32/64 params: Icache: line = %d, total = %d, "
910 		    "ways = %d\n", mips_picache_line_size,
911 		    mips_picache_way_size * mips_picache_ways,
912 		    mips_picache_ways);
913 		printf("\t\t sets = %d\n", (mips_picache_way_size *
914 		    mips_picache_ways / mips_picache_line_size) /
915 		    mips_picache_ways);
916 	}
917 	if (mips_pdcache_line_size == 0)
918 		printf("MIPS32/64 params: no Dcache\n");
919 	else {
920 		printf("MIPS32/64 params: Dcache: line = %d, total = %d, "
921 		    "ways = %d\n", mips_pdcache_line_size,
922 		    mips_pdcache_way_size * mips_pdcache_ways,
923 		    mips_pdcache_ways);
924 		printf("\t\t sets = %d\n", (mips_pdcache_way_size *
925 		    mips_pdcache_ways / mips_pdcache_line_size) /
926 		    mips_pdcache_ways);
927 	}
928 #endif /* CACHE_DEBUG */
929 
930 	switch (mips_picache_line_size) {
931 	case 16:
932 		mips_cache_ops.mco_icache_sync_all = mipsNN_icache_sync_all_16;
933 		mips_cache_ops.mco_icache_sync_range =
934 		    mipsNN_icache_sync_range_16;
935 		switch (mips_picache_ways) {
936 		case 2:
937 			mips_cache_ops.mco_icache_sync_range_index =
938 			    mipsNN_icache_sync_range_index_16_2way;
939 			break;
940 		case 4:
941 			mips_cache_ops.mco_icache_sync_range_index =
942 			    mipsNN_icache_sync_range_index_16_4way;
943 			break;
944 		default:
945 			panic("no %d-way Icache ops", mips_picache_ways);
946 		}
947 		break;
948 	case 32:
949 		mips_cache_ops.mco_icache_sync_all = mipsNN_icache_sync_all_32;
950 		mips_cache_ops.mco_icache_sync_range =
951 		    mipsNN_icache_sync_range_32;
952 		switch (mips_picache_ways) {
953 		case 2:
954 			mips_cache_ops.mco_icache_sync_range_index =
955 			    mipsNN_icache_sync_range_index_32_2way;
956 			break;
957 		case 4:
958 			mips_cache_ops.mco_icache_sync_range_index =
959 			    mipsNN_icache_sync_range_index_32_4way;
960 			break;
961 		default:
962 			panic("no %d-way Icache ops", mips_picache_ways);
963 		}
964 		break;
965 #ifdef MIPS_DISABLE_L1_CACHE
966 	case 0:
967 		mips_cache_ops.mco_icache_sync_all = (void *)cache_noop;
968 		mips_cache_ops.mco_icache_sync_range = (void *)cache_noop;
969 		mips_cache_ops.mco_icache_sync_range_index = (void *)cache_noop;
970 		break;
971 #endif
972 	default:
973 		panic("no Icache ops for %d byte lines",
974 		    mips_picache_line_size);
975 	}
976 
977 	switch (mips_pdcache_line_size) {
978 	case 16:
979 		mips_cache_ops.mco_pdcache_wbinv_all =
980 		    mipsNN_pdcache_wbinv_all_16;
981 		mips_cache_ops.mco_pdcache_wbinv_range =
982 		    mipsNN_pdcache_wbinv_range_16;
983 		switch (mips_pdcache_ways) {
984 		case 2:
985 			mips_cache_ops.mco_pdcache_wbinv_range_index =
986 			    mipsNN_pdcache_wbinv_range_index_16_2way;
987 			break;
988 		case 4:
989 			mips_cache_ops.mco_pdcache_wbinv_range_index =
990 			    mipsNN_pdcache_wbinv_range_index_16_4way;
991 			break;
992 		default:
993 			panic("no %d-way Dcache ops", mips_pdcache_ways);
994 		}
995 		mips_cache_ops.mco_pdcache_inv_range =
996 		    mipsNN_pdcache_inv_range_16;
997 		mips_cache_ops.mco_pdcache_wb_range =
998 		    mipsNN_pdcache_wb_range_16;
999 		break;
1000 	case 32:
1001 		mips_cache_ops.mco_pdcache_wbinv_all =
1002 		    mipsNN_pdcache_wbinv_all_32;
1003 		mips_cache_ops.mco_pdcache_wbinv_range =
1004 		    mipsNN_pdcache_wbinv_range_32;
1005 		switch (mips_pdcache_ways) {
1006 		case 2:
1007 			mips_cache_ops.mco_pdcache_wbinv_range_index =
1008 			    mipsNN_pdcache_wbinv_range_index_32_2way;
1009 			break;
1010 		case 4:
1011 			mips_cache_ops.mco_pdcache_wbinv_range_index =
1012 			    mipsNN_pdcache_wbinv_range_index_32_4way;
1013 			break;
1014 		default:
1015 			panic("no %d-way Dcache ops", mips_pdcache_ways);
1016 		}
1017 		mips_cache_ops.mco_pdcache_inv_range =
1018 		    mipsNN_pdcache_inv_range_32;
1019 		mips_cache_ops.mco_pdcache_wb_range =
1020 		    mipsNN_pdcache_wb_range_32;
1021 		break;
1022 #ifdef MIPS_DISABLE_L1_CACHE
1023 	case 0:
1024 		mips_cache_ops.mco_pdcache_wbinv_all = (void *)cache_noop;
1025 		mips_cache_ops.mco_pdcache_wbinv_range = (void *)cache_noop;
1026 		mips_cache_ops.mco_pdcache_wbinv_range_index =
1027 		    (void *)cache_noop;
1028 		mips_cache_ops.mco_pdcache_inv_range = (void *)cache_noop;
1029 		mips_cache_ops.mco_pdcache_wb_range = (void *)cache_noop;
1030 		break;
1031 #endif
1032 	default:
1033 		panic("no Dcache ops for %d byte lines",
1034 		    mips_pdcache_line_size);
1035 	}
1036 }
1037 #endif /* MIPS32 || MIPS64 */
1038