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