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