Annotation of src/sys/arch/mips/mips/cache.c, Revision 1.48.26.3
1.48.26.3! skrll 1: /* $NetBSD: cache.c,v 1.48.26.2 2015/09/22 12:05:47 skrll 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.48.26.3! skrll 71: __KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.48.26.2 2015/09/22 12:05:47 skrll 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:
1.46 matt 98: #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
1.10 simonb 99: #include <mips/mipsNN.h> /* MIPS32/MIPS64 registers */
100: #include <mips/cache_mipsNN.h>
1.48.26.1 skrll 101: #ifdef MIPS64_OCTEON
102: #include <mips/cache_octeon.h>
103: #endif
1.2 thorpej 104: #endif
105:
106: #ifdef MIPS1
107: #ifdef ENABLE_MIPS_TX3900
108: #include <mips/cache_tx39.h>
109: void tx3900_get_cache_config(void);
110: void tx3920_get_cache_config(void);
1.9 uch 111: void tx39_cache_config_write_through(void);
1.2 thorpej 112: #endif /* ENABLE_MIPS_TX3900 */
113: #endif /* MIPS1 */
114:
1.10 simonb 115: #if defined(MIPS3) || defined(MIPS4)
116: void mips3_get_cache_config(int);
1.21 tsutsui 117: #ifdef ENABLE_MIPS4_CACHE_R10K
118: void mips4_get_cache_config(int);
119: #endif /* ENABLE_MIPS4_CACHE_R10K */
1.10 simonb 120: #endif /* MIPS3 || MIPS4 */
1.2 thorpej 121:
1.10 simonb 122: #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4)
123: static void mips_config_cache_prehistoric(void);
1.43 pooka 124: static void mips_config_cache_emips(void);
1.10 simonb 125: #endif
1.46 matt 126: #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
1.48 matt 127: static void mips_config_cache_modern(uint32_t);
1.10 simonb 128: #endif
1.2 thorpej 129:
1.48.26.3! skrll 130: #if (MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS64 + MIPS32R2 + MIPS64R2) > 0
1.43 pooka 131: /* no-cache definition */
132: static void no_cache_op(void);
1.48.26.3! skrll 133: static void no_cache_op_range(register_t va, vsize_t size);
! 134: static void no_cache_op_range_index(vaddr_t va, vsize_t size);
1.43 pooka 135:
136: /* no-cache implementation */
137: static void no_cache_op(void) {}
1.48.26.3! skrll 138: static void no_cache_op_range(register_t va, vsize_t size) {}
! 139: static void no_cache_op_range_index(vaddr_t va, vsize_t size) {}
1.44 uebayasi 140: #endif
1.43 pooka 141:
1.48.26.3! skrll 142: struct mips_cache_info mips_cache_info;
! 143: struct mips_cache_ops mips_cache_ops = {
! 144: .mco_intern_icache_sync_range_index = no_cache_op_range_index,
! 145: .mco_intern_icache_sync_range = no_cache_op_range,
! 146: .mco_intern_pdcache_sync_all= no_cache_op,
! 147: .mco_intern_pdcache_sync_range_index = no_cache_op_range_index,
! 148: .mco_intern_pdcache_sync_range = no_cache_op_range,
! 149: .mco_intern_pdcache_wbinv_range_index = no_cache_op_range_index,
! 150: .mco_intern_sdcache_sync_all= no_cache_op,
! 151: .mco_intern_sdcache_sync_range_index = no_cache_op_range_index,
! 152: .mco_intern_sdcache_sync_range = no_cache_op_range,
! 153: .mco_intern_sdcache_wbinv_range_index = no_cache_op_range_index,
! 154: };
! 155:
1.2 thorpej 156: /*
1.4 thorpej 157: * mips_dcache_compute_align:
158: *
159: * Compute the D-cache alignment values.
160: */
161: void
162: mips_dcache_compute_align(void)
163: {
1.45 matt 164: struct mips_cache_info * const mci = &mips_cache_info;
1.13 thorpej 165: u_int align;
1.4 thorpej 166:
1.45 matt 167: align = mci->mci_pdcache_line_size;
1.4 thorpej 168:
1.45 matt 169: if (mci->mci_sdcache_line_size > align)
170: align = mci->mci_sdcache_line_size;
1.4 thorpej 171:
1.45 matt 172: if (mci->mci_tcache_line_size > align)
173: align = mci->mci_tcache_line_size;
1.4 thorpej 174:
1.45 matt 175: mci->mci_dcache_align = align;
176: mci->mci_dcache_align_mask = align - 1;
1.4 thorpej 177: }
178:
179: /*
1.2 thorpej 180: * mips_config_cache:
181: *
182: * Configure the cache for the system.
183: *
184: * XXX DOES NOT HANDLE SPLIT SECONDARY CACHES.
185: */
186: void
187: mips_config_cache(void)
188: {
1.45 matt 189: #ifdef DIAGNOSTIC
190: struct mips_cache_info * const mci = &mips_cache_info;
191: struct mips_cache_ops * const mco = &mips_cache_ops;
192: #endif
193: const mips_prid_t cpu_id = mips_options.mips_cpu_id;
1.48.26.2 skrll 194:
1.10 simonb 195: #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4)
196: if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC)
197: mips_config_cache_prehistoric();
1.43 pooka 198: else if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_MICROSOFT)
199: mips_config_cache_emips();
1.10 simonb 200: #endif
1.46 matt 201: #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
1.10 simonb 202: if (MIPS_PRID_CID(cpu_id) != MIPS_PRID_CID_PREHISTORIC)
1.48 matt 203: mips_config_cache_modern(cpu_id);
1.10 simonb 204: #endif
205:
206: #ifdef DIAGNOSTIC
207: /* Check that all cache ops are set up. */
1.45 matt 208: if (mci->mci_picache_size || 1) { /* XXX- must have primary Icache */
209: if (!mco->mco_icache_sync_all)
1.10 simonb 210: panic("no icache_sync_all cache op");
1.45 matt 211: if (!mco->mco_icache_sync_range)
1.10 simonb 212: panic("no icache_sync_range cache op");
1.45 matt 213: if (!mco->mco_icache_sync_range_index)
1.10 simonb 214: panic("no icache_sync_range_index cache op");
215: }
1.46 matt 216: if (mci->mci_pdcache_size || 1) { /* XXX- must have primary Dcache */
1.45 matt 217: if (!mco->mco_pdcache_wbinv_all)
1.10 simonb 218: panic("no pdcache_wbinv_all");
1.45 matt 219: if (!mco->mco_pdcache_wbinv_range)
1.10 simonb 220: panic("no pdcache_wbinv_range");
1.45 matt 221: if (!mco->mco_pdcache_wbinv_range_index)
1.10 simonb 222: panic("no pdcache_wbinv_range_index");
1.45 matt 223: if (!mco->mco_pdcache_inv_range)
1.10 simonb 224: panic("no pdcache_inv_range");
1.45 matt 225: if (!mco->mco_pdcache_wb_range)
1.10 simonb 226: panic("no pdcache_wb_range");
227: }
1.45 matt 228: if (mci->mci_sdcache_size) {
229: if (!mco->mco_sdcache_wbinv_all)
1.10 simonb 230: panic("no sdcache_wbinv_all");
1.45 matt 231: if (!mco->mco_sdcache_wbinv_range)
1.10 simonb 232: panic("no sdcache_wbinv_range");
1.45 matt 233: if (!mco->mco_sdcache_wbinv_range_index)
1.10 simonb 234: panic("no sdcache_wbinv_range_index");
1.45 matt 235: if (!mco->mco_sdcache_inv_range)
1.10 simonb 236: panic("no sdcache_inv_range");
1.45 matt 237: if (!mco->mco_sdcache_wb_range)
1.10 simonb 238: panic("no sdcache_wb_range");
239: }
240: #endif /* DIAGNOSTIC */
241: }
242:
243: #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4)
244: /*
245: * XXX DOES NOT HANDLE SPLIT SECONDARY CACHES.
246: */
247: void
248: mips_config_cache_prehistoric(void)
249: {
1.45 matt 250: struct mips_cache_info * const mci = &mips_cache_info;
251: struct mips_cache_ops * const mco = &mips_cache_ops;
252: const mips_prid_t cpu_id = mips_options.mips_cpu_id;
1.10 simonb 253: #if defined(MIPS3) || defined(MIPS4)
1.2 thorpej 254: int csizebase = MIPS3_CONFIG_C_DEFBASE;
255: #endif
256:
257: KASSERT(PAGE_SIZE != 0);
258:
259: /*
260: * Configure primary caches.
261: */
262: switch (MIPS_PRID_IMPL(cpu_id)) {
263: #ifdef MIPS1
264: case MIPS_R2000:
265: case MIPS_R3000:
1.45 matt 266: mci->mci_picache_size = r3k_picache_size();
267: mci->mci_pdcache_size = r3k_pdcache_size();
1.2 thorpej 268:
1.45 matt 269: mci->mci_picache_line_size = 4;
270: mci->mci_pdcache_line_size = 4;
1.2 thorpej 271:
1.45 matt 272: mci->mci_picache_ways = 1;
273: mci->mci_pdcache_ways = 1;
1.2 thorpej 274:
1.45 matt 275: mci->mci_pdcache_write_through = true;
1.2 thorpej 276:
1.45 matt 277: mco->mco_icache_sync_all =
1.2 thorpej 278: r3k_icache_sync_all;
1.45 matt 279: mco->mco_icache_sync_range =
1.2 thorpej 280: r3k_icache_sync_range;
1.45 matt 281: mco->mco_icache_sync_range_index =
1.48.26.3! skrll 282: (void (*)(vaddr_t, vsize_t)) mco->mco_icache_sync_range;
1.2 thorpej 283:
1.45 matt 284: mco->mco_pdcache_wbinv_all =
1.2 thorpej 285: r3k_pdcache_wbinv_all;
1.45 matt 286: mco->mco_pdcache_wbinv_range =
1.2 thorpej 287: r3k_pdcache_inv_range;
1.45 matt 288: mco->mco_pdcache_wbinv_range_index =
1.48.26.3! skrll 289: (void (*)(vaddr_t, vsize_t)) mco->mco_pdcache_wbinv_range;
1.45 matt 290: mco->mco_pdcache_inv_range =
1.2 thorpej 291: r3k_pdcache_inv_range;
1.45 matt 292: mco->mco_pdcache_wb_range =
1.2 thorpej 293: r3k_pdcache_wb_range;
294:
1.45 matt 295: uvmexp.ncolors = atop(mci->mci_pdcache_size);
1.2 thorpej 296: break;
297:
298: #ifdef ENABLE_MIPS_TX3900
299: case MIPS_TX3900:
300: switch (MIPS_PRID_REV_MAJ(cpu_id)) {
301: case 1: /* TX3912 */
1.45 matt 302: mci->mci_picache_ways = 1;
303: mci->mci_picache_line_size = 16;
304: mci->mci_pdcache_line_size = 4;
1.2 thorpej 305:
306: tx3900_get_cache_config();
307:
1.45 matt 308: mci->mci_pdcache_write_through = true;
1.2 thorpej 309:
1.45 matt 310: mco->mco_icache_sync_all =
1.2 thorpej 311: tx3900_icache_sync_all_16;
1.45 matt 312: mco->mco_icache_sync_range =
1.2 thorpej 313: tx3900_icache_sync_range_16;
1.45 matt 314: mco->mco_icache_sync_range_index =
1.48.26.3! skrll 315: (void (*)(vaddr_t, vsize_t))
! 316: tx3900_icache_sync_range_16;
1.2 thorpej 317:
1.45 matt 318: mco->mco_pdcache_wbinv_all =
1.2 thorpej 319: tx3900_pdcache_wbinv_all_4;
1.45 matt 320: mco->mco_pdcache_wbinv_range =
1.2 thorpej 321: tx3900_pdcache_inv_range_4;
1.45 matt 322: mco->mco_pdcache_wbinv_range_index =
1.48.26.3! skrll 323: (void (*)(vaddr_t, vsize_t))
! 324: tx3900_pdcache_inv_range_4;
1.45 matt 325: mco->mco_pdcache_inv_range =
1.2 thorpej 326: tx3900_pdcache_inv_range_4;
1.45 matt 327: mco->mco_pdcache_wb_range =
1.2 thorpej 328: tx3900_pdcache_wb_range_4;
329: break;
330:
331: case 3: /* TX3922 */
1.45 matt 332: mci->mci_picache_ways = 2;
333: mci->mci_picache_line_size = 16;
334: mci->mci_pdcache_line_size = 16;
1.2 thorpej 335:
336: tx3920_get_cache_config();
337:
1.45 matt 338: mco->mco_icache_sync_all =
339: mci->mci_pdcache_write_through ?
1.2 thorpej 340: tx3900_icache_sync_all_16 :
341: tx3920_icache_sync_all_16wb;
1.45 matt 342: mco->mco_icache_sync_range =
343: mci->mci_pdcache_write_through ?
1.2 thorpej 344: tx3920_icache_sync_range_16wt :
345: tx3920_icache_sync_range_16wb;
1.45 matt 346: mco->mco_icache_sync_range_index =
1.48.26.3! skrll 347: (void (*)(vaddr_t, vsize_t))
! 348: mco->mco_icache_sync_range;
1.2 thorpej 349:
1.45 matt 350: mco->mco_pdcache_wbinv_all =
351: mci->mci_pdcache_write_through ?
1.2 thorpej 352: tx3920_pdcache_wbinv_all_16wt :
353: tx3920_pdcache_wbinv_all_16wb;
1.45 matt 354: mco->mco_pdcache_wbinv_range =
355: mci->mci_pdcache_write_through ?
1.2 thorpej 356: tx3920_pdcache_inv_range_16 :
357: tx3920_pdcache_wbinv_range_16wb;
1.45 matt 358: mco->mco_pdcache_wbinv_range_index =
1.48.26.3! skrll 359: (void (*)(vaddr_t, vsize_t))
! 360: mco->mco_pdcache_wbinv_range;
1.45 matt 361: mco->mco_pdcache_inv_range =
1.2 thorpej 362: tx3920_pdcache_inv_range_16;
1.45 matt 363: mco->mco_pdcache_wb_range =
364: mci->mci_pdcache_write_through ?
1.2 thorpej 365: tx3920_pdcache_wb_range_16wt :
366: tx3920_pdcache_wb_range_16wb;
367: break;
368:
369: default:
370: panic("mips_config_cache: unsupported TX3900");
371: }
372:
1.45 matt 373: mci->mci_pdcache_ways = 2;
1.2 thorpej 374: tx3900_get_cache_config();
1.9 uch 375: /* change to write-through mode */
376: tx39_cache_config_write_through();
1.2 thorpej 377:
1.45 matt 378: uvmexp.ncolors = atop(mci->mci_pdcache_size) / mci->mci_pdcache_ways;
1.2 thorpej 379: break;
380: #endif /* ENABLE_MIPS_TX3900 */
381: #endif /* MIPS1 */
382:
1.10 simonb 383: #if defined(MIPS3) || defined(MIPS4)
1.6 takemura 384: case MIPS_R4100:
1.29 tsutsui 385: if ((mips3_cp0_config_read() & MIPS3_CONFIG_CS) != 0)
386: csizebase = MIPS3_CONFIG_C_4100BASE;
387:
1.6 takemura 388: /*
389: * R4100 (NEC VR series) revision number means:
390: *
391: * MIPS_PRID_REV_MAJ MIPS_PRID_REV_MIN
392: * VR4102 4 ?
393: * VR4111 5 ?
394: * VR4181 5 ?
395: * VR4121 6 ?
396: * VR4122 7 0 or 1
397: * VR4181A 7 3 <
398: * VR4131 8 ?
399: */
400: /* Vr4131 has R4600 style 2-way set-associative cache */
401: if (MIPS_PRID_REV_MAJ(cpu_id) == 8)
402: goto primary_cache_is_2way;
403: /* FALLTHROUGH */
404:
1.2 thorpej 405: case MIPS_R4000:
406: case MIPS_R4300:
1.45 matt 407: mci->mci_picache_ways = 1;
408: mci->mci_pdcache_ways = 1;
409: mci->mci_sdcache_ways = 1;
1.2 thorpej 410:
411: mips3_get_cache_config(csizebase);
412:
1.27 tsutsui 413: /* no VCE support if there is no L2 cache */
1.48.26.3! skrll 414: if (mci->mci_picache_size > PAGE_SIZE)
! 415: mci->mci_icache_virtual_alias = true;
! 416: if (mci->mci_pdcache_size > PAGE_SIZE)
1.45 matt 417: mci->mci_cache_virtual_alias = true;
1.27 tsutsui 418:
1.48.26.3! skrll 419: mco->mco_icache_sync_all = r4k_icache_sync_all_generic;
1.45 matt 420: switch (mci->mci_picache_line_size) {
1.2 thorpej 421: case 16:
1.45 matt 422: mco->mco_icache_sync_range =
1.48.26.3! skrll 423: cache_r4k_icache_hit_inv_16;
1.45 matt 424: mco->mco_icache_sync_range_index =
1.48.26.3! skrll 425: cache_r4k_icache_index_inv_16;
1.2 thorpej 426: break;
427:
1.5 tsutsui 428: case 32:
1.45 matt 429: mco->mco_icache_sync_range =
1.48.26.3! skrll 430: cache_r4k_icache_hit_inv_32;
1.45 matt 431: mco->mco_icache_sync_range_index =
1.48.26.3! skrll 432: cache_r4k_icache_index_inv_32;
1.5 tsutsui 433: break;
434:
1.2 thorpej 435: default:
436: panic("r4k picache line size %d",
1.45 matt 437: mci->mci_picache_line_size);
1.2 thorpej 438: }
439:
1.48.26.3! skrll 440: mco->mco_pdcache_wbinv_all = r4k_pdcache_wbinv_all_generic;
1.45 matt 441: switch (mci->mci_pdcache_line_size) {
1.2 thorpej 442: case 16:
1.45 matt 443: mco->mco_pdcache_wbinv_range =
1.48.26.3! skrll 444: cache_r4k_pdcache_hit_wb_inv_16;
1.45 matt 445: mco->mco_pdcache_wbinv_range_index =
1.48.26.3! skrll 446: cache_r4k_pdcache_index_wb_inv_16;
1.45 matt 447: mco->mco_pdcache_inv_range =
1.48.26.3! skrll 448: cache_r4k_pdcache_hit_inv_16;
1.45 matt 449: mco->mco_pdcache_wb_range =
1.48.26.3! skrll 450: cache_r4k_pdcache_hit_wb_16;
1.5 tsutsui 451: break;
452:
453: case 32:
1.45 matt 454: mco->mco_pdcache_wbinv_range =
1.48.26.3! skrll 455: cache_r4k_pdcache_hit_wb_inv_32;
1.45 matt 456: mco->mco_pdcache_wbinv_range_index =
1.48.26.3! skrll 457: cache_r4k_pdcache_index_wb_inv_32;
1.45 matt 458: mco->mco_pdcache_inv_range =
1.48.26.3! skrll 459: cache_r4k_pdcache_hit_inv_32;
1.45 matt 460: mco->mco_pdcache_wb_range =
1.48.26.3! skrll 461: cache_r4k_pdcache_hit_wb_32;
1.2 thorpej 462: break;
463:
464: default:
465: panic("r4k pdcache line size %d",
1.45 matt 466: mci->mci_pdcache_line_size);
1.2 thorpej 467: }
468: break;
469:
470: case MIPS_R4600:
471: #ifdef ENABLE_MIPS_R4700
472: case MIPS_R4700:
473: #endif
474: #ifndef ENABLE_MIPS_R3NKK
475: case MIPS_R5000:
476: #endif
477: case MIPS_RM5200:
1.6 takemura 478: primary_cache_is_2way:
1.45 matt 479: mci->mci_picache_ways = 2;
480: mci->mci_pdcache_ways = 2;
1.2 thorpej 481:
482: mips3_get_cache_config(csizebase);
483:
1.48.26.3! skrll 484: if (mci->mci_picache_size / mci->mci_picache_ways > PAGE_SIZE)
! 485: mci->mci_icache_virtual_alias = true;
! 486: if (mci->mci_pdcache_size / mci->mci_pdcache_ways > PAGE_SIZE)
1.45 matt 487: mci->mci_cache_virtual_alias = true;
1.27 tsutsui 488:
1.48.26.3! skrll 489: mco->mco_icache_sync_all = r5k_picache_sync_all;
! 490: mco->mco_icache_sync_range = r5k_picache_sync_range;
! 491: mco->mco_icache_sync_range_index = r5k_picache_sync_range_index;
! 492:
1.45 matt 493: switch (mci->mci_picache_line_size) {
1.2 thorpej 494: case 32:
1.48.26.3! skrll 495: /* used internally by mipsNN_picache_sync_range */
! 496: mco->mco_intern_icache_sync_range =
! 497: cache_r4k_icache_hit_inv_16;
! 498:
! 499: /* used internally by mipsNN_picache_sync_range_index */
! 500: mco->mco_intern_icache_sync_range_index =
! 501: cache_r4k_icache_index_inv_16;
1.2 thorpej 502: break;
503:
504: default:
1.48.26.3! skrll 505: panic("r5k picache line size %u",
1.45 matt 506: mci->mci_picache_line_size);
1.2 thorpej 507: }
508:
1.48.26.3! skrll 509: mco->mco_pdcache_wbinv_all = r5k_pdcache_wbinv_all;
! 510: mco->mco_pdcache_wbinv_range_index =
! 511: r5k_pdcache_wbinv_range_index;
! 512:
1.45 matt 513: switch (mci->mci_pdcache_line_size) {
1.6 takemura 514: case 16:
1.45 matt 515: mco->mco_pdcache_wbinv_range =
1.48.26.3! skrll 516: cache_r4k_pdcache_hit_wb_inv_16;
1.45 matt 517: mco->mco_pdcache_inv_range =
1.48.26.3! skrll 518: cache_r4k_pdcache_hit_inv_16;
1.45 matt 519: mco->mco_pdcache_wb_range =
1.48.26.3! skrll 520: cache_r4k_pdcache_hit_wb_16;
! 521:
! 522: /* used internally by r5k_pdcache_wbinv_range_index */
! 523: mco->mco_intern_pdcache_wbinv_range_index =
! 524: cache_r4k_pdcache_index_wb_inv_16;
1.6 takemura 525: break;
526:
1.2 thorpej 527: case 32:
1.45 matt 528: mco->mco_pdcache_wbinv_range =
1.48.26.3! skrll 529: cache_r4k_pdcache_hit_wb_inv_32;
1.45 matt 530: mco->mco_pdcache_inv_range =
1.48.26.3! skrll 531: cache_r4k_pdcache_hit_inv_32;
1.45 matt 532: mco->mco_pdcache_wb_range =
1.48.26.3! skrll 533: cache_r4k_pdcache_hit_wb_32;
! 534:
! 535: /* used internally by r5k_pdcache_wbinv_range_index */
! 536: mco->mco_intern_pdcache_wbinv_range_index =
! 537: cache_r4k_pdcache_index_wb_inv_32;
1.2 thorpej 538: break;
539:
540: default:
541: panic("r5k pdcache line size %d",
1.45 matt 542: mci->mci_pdcache_line_size);
1.2 thorpej 543: }
544:
1.48.26.3! skrll 545: mco->mco_intern_pdcache_sync_all = mco->mco_pdcache_wbinv_all;
! 546: mco->mco_intern_pdcache_sync_range_index =
! 547: mco->mco_intern_pdcache_wbinv_range_index;
! 548: mco->mco_intern_pdcache_sync_range = mco->mco_pdcache_wb_range;
! 549:
1.2 thorpej 550: /*
551: * Deal with R4600 chip bugs.
552: */
553: if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4600 &&
554: MIPS_PRID_REV_MAJ(cpu_id) == 1) {
1.45 matt 555: KASSERT(mci->mci_pdcache_line_size == 32);
556: mco->mco_pdcache_wbinv_range =
1.2 thorpej 557: r4600v1_pdcache_wbinv_range_32;
1.45 matt 558: mco->mco_pdcache_inv_range =
1.2 thorpej 559: r4600v1_pdcache_inv_range_32;
1.45 matt 560: mco->mco_pdcache_wb_range =
1.2 thorpej 561: r4600v1_pdcache_wb_range_32;
562: } else if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4600 &&
563: MIPS_PRID_REV_MAJ(cpu_id) == 2) {
1.45 matt 564: KASSERT(mci->mci_pdcache_line_size == 32);
565: mco->mco_pdcache_wbinv_range =
1.2 thorpej 566: r4600v2_pdcache_wbinv_range_32;
1.45 matt 567: mco->mco_pdcache_inv_range =
1.2 thorpej 568: r4600v2_pdcache_inv_range_32;
1.45 matt 569: mco->mco_pdcache_wb_range =
1.2 thorpej 570: r4600v2_pdcache_wb_range_32;
1.8 shin 571: }
572:
573: /*
574: * Deal with VR4131 chip bugs.
575: */
576: if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4100 &&
577: MIPS_PRID_REV_MAJ(cpu_id) == 8) {
1.45 matt 578: KASSERT(mci->mci_pdcache_line_size == 16);
579: mco->mco_pdcache_wbinv_range =
1.8 shin 580: vr4131v1_pdcache_wbinv_range_16;
1.2 thorpej 581: }
582: break;
1.21 tsutsui 583: #ifdef ENABLE_MIPS4_CACHE_R10K
584: case MIPS_R10000:
1.23 shin 585: case MIPS_R12000:
586: case MIPS_R14000:
1.45 matt 587: mci->mci_picache_ways = 2;
588: mci->mci_pdcache_ways = 2;
589: mci->mci_sdcache_ways = 2;
1.21 tsutsui 590:
591: mips4_get_cache_config(csizebase);
592:
1.27 tsutsui 593: /* VCE is handled by hardware */
594:
1.45 matt 595: mco->mco_icache_sync_all =
1.23 shin 596: r10k_icache_sync_all;
1.45 matt 597: mco->mco_icache_sync_range =
1.23 shin 598: r10k_icache_sync_range;
1.45 matt 599: mco->mco_icache_sync_range_index =
1.23 shin 600: r10k_icache_sync_range_index;
1.45 matt 601: mco->mco_pdcache_wbinv_all =
1.23 shin 602: r10k_pdcache_wbinv_all;
1.45 matt 603: mco->mco_pdcache_wbinv_range =
1.23 shin 604: r10k_pdcache_wbinv_range;
1.45 matt 605: mco->mco_pdcache_wbinv_range_index =
1.23 shin 606: r10k_pdcache_wbinv_range_index;
1.45 matt 607: mco->mco_pdcache_inv_range =
1.23 shin 608: r10k_pdcache_inv_range;
1.45 matt 609: mco->mco_pdcache_wb_range =
1.23 shin 610: r10k_pdcache_wb_range;
1.21 tsutsui 611: break;
612: #endif /* ENABLE_MIPS4_CACHE_R10K */
1.36 matt 613: #ifdef MIPS3_LOONGSON2
1.34 matt 614: case MIPS_LOONGSON2:
1.47 bouyer 615: mci->mci_picache_ways = 4;
616: mci->mci_pdcache_ways = 4;
1.2 thorpej 617:
1.38 matt 618: mips3_get_cache_config(csizebase);
1.34 matt 619:
1.47 bouyer 620: mci->mci_sdcache_line_size = 32; /* don't trust config reg */
1.41 matt 621:
1.48.26.3! skrll 622: if (mci->mci_picache_size / mci->mci_picache_ways > PAGE_SIZE)
! 623: mci->mci_icache_virtual_alias = true;
! 624: if (mci->mci_pdcache_size / mci->mci_pdcache_ways > PAGE_SIZE)
1.48.26.2 skrll 625: mci->mci_cache_virtual_alias = true;
1.37 matt 626:
1.47 bouyer 627: mco->mco_icache_sync_all =
1.39 matt 628: ls2_icache_sync_all;
1.47 bouyer 629: mco->mco_icache_sync_range =
1.39 matt 630: ls2_icache_sync_range;
1.47 bouyer 631: mco->mco_icache_sync_range_index =
1.39 matt 632: ls2_icache_sync_range_index;
1.34 matt 633:
1.47 bouyer 634: mco->mco_pdcache_wbinv_all =
1.39 matt 635: ls2_pdcache_wbinv_all;
1.47 bouyer 636: mco->mco_pdcache_wbinv_range =
1.39 matt 637: ls2_pdcache_wbinv_range;
1.47 bouyer 638: mco->mco_pdcache_wbinv_range_index =
1.39 matt 639: ls2_pdcache_wbinv_range_index;
1.47 bouyer 640: mco->mco_pdcache_inv_range =
1.39 matt 641: ls2_pdcache_inv_range;
1.47 bouyer 642: mco->mco_pdcache_wb_range =
1.39 matt 643: ls2_pdcache_wb_range;
1.34 matt 644:
1.37 matt 645: /*
646: * For current version chips, [the] operating system is
647: * obliged to eliminate the potential for virtual aliasing.
648: */
1.47 bouyer 649: uvmexp.ncolors = mci->mci_pdcache_ways;
1.34 matt 650: break;
651: #endif
1.36 matt 652: #endif /* MIPS3 || MIPS4 */
1.2 thorpej 653: default:
1.12 provos 654: panic("can't handle primary cache on impl 0x%x",
1.2 thorpej 655: MIPS_PRID_IMPL(cpu_id));
656: }
657:
658: /*
659: * Compute the "way mask" for each cache.
660: */
1.45 matt 661: if (mci->mci_picache_size) {
662: KASSERT(mci->mci_picache_ways != 0);
1.48.26.3! skrll 663: mci->mci_picache_way_size = mci->mci_picache_size / mci->mci_picache_ways;
1.45 matt 664: mci->mci_picache_way_mask = mci->mci_picache_way_size - 1;
1.48.26.3! skrll 665: #if (MIPS2 + MIPS3) > 0
! 666: if (mci->mci_icache_virtual_alias)
! 667: mci->mci_icache_alias_mask =
! 668: mci->mci_picache_way_mask & -PAGE_SIZE;
! 669: #endif
1.2 thorpej 670: }
1.45 matt 671: if (mci->mci_pdcache_size) {
672: KASSERT(mci->mci_pdcache_ways != 0);
1.48.26.3! skrll 673: mci->mci_pdcache_way_size = mci->mci_pdcache_size / mci->mci_pdcache_ways;
1.45 matt 674: mci->mci_pdcache_way_mask = mci->mci_pdcache_way_size - 1;
1.48.26.3! skrll 675: #if (MIPS2 + MIPS3) > 0
! 676: if (mci->mci_cache_virtual_alias)
! 677: mci->mci_cache_alias_mask =
! 678: mci->mci_picache_way_mask & -PAGE_SIZE;
! 679: #endif
1.2 thorpej 680: }
681:
1.4 thorpej 682: mips_dcache_compute_align();
683:
1.45 matt 684: if (mci->mci_sdcache_line_size == 0)
1.2 thorpej 685: return;
686:
687: /*
688: * Configure the secondary cache.
689: */
690: switch (MIPS_PRID_IMPL(cpu_id)) {
1.10 simonb 691: #if defined(MIPS3) || defined(MIPS4)
1.2 thorpej 692: case MIPS_R4000:
1.7 shin 693: /*
1.30 tsutsui 694: * R4000/R4400 detects virtual alias by VCE as if
695: * its primary cache size were 32KB, because it always
696: * compares 3 bits of vaddr[14:12] which causes
697: * primary cache miss and PIdx[2:0] in the secondary
698: * cache tag regardless of its primary cache size.
699: * i.e. VCE could happen even if there is no actual
700: * virtual alias on its 8KB or 16KB primary cache
701: * which has only 1 or 2 bit valid PIdx in 4KB page.
702: * Actual primary cache size is ignored wrt VCE
703: * and virtual aliases are resolved by the VCE hander,
704: * but it's still worth to avoid unnecessary VCE by
705: * setting alias mask and prefer mask to 32K, though
706: * some other possible aliases (maybe caused by KSEG0
707: * accesses which can't be managed by PMAP_PREFER(9))
708: * will still be resolved by the VCED/VCEI handler.
1.27 tsutsui 709: */
1.45 matt 710: mci->mci_cache_alias_mask =
1.30 tsutsui 711: (MIPS3_MAX_PCACHE_SIZE - 1) & ~PAGE_MASK; /* va[14:12] */
1.45 matt 712: mci->mci_cache_prefer_mask = MIPS3_MAX_PCACHE_SIZE - 1;
1.30 tsutsui 713:
1.48.26.3! skrll 714: mci->mci_icache_virtual_alias = false;
1.48.26.2 skrll 715: mci->mci_cache_virtual_alias = false;
1.7 shin 716: /* FALLTHROUGH */
1.2 thorpej 717: case MIPS_R4600:
718: #ifdef ENABLE_MIPS_R4700
719: case MIPS_R4700:
720: #endif
1.45 matt 721: switch (mci->mci_sdcache_ways) {
1.2 thorpej 722: case 1:
1.48.26.3! skrll 723: mco->mco_sdcache_wbinv_all =
! 724: r4k_sdcache_wbinv_all_generic;
1.45 matt 725: switch (mci->mci_sdcache_line_size) {
1.48.26.3! skrll 726: case 16:
! 727: mco->mco_sdcache_wbinv_range =
! 728: cache_r4k_sdcache_hit_wb_inv_16;
! 729: mco->mco_sdcache_wbinv_range_index =
! 730: cache_r4k_sdcache_index_wb_inv_16;
! 731: mco->mco_sdcache_inv_range =
! 732: cache_r4k_sdcache_hit_inv_16;
! 733: mco->mco_sdcache_wb_range =
! 734: cache_r4k_sdcache_hit_wb_16;
! 735: break;
! 736:
1.2 thorpej 737: case 32:
1.45 matt 738: mco->mco_sdcache_wbinv_range =
1.48.26.3! skrll 739: cache_r4k_sdcache_hit_wb_inv_32;
1.45 matt 740: mco->mco_sdcache_wbinv_range_index =
1.48.26.3! skrll 741: cache_r4k_sdcache_index_wb_inv_32;
1.45 matt 742: mco->mco_sdcache_inv_range =
1.48.26.3! skrll 743: cache_r4k_sdcache_hit_inv_32;
1.45 matt 744: mco->mco_sdcache_wb_range =
1.48.26.3! skrll 745: cache_r4k_sdcache_hit_wb_32;
1.2 thorpej 746: break;
747:
748: case 64:
1.45 matt 749: mco->mco_sdcache_wbinv_range =
1.48.26.3! skrll 750: cache_r4k_sdcache_hit_wb_inv_64;
1.45 matt 751: mco->mco_sdcache_wbinv_range_index =
1.48.26.3! skrll 752: cache_r4k_sdcache_index_wb_inv_64;
1.45 matt 753: mco->mco_sdcache_inv_range =
1.48.26.3! skrll 754: cache_r4k_sdcache_hit_inv_64;
1.45 matt 755: mco->mco_sdcache_wb_range =
1.48.26.3! skrll 756: cache_r4k_sdcache_hit_wb_64;
1.3 thorpej 757: break;
758:
759: case 128:
1.45 matt 760: mco->mco_sdcache_wbinv_range =
1.48.26.3! skrll 761: cache_r4k_sdcache_hit_wb_inv_128;
1.45 matt 762: mco->mco_sdcache_wbinv_range_index =
1.48.26.3! skrll 763: cache_r4k_sdcache_index_wb_inv_128;
1.45 matt 764: mco->mco_sdcache_inv_range =
1.48.26.3! skrll 765: cache_r4k_sdcache_hit_inv_128;
1.45 matt 766: mco->mco_sdcache_wb_range =
1.48.26.3! skrll 767: cache_r4k_sdcache_hit_wb_128;
1.2 thorpej 768: break;
769:
770: default:
1.12 provos 771: panic("r4k sdcache %d way line size %d",
1.45 matt 772: mci->mci_sdcache_ways, mci->mci_sdcache_line_size);
1.2 thorpej 773: }
774: break;
775:
776: default:
1.12 provos 777: panic("r4k sdcache %d way line size %d",
1.45 matt 778: mci->mci_sdcache_ways, mci->mci_sdcache_line_size);
1.2 thorpej 779: }
1.18 rafal 780: break;
781: #ifndef ENABLE_MIPS_R3NKK
782: case MIPS_R5000:
783: #endif
784: case MIPS_RM5200:
1.45 matt 785: mci->mci_sdcache_write_through = true;
786: mco->mco_sdcache_wbinv_all =
1.18 rafal 787: r5k_sdcache_wbinv_all;
1.45 matt 788: mco->mco_sdcache_wbinv_range =
1.18 rafal 789: r5k_sdcache_wbinv_range;
1.45 matt 790: mco->mco_sdcache_wbinv_range_index =
1.25 sekiya 791: r5k_sdcache_wbinv_range_index;
1.45 matt 792: mco->mco_sdcache_inv_range =
1.18 rafal 793: r5k_sdcache_wbinv_range;
1.48.26.3! skrll 794: mco->mco_sdcache_wb_range = no_cache_op_range;
1.2 thorpej 795: break;
1.21 tsutsui 796: #ifdef ENABLE_MIPS4_CACHE_R10K
797: case MIPS_R10000:
1.23 shin 798: case MIPS_R12000:
799: case MIPS_R14000:
1.45 matt 800: mco->mco_sdcache_wbinv_all =
1.23 shin 801: r10k_sdcache_wbinv_all;
1.45 matt 802: mco->mco_sdcache_wbinv_range =
1.23 shin 803: r10k_sdcache_wbinv_range;
1.45 matt 804: mco->mco_sdcache_wbinv_range_index =
1.23 shin 805: r10k_sdcache_wbinv_range_index;
1.45 matt 806: mco->mco_sdcache_inv_range =
1.23 shin 807: r10k_sdcache_inv_range;
1.45 matt 808: mco->mco_sdcache_wb_range =
1.23 shin 809: r10k_sdcache_wb_range;
1.21 tsutsui 810: break;
811: #endif /* ENABLE_MIPS4_CACHE_R10K */
1.36 matt 812: #ifdef MIPS3_LOONGSON2
1.34 matt 813: case MIPS_LOONGSON2:
1.47 bouyer 814: mci->mci_sdcache_ways = 4;
815: mci->mci_sdcache_size = 512*1024;
816: mci->mci_scache_unified = 1;
1.34 matt 817:
1.47 bouyer 818: mco->mco_sdcache_wbinv_all =
1.39 matt 819: ls2_sdcache_wbinv_all;
1.47 bouyer 820: mco->mco_sdcache_wbinv_range =
1.39 matt 821: ls2_sdcache_wbinv_range;
1.47 bouyer 822: mco->mco_sdcache_wbinv_range_index =
1.39 matt 823: ls2_sdcache_wbinv_range_index;
1.47 bouyer 824: mco->mco_sdcache_inv_range =
1.39 matt 825: ls2_sdcache_inv_range;
1.47 bouyer 826: mco->mco_sdcache_wb_range =
1.39 matt 827: ls2_sdcache_wb_range;
1.37 matt 828:
829: /*
830: * The secondary cache is physically indexed and tagged
831: */
1.34 matt 832: break;
833: #endif
1.36 matt 834: #endif /* MIPS3 || MIPS4 */
1.2 thorpej 835:
836: default:
1.12 provos 837: panic("can't handle secondary cache on impl 0x%x",
1.2 thorpej 838: MIPS_PRID_IMPL(cpu_id));
839: }
840:
841: /*
842: * Compute the "way mask" for each secondary cache.
843: */
1.45 matt 844: if (mci->mci_sdcache_size) {
845: KASSERT(mci->mci_sdcache_ways != 0);
1.48.26.3! skrll 846: mci->mci_sdcache_way_size = mci->mci_sdcache_size / mci->mci_sdcache_ways;
1.45 matt 847: mci->mci_sdcache_way_mask = mci->mci_sdcache_way_size - 1;
1.2 thorpej 848: }
1.4 thorpej 849:
850: mips_dcache_compute_align();
1.2 thorpej 851: }
852:
1.44 uebayasi 853: #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4)
1.43 pooka 854: void
855: mips_config_cache_emips(void)
856: {
1.45 matt 857: struct mips_cache_info * const mci = &mips_cache_info;
858: struct mips_cache_ops * const mco = &mips_cache_ops;
859: const mips_prid_t cpu_id = mips_options.mips_cpu_id;
1.43 pooka 860: KASSERT(PAGE_SIZE != 0);
861:
862: /*
863: * Configure primary caches.
864: */
865: switch (MIPS_PRID_IMPL(cpu_id)) {
866: case MIPS_eMIPS:
1.45 matt 867: mci->mci_picache_size = 0;
868: mci->mci_pdcache_size = 0;
1.43 pooka 869:
1.45 matt 870: mci->mci_picache_line_size = 4;
871: mci->mci_pdcache_line_size = 4;
1.43 pooka 872:
1.45 matt 873: mci->mci_picache_ways = 1;
874: mci->mci_pdcache_ways = 1;
1.43 pooka 875:
1.48.26.3! skrll 876: mci->mci_pdcache_write_through = true;
1.45 matt 877:
878: mco->mco_icache_sync_all = no_cache_op;
879: mco->mco_icache_sync_range = no_cache_op_range;
1.48.26.3! skrll 880: mco->mco_icache_sync_range_index = no_cache_op_range_index;
1.45 matt 881:
882: mco->mco_pdcache_wbinv_all = no_cache_op;
883: mco->mco_pdcache_wbinv_range = no_cache_op_range;
1.48.26.3! skrll 884: mco->mco_pdcache_wbinv_range_index = no_cache_op_range_index;
1.45 matt 885: mco->mco_pdcache_inv_range = no_cache_op_range;
886: mco->mco_pdcache_wb_range = no_cache_op_range;
1.43 pooka 887:
888: uvmexp.ncolors = 1;
889: break;
890:
891: default:
1.45 matt 892: panic("%s: unsupported eMIPS", __func__);
1.43 pooka 893: }
894: }
1.44 uebayasi 895: #endif
1.43 pooka 896:
1.2 thorpej 897: #ifdef MIPS1
898: #ifdef ENABLE_MIPS_TX3900
899: /*
900: * tx3900_get_cache_config:
901: *
902: * Fetch cache size information for the TX3900.
903: */
904: void
905: tx3900_get_cache_config(void)
906: {
1.45 matt 907: struct mips_cache_info * const mci = &mips_cache_info;
1.2 thorpej 908: uint32_t config;
909:
910: config = tx3900_cp0_config_read();
911:
1.45 matt 912: mci->mci_picache_size = R3900_C_SIZE_MIN <<
1.2 thorpej 913: ((config & R3900_CONFIG_ICS_MASK) >> R3900_CONFIG_ICS_SHIFT);
914:
1.45 matt 915: mci->mci_pdcache_size = R3900_C_SIZE_MIN <<
1.2 thorpej 916: ((config & R3900_CONFIG_DCS_MASK) >> R3900_CONFIG_DCS_SHIFT);
917: }
918:
919: /*
920: * tx3920_get_cache_config:
921: *
922: * Fetch cache size information for the TX3920.
923: */
924: void
925: tx3920_get_cache_config(void)
926: {
1.45 matt 927: struct mips_cache_info * const mci = &mips_cache_info;
1.2 thorpej 928:
929: /* Size is the same as TX3900. */
930: tx3900_get_cache_config();
931:
932: /* Now determine write-through/write-back mode. */
933: if ((tx3900_cp0_config_read() & R3900_CONFIG_WBON) == 0)
1.45 matt 934: mci->mci_pdcache_write_through = true;
1.2 thorpej 935: }
1.9 uch 936:
937: /*
938: * tx39_cache_config_write_through:
939: *
940: * TX3922 write-through D-cache mode.
941: * for TX3912, no meaning. (no write-back mode)
942: */
943: void
944: tx39_cache_config_write_through(void)
945: {
946: u_int32_t r;
947:
948: mips_dcache_wbinv_all();
949:
1.33 perry 950: __asm volatile("mfc0 %0, $3" : "=r"(r));
1.9 uch 951: r &= 0xffffdfff;
1.33 perry 952: __asm volatile("mtc0 %0, $3" : : "r"(r));
1.9 uch 953: }
954:
1.2 thorpej 955: #endif /* ENABLE_MIPS_TX3900 */
956: #endif /* MIPS1 */
957:
1.10 simonb 958: #if defined(MIPS3) || defined(MIPS4)
1.2 thorpej 959: /*
960: * mips3_get_cache_config:
961: *
962: * Fetch the cache config information for a MIPS-3 or MIPS-4
963: * processor (virtually-indexed cache).
964: *
965: * NOTE: Fetching the size of the secondary cache is something
966: * that platform specific code has to do. We'd appreciate it
967: * if they initialized the size before now.
968: *
969: * ALSO NOTE: The number of ways in the cache must already be
970: * initialized.
971: */
972: void
973: mips3_get_cache_config(int csizebase)
974: {
1.45 matt 975: struct mips_cache_info * const mci = &mips_cache_info;
976: const mips_prid_t cpu_id = mips_options.mips_cpu_id;
977: bool has_sdcache_enable = false;
1.2 thorpej 978: uint32_t config = mips3_cp0_config_read();
979:
1.45 matt 980: mci->mci_picache_size = MIPS3_CONFIG_CACHE_SIZE(config,
1.2 thorpej 981: MIPS3_CONFIG_IC_MASK, csizebase, MIPS3_CONFIG_IC_SHIFT);
1.45 matt 982: mci->mci_picache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config,
1.2 thorpej 983: MIPS3_CONFIG_IB);
984:
1.45 matt 985: mci->mci_pdcache_size = MIPS3_CONFIG_CACHE_SIZE(config,
1.2 thorpej 986: MIPS3_CONFIG_DC_MASK, csizebase, MIPS3_CONFIG_DC_SHIFT);
1.45 matt 987: mci->mci_pdcache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config,
1.2 thorpej 988: MIPS3_CONFIG_DB);
989:
1.48.26.3! skrll 990: mci->mci_icache_alias_mask =
! 991: (mci->mci_picache_size / mci->mci_picache_ways - 1) & -PAGE_SIZE;
1.45 matt 992: mci->mci_cache_alias_mask =
1.48.26.3! skrll 993: (mci->mci_pdcache_size / mci->mci_pdcache_ways - 1) & -PAGE_SIZE;
1.45 matt 994: mci->mci_cache_prefer_mask =
995: max(mci->mci_pdcache_size, mci->mci_picache_size) - 1;
996: uvmexp.ncolors = (mci->mci_cache_alias_mask >> PAGE_SHIFT) + 1;
1.2 thorpej 997:
1.19 rafal 998: switch(MIPS_PRID_IMPL(cpu_id)) {
999: #ifndef ENABLE_MIPS_R3NKK
1000: case MIPS_R5000:
1001: #endif
1002: case MIPS_RM5200:
1.45 matt 1003: has_sdcache_enable = true;
1.19 rafal 1004: break;
1005: }
1006:
1.48.26.2 skrll 1007: /*
1.16 rafal 1008: * If CPU has a software-enabled L2 cache, check both if it's
1009: * present and if it's enabled before making assumptions the
1010: * L2 is usable. If the L2 is disabled, we treat it the same
1011: * as if there were no L2 cache.
1012: */
1.2 thorpej 1013: if ((config & MIPS3_CONFIG_SC) == 0) {
1.16 rafal 1014: if (has_sdcache_enable == 0 ||
1015: (has_sdcache_enable && (config & MIPS3_CONFIG_SE))) {
1.48.26.2 skrll 1016: mci->mci_sdcache_line_size =
1.16 rafal 1017: MIPS3_CONFIG_CACHE_L2_LSIZE(config);
1018: if ((config & MIPS3_CONFIG_SS) == 0)
1.45 matt 1019: mci->mci_scache_unified = true;
1.16 rafal 1020: } else {
1021: #ifdef CACHE_DEBUG
1022: printf("External cache detected, but is disabled -- WILL NOT ENABLE!\n");
1023: #endif /* CACHE_DEBUG */
1024: }
1.2 thorpej 1025: }
1026: }
1.21 tsutsui 1027:
1028: #ifdef ENABLE_MIPS4_CACHE_R10K
1029: void
1030: mips4_get_cache_config(int csizebase)
1031: {
1.45 matt 1032: struct mips_cache_info * const mci = &mips_cache_info;
1.21 tsutsui 1033: uint32_t config = mips3_cp0_config_read();
1034:
1.45 matt 1035: mci->mci_picache_size = MIPS4_CONFIG_CACHE_SIZE(config,
1.21 tsutsui 1036: MIPS4_CONFIG_IC_MASK, csizebase, MIPS4_CONFIG_IC_SHIFT);
1.45 matt 1037: mci->mci_picache_line_size = 64; /* 64 Byte */
1.21 tsutsui 1038:
1.45 matt 1039: mci->mci_pdcache_size = MIPS4_CONFIG_CACHE_SIZE(config,
1.21 tsutsui 1040: MIPS4_CONFIG_DC_MASK, csizebase, MIPS4_CONFIG_DC_SHIFT);
1.45 matt 1041: mci->mci_pdcache_line_size = 32; /* 32 Byte */
1.21 tsutsui 1042:
1.45 matt 1043: mci->mci_cache_alias_mask =
1044: ((mci->mci_pdcache_size / mci->mci_pdcache_ways) - 1) & ~PAGE_MASK;
1045: mci->mci_cache_prefer_mask =
1046: max(mci->mci_pdcache_size, mci->mci_picache_size) - 1;
1.21 tsutsui 1047: }
1048: #endif /* ENABLE_MIPS4_CACHE_R10K */
1.10 simonb 1049: #endif /* MIPS3 || MIPS4 */
1050: #endif /* MIPS1 || MIPS3 || MIPS4 */
1051:
1.46 matt 1052: #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
1.10 simonb 1053:
1054: static void
1.48 matt 1055: mips_config_cache_modern(uint32_t cpu_id)
1.10 simonb 1056: {
1.45 matt 1057: struct mips_cache_info * const mci = &mips_cache_info;
1058: struct mips_cache_ops * const mco = &mips_cache_ops;
1.48.26.3! skrll 1059: struct mips_options * const opts = &mips_options;
1.10 simonb 1060: /* MIPS32/MIPS64, use coprocessor 0 config registers */
1061: uint32_t cfg, cfg1;
1062:
1063: cfg = mips3_cp0_config_read();
1064: cfg1 = mipsNN_cp0_config1_read();
1065:
1066: #ifdef MIPS_DISABLE_L1_CACHE
1067: cfg1 &= ~MIPSNN_CFG1_IL_MASK;
1068: cfg1 &= ~MIPSNN_CFG1_DL_MASK;
1069: mipsNN_cp0_config1_write(cfg1);
1070: #endif
1071:
1072: /* figure out Dcache params. */
1073: switch (MIPSNN_GET(CFG1_DL, cfg1)) {
1074: case MIPSNN_CFG1_DL_NONE:
1.48.26.1 skrll 1075: #ifdef MIPS64_OCTEON
1076: mci->mci_pdcache_line_size = 128;
1077: mci->mci_pdcache_way_size = 256;
1078: mci->mci_pdcache_ways = 64;
1.48.26.3! skrll 1079: mci->mci_pdcache_write_through = true;
1.48.26.1 skrll 1080:
1081: mci->mci_pdcache_size =
1082: mci->mci_pdcache_way_size * mci->mci_pdcache_ways;
1083: mci->mci_pdcache_way_mask = mci->mci_pdcache_way_size - 1;
1084: uvmexp.ncolors = atop(mci->mci_pdcache_size) / mci->mci_pdcache_ways;
1085: #else
1.45 matt 1086: mci->mci_pdcache_line_size = mci->mci_pdcache_way_size =
1087: mci->mci_pdcache_ways = 0;
1.48.26.1 skrll 1088: #endif
1.10 simonb 1089: break;
1090: case MIPSNN_CFG1_DL_RSVD:
1091: panic("reserved MIPS32/64 Dcache line size");
1092: break;
1093: default:
1094: if (MIPSNN_GET(CFG1_DS, cfg1) == MIPSNN_CFG1_DS_RSVD)
1095: panic("reserved MIPS32/64 Dcache sets per way");
1.45 matt 1096: mci->mci_pdcache_line_size = MIPSNN_CFG1_DL(cfg1);
1097: mci->mci_pdcache_way_size =
1098: mci->mci_pdcache_line_size * MIPSNN_CFG1_DS(cfg1);
1099: mci->mci_pdcache_ways = MIPSNN_CFG1_DA(cfg1) + 1;
1.10 simonb 1100:
1101: /*
1102: * Compute the total size and "way mask" for the
1.45 matt 1103: * primary Dcache.
1.10 simonb 1104: */
1.45 matt 1105: mci->mci_pdcache_size =
1106: mci->mci_pdcache_way_size * mci->mci_pdcache_ways;
1107: mci->mci_pdcache_way_mask = mci->mci_pdcache_way_size - 1;
1.48.26.3! skrll 1108: uvmexp.ncolors = atop(mci->mci_pdcache_way_size);
1.10 simonb 1109: break;
1110: }
1111:
1112: /* figure out Icache params. */
1113: switch (MIPSNN_GET(CFG1_IL, cfg1)) {
1114: case MIPSNN_CFG1_IL_NONE:
1.45 matt 1115: mci->mci_picache_line_size = mci->mci_picache_way_size =
1116: mci->mci_picache_ways = 0;
1.10 simonb 1117: break;
1118: case MIPSNN_CFG1_IL_RSVD:
1119: panic("reserved MIPS32/64 Icache line size");
1120: break;
1121: default:
1122: if (MIPSNN_GET(CFG1_IS, cfg1) == MIPSNN_CFG1_IS_RSVD)
1123: panic("reserved MIPS32/64 Icache sets per way");
1.45 matt 1124: mci->mci_picache_line_size = MIPSNN_CFG1_IL(cfg1);
1125: mci->mci_picache_way_size =
1126: mci->mci_picache_line_size * MIPSNN_CFG1_IS(cfg1);
1127: mci->mci_picache_ways = MIPSNN_CFG1_IA(cfg1) + 1;
1.10 simonb 1128:
1129: /*
1.48.26.3! skrll 1130: * Is this Icache virtually indexed and virtually tagged?
! 1131: */
! 1132: mci->mci_picache_vivt = (cfg & MIPSNN_CFG_VI) != 0;
! 1133:
! 1134: /*
1.10 simonb 1135: * Compute the total size and "way mask" for the
1.48.26.3! skrll 1136: * primary Icache.
1.10 simonb 1137: */
1.45 matt 1138: mci->mci_picache_size =
1139: mci->mci_picache_way_size * mci->mci_picache_ways;
1140: mci->mci_picache_way_mask = mci->mci_picache_way_size - 1;
1.10 simonb 1141: break;
1142: }
1143:
1144: #define CACHE_DEBUG
1145: #ifdef CACHE_DEBUG
1.48.26.3! skrll 1146: printf("MIPS32/64 params: cpu arch: %d\n", opts->mips_cpu_arch);
! 1147: printf("MIPS32/64 params: TLB entries: %d\n", opts->mips_num_tlb_entries);
! 1148: if (mci->mci_picache_line_size == 0) {
1.10 simonb 1149: printf("MIPS32/64 params: no Icache\n");
1.48.26.3! skrll 1150: } else {
! 1151: printf("MIPS32/64 params: %s: line=%d, total=%d, "
! 1152: "ways=%d, sets=%d, colors=%d\n", "Icache",
! 1153: mci->mci_picache_line_size,
1.45 matt 1154: mci->mci_picache_way_size * mci->mci_picache_ways,
1.48.26.3! skrll 1155: mci->mci_picache_ways,
! 1156: mci->mci_picache_way_size / mci->mci_picache_line_size,
! 1157: mci->mci_picache_way_size >> PAGE_SHIFT);
1.10 simonb 1158: }
1.48.26.3! skrll 1159: if (mci->mci_pdcache_line_size == 0) {
1.10 simonb 1160: printf("MIPS32/64 params: no Dcache\n");
1.48.26.3! skrll 1161: } else {
! 1162: printf("MIPS32/64 params: %s: line=%d, total=%d, "
! 1163: "ways=%d, sets=%d, colors=%d\n", "Dcache",
! 1164: mci->mci_pdcache_line_size,
1.45 matt 1165: mci->mci_pdcache_way_size * mci->mci_pdcache_ways,
1.48.26.3! skrll 1166: mci->mci_pdcache_ways,
! 1167: mci->mci_pdcache_way_size / mci->mci_pdcache_line_size,
! 1168: mci->mci_pdcache_way_size >> PAGE_SHIFT);
1.10 simonb 1169: }
1170: #endif /* CACHE_DEBUG */
1171:
1.48.26.3! skrll 1172: mco->mco_icache_sync_all = mipsNN_picache_sync_all;
! 1173: mco->mco_icache_sync_range = mipsNN_picache_sync_range;
! 1174: mco->mco_icache_sync_range_index = mipsNN_picache_sync_range_index;
! 1175:
1.45 matt 1176: switch (mci->mci_picache_line_size) {
1.10 simonb 1177: case 16:
1.48.26.3! skrll 1178: /* used internally by mipsNN_picache_sync_range */
! 1179: mco->mco_intern_icache_sync_range =
! 1180: cache_r4k_icache_hit_inv_16;
! 1181:
! 1182: /* used internally by mipsNN_picache_sync_range_index */
! 1183: mco->mco_intern_icache_sync_range_index =
! 1184: cache_r4k_icache_index_inv_16;
1.10 simonb 1185: break;
1186: case 32:
1.48.26.3! skrll 1187: /* used internally by mipsNN_picache_sync_range */
! 1188: mco->mco_intern_icache_sync_range =
! 1189: cache_r4k_icache_hit_inv_32;
! 1190:
! 1191: /* used internally by mipsNN_picache_sync_range_index */
! 1192: mco->mco_intern_icache_sync_range_index =
! 1193: cache_r4k_icache_index_inv_32;
1.10 simonb 1194: break;
1195: #ifdef MIPS_DISABLE_L1_CACHE
1196: case 0:
1.48.26.3! skrll 1197: mco->mco_icache_sync_all = no_cache_op;
! 1198: mco->mco_icache_sync_range = no_cache_op_range;
! 1199: mco->mco_icache_sync_range_index = no_cache_op_range_index;
1.10 simonb 1200: break;
1201: #endif
1.48.26.3! skrll 1202: case 64:
! 1203: /* used internally by mipsNN_picache_sync_range */
! 1204: mco->mco_intern_icache_sync_range =
! 1205: cache_r4k_icache_hit_inv_64;
! 1206:
! 1207: /* used internally by mipsNN_picache_sync_range_index */
! 1208: mco->mco_intern_icache_sync_range_index =
! 1209: cache_r4k_icache_index_inv_64;
! 1210: break;
1.48.26.1 skrll 1211: case 128:
1.48.26.3! skrll 1212: #ifdef MIPS64_OCTEON
1.48.26.1 skrll 1213: mco->mco_icache_sync_all = octeon_icache_sync_all;
1214: mco->mco_icache_sync_range = octeon_icache_sync_range;
1215: mco->mco_icache_sync_range_index = octeon_icache_sync_range_index;
1.48.26.3! skrll 1216: #else
! 1217: /* used internally by mipsNN_picache_sync_range */
! 1218: mco->mco_intern_icache_sync_range =
! 1219: cache_r4k_icache_hit_inv_128;
! 1220:
! 1221: /* used internally by mipsNN_picache_sync_range_index */
! 1222: mco->mco_intern_icache_sync_range_index =
! 1223: cache_r4k_icache_index_inv_128;
1.48.26.1 skrll 1224: #endif
1.48.26.3! skrll 1225: break;
1.10 simonb 1226: default:
1.48.26.3! skrll 1227: panic("no Icache ops for %dB lines",
1.45 matt 1228: mci->mci_picache_line_size);
1.10 simonb 1229: }
1230:
1.48.26.3! skrll 1231: mco->mco_pdcache_wbinv_all = mipsNN_pdcache_wbinv_all;
! 1232: mco->mco_pdcache_wbinv_range_index = mipsNN_pdcache_wbinv_range_index;
! 1233:
1.45 matt 1234: switch (mci->mci_pdcache_line_size) {
1.10 simonb 1235: case 16:
1.45 matt 1236: mco->mco_pdcache_wbinv_range =
1.48.26.3! skrll 1237: cache_r4k_pdcache_hit_wb_inv_16;
1.45 matt 1238: mco->mco_pdcache_inv_range =
1.48.26.3! skrll 1239: cache_r4k_pdcache_hit_inv_16;
1.45 matt 1240: mco->mco_pdcache_wb_range =
1.48.26.3! skrll 1241: cache_r4k_pdcache_hit_wb_16;
! 1242:
! 1243: /* used internally by mipsNN_pdcache_wbinv_range_index */
! 1244: mco->mco_intern_pdcache_wbinv_range_index =
! 1245: cache_r4k_pdcache_index_wb_inv_16;
1.10 simonb 1246: break;
1247: case 32:
1.45 matt 1248: mco->mco_pdcache_wbinv_range =
1.48.26.3! skrll 1249: cache_r4k_pdcache_hit_wb_inv_32;
1.45 matt 1250: mco->mco_pdcache_inv_range =
1.48.26.3! skrll 1251: cache_r4k_pdcache_hit_inv_32;
1.45 matt 1252: mco->mco_pdcache_wb_range =
1.48.26.3! skrll 1253: cache_r4k_pdcache_hit_wb_32;
! 1254:
! 1255: /* used internally by mipsNN_pdcache_wbinv_range_index */
! 1256: mco->mco_intern_pdcache_wbinv_range_index =
! 1257: cache_r4k_pdcache_index_wb_inv_32;
1.10 simonb 1258: break;
1.48.26.3! skrll 1259: case 64:
! 1260: mco->mco_pdcache_wbinv_range =
! 1261: cache_r4k_pdcache_hit_wb_inv_64;
! 1262: mco->mco_pdcache_inv_range =
! 1263: cache_r4k_pdcache_hit_inv_64;
! 1264: mco->mco_pdcache_wb_range =
! 1265: cache_r4k_pdcache_hit_wb_64;
! 1266:
! 1267: /* used internally by mipsNN_pdcache_wbinv_range_index */
! 1268: mco->mco_intern_pdcache_wbinv_range_index =
! 1269: cache_r4k_pdcache_index_wb_inv_64;
1.48.26.1 skrll 1270: case 128:
1.48.26.3! skrll 1271: #ifdef MIPS64_OCTEON
! 1272: mco->mco_pdcache_wbinv_all = octeon_pdcache_inv_all;
! 1273: mco->mco_pdcache_wbinv_range = octeon_pdcache_inv_range;
! 1274: mco->mco_pdcache_wbinv_range_index = octeon_pdcache_inv_range_index;
! 1275: mco->mco_pdcache_inv_range = octeon_pdcache_inv_range;
! 1276: mco->mco_pdcache_wb_range = no_cache_op_range;
! 1277: #else
1.48.26.1 skrll 1278: mco->mco_pdcache_wbinv_range =
1.48.26.3! skrll 1279: cache_r4k_pdcache_hit_wb_inv_128;
1.48.26.1 skrll 1280: mco->mco_pdcache_inv_range =
1.48.26.3! skrll 1281: cache_r4k_pdcache_hit_inv_128;
1.48.26.1 skrll 1282: mco->mco_pdcache_wb_range =
1.48.26.3! skrll 1283: cache_r4k_pdcache_hit_wb_128;
! 1284:
! 1285: /* used internally by mipsNN_pdcache_wbinv_range_index */
! 1286: mco->mco_intern_pdcache_wbinv_range_index =
! 1287: cache_r4k_pdcache_index_wb_inv_128;
1.48.26.1 skrll 1288: #endif
1.48.26.3! skrll 1289: break;
1.10 simonb 1290: #ifdef MIPS_DISABLE_L1_CACHE
1291: case 0:
1.48.26.3! skrll 1292: mco->mco_pdcache_wbinv_all = no_cache_op;
! 1293: mco->mco_pdcache_wbinv_range = no_cache_op_range;
! 1294: mco->mco_pdcache_wbinv_range_index = no_cache_op_index;
! 1295: mco->mco_pdcache_inv_range = no_cache_op_range;
! 1296: mco->mco_pdcache_wb_range = no_cache_op_range;
1.10 simonb 1297: break;
1298: #endif
1299: default:
1.48.26.3! skrll 1300: panic("no Dcache ops for %dB lines",
1.45 matt 1301: mci->mci_pdcache_line_size);
1.10 simonb 1302: }
1.14 simonb 1303:
1.48.26.3! skrll 1304: mco->mco_intern_pdcache_sync_all = mco->mco_pdcache_wbinv_all;
! 1305: mco->mco_intern_pdcache_sync_range_index = mco->mco_intern_pdcache_wbinv_range_index;
! 1306: mco->mco_intern_pdcache_sync_range = mco->mco_pdcache_wb_range;
! 1307:
! 1308: if (MIPSNN_CFG1_M & cfg1) {
! 1309: uint32_t cfg2 = mipsNN_cp0_config2_read();
! 1310:
! 1311: switch (MIPSNN_GET(CFG2_SL, cfg2)) {
! 1312: case MIPSNN_CFG2_SL_NONE:
! 1313: break;
! 1314: default:
! 1315: mci->mci_scache_unified = true;
! 1316:
! 1317: mci->mci_sdcache_line_size = MIPSNN_CFG2_SL(cfg2);
! 1318: mci->mci_sdcache_way_size =
! 1319: mci->mci_sdcache_line_size * MIPSNN_CFG2_SS(cfg2);
! 1320: mci->mci_sdcache_ways = MIPSNN_CFG2_SA(cfg2) + 1;
! 1321:
! 1322: /*
! 1323: * Compute the total size and "way mask" for the
! 1324: * secondary Dcache.
! 1325: */
! 1326: mci->mci_sdcache_size =
! 1327: mci->mci_sdcache_way_size * mci->mci_sdcache_ways;
! 1328: mci->mci_sdcache_way_mask =
! 1329: mci->mci_sdcache_way_size - 1;
! 1330:
! 1331: /*
! 1332: * cache is unified so copy data info to inst info.
! 1333: */
! 1334: mci->mci_sicache_line_size = mci->mci_sdcache_line_size;
! 1335: mci->mci_sicache_way_size = mci->mci_sdcache_way_size;
! 1336: mci->mci_sicache_ways = mci->mci_sdcache_ways;
! 1337: mci->mci_sicache_size = mci->mci_sdcache_size;
! 1338: mci->mci_sicache_way_mask = mci->mci_sdcache_way_mask;
! 1339:
! 1340: break;
! 1341: }
! 1342:
! 1343: // Note we don't set up any sd cache ops because we expect that
! 1344: // the coherence checks below will overwrite them with no ops.
! 1345:
! 1346: #ifdef CACHE_DEBUG
! 1347: if (mci->mci_sdcache_line_size != 0) {
! 1348: printf("MIPS32/64 params: %s: line=%d, total=%d, "
! 1349: "ways=%d, sets=%d, colors=%d\n",
! 1350: "SDcache",
! 1351: mci->mci_sdcache_line_size,
! 1352: mci->mci_sdcache_way_size * mci->mci_sdcache_ways,
! 1353: mci->mci_sdcache_ways,
! 1354: mci->mci_sdcache_way_size
! 1355: / mci->mci_sdcache_line_size,
! 1356: mci->mci_sdcache_way_size >> PAGE_SHIFT);
! 1357: }
! 1358: #endif
! 1359:
! 1360: switch (MIPSNN_GET(CFG2_TL, cfg2)) {
! 1361: case MIPSNN_CFG2_TL_NONE:
! 1362: break;
! 1363: default:
! 1364: mci->mci_tcache_line_size = MIPSNN_CFG2_TL(cfg2);
! 1365: mci->mci_tcache_way_size =
! 1366: mci->mci_tcache_line_size * MIPSNN_CFG2_TS(cfg2);
! 1367: mci->mci_tcache_ways = MIPSNN_CFG2_TA(cfg2) + 1;
! 1368:
! 1369: /*
! 1370: * Compute the total size and "way mask" for the
! 1371: * secondary Dcache.
! 1372: */
! 1373: mci->mci_tcache_size =
! 1374: mci->mci_tcache_way_size * mci->mci_tcache_ways;
! 1375: mci->mci_tcache_way_mask =
! 1376: mci->mci_tcache_way_size - 1;
! 1377: break;
! 1378: }
! 1379: }
! 1380:
! 1381: /*
! 1382: * calculate the alias masks and from them set to virtual alias flags.
! 1383: */
! 1384: mci->mci_cache_alias_mask = mci->mci_pdcache_way_mask & -PAGE_SIZE;
! 1385: mci->mci_cache_virtual_alias = (mci->mci_cache_alias_mask != 0);
! 1386:
! 1387: mci->mci_icache_alias_mask = mci->mci_picache_way_mask & -PAGE_SIZE;
! 1388: mci->mci_icache_virtual_alias = (mci->mci_icache_alias_mask != 0);
! 1389:
1.48 matt 1390: /*
1391: * RMI (NetLogic/Broadcom) don't support WB (op 6) so we have to make
1392: * do with WBINV (op 5). This is merely for correctness since because
1393: * the caches are coherent, these routines will become noops in a bit.
1394: */
1395: if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_RMI) {
1396: mco->mco_pdcache_wb_range = mco->mco_pdcache_wbinv_range;
1.48.26.3! skrll 1397: mco->mco_intern_pdcache_sync_range = mco->mco_pdcache_wbinv_range;
! 1398: if (MIPSNN_GET(CFG_AR, cfg) == MIPSNN_CFG_AR_REV2) {
! 1399: mci->mci_pdcache_write_through = true;
! 1400: mci->mci_sdcache_write_through = false;
! 1401: KASSERT(PAGE_SIZE >= mci->mci_picache_way_size
! 1402: || MIPS_ICACHE_VIRTUAL_ALIAS);
! 1403: } else {
! 1404: KASSERT(MIPS_CACHE_VIRTUAL_ALIAS == 0);
! 1405: KASSERT(MIPS_ICACHE_VIRTUAL_ALIAS == 0);
! 1406: }
! 1407: } else if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_MTI) {
! 1408: /*
! 1409: * All MTI cores share a (mostly) common config7 defintion.
! 1410: * Use it to determine if the caches have virtual aliases.
! 1411: * If the core doesn't have a config7 register, its caches
! 1412: * are too small or have too many ways to have aliases.
! 1413: */
! 1414: if (opts->mips_cpu->cpu_cp0flags & MIPS_CP0FL_CONFIG7) {
! 1415: const uint32_t cfg7 = mipsNN_cp0_config7_read();
! 1416: if (cfg7 & MIPSNN_MTI_CFG7_AR) {
! 1417: /* [Data] Alias Removal Present */
! 1418: mci->mci_cache_virtual_alias = false;
! 1419: }
! 1420: if (cfg7 & MIPSNN_MTI_CFG7_IAR) {
! 1421: /* Instruction Alias Removal Present */
! 1422: mci->mci_icache_virtual_alias = false;
! 1423: }
! 1424: #if 0
! 1425: } else {
! 1426: KASSERT(mci->mci_pdcache_way_size <= PAGE_SIZE);
! 1427: KASSERT(mci->mci_picache_way_size <= PAGE_SIZE);
! 1428: #endif
! 1429: }
1.48 matt 1430: }
1431:
1.14 simonb 1432: mipsNN_cache_init(cfg, cfg1);
1.15 simonb 1433:
1.48.26.3! skrll 1434: if (opts->mips_cpu_flags &
1.15 simonb 1435: (CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_I_D_CACHE_COHERENT)) {
1436: #ifdef CACHE_DEBUG
1437: printf(" Dcache is coherent\n");
1438: #endif
1.48.26.3! skrll 1439: mco->mco_pdcache_wbinv_all = no_cache_op;
! 1440: mco->mco_pdcache_wbinv_range = no_cache_op_range;
! 1441: mco->mco_pdcache_wbinv_range_index = no_cache_op_range_index;
! 1442: mco->mco_pdcache_inv_range = no_cache_op_range;
! 1443: mco->mco_pdcache_wb_range = no_cache_op_range;
! 1444: mco->mco_sdcache_wbinv_all = no_cache_op;
! 1445: mco->mco_sdcache_wbinv_range = no_cache_op_range;
! 1446: mco->mco_sdcache_wbinv_range_index = no_cache_op_range_index;
! 1447: mco->mco_sdcache_inv_range = no_cache_op_range;
! 1448: mco->mco_sdcache_wb_range = no_cache_op_range;
1.15 simonb 1449: }
1.48.26.3! skrll 1450: if (opts->mips_cpu_flags & CPU_MIPS_I_D_CACHE_COHERENT) {
1.15 simonb 1451: #ifdef CACHE_DEBUG
1452: printf(" Icache is coherent against Dcache\n");
1453: #endif
1.48.26.3! skrll 1454: mco->mco_intern_pdcache_sync_all = no_cache_op;
! 1455: mco->mco_intern_pdcache_sync_range_index = no_cache_op_range_index;
! 1456: mco->mco_intern_pdcache_sync_range = no_cache_op_range;
1.15 simonb 1457: }
1.10 simonb 1458: }
1.46 matt 1459: #endif /* MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2 > 0 */
CVSweb <webmaster@jp.NetBSD.org>