[BACK]Return to cache.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / mips / mips

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>