[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.8.1

1.48.8.1! jdolecek    1: /*     $NetBSD$        */
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.8.1! jdolecek   71: __KERNEL_RCSID(0, "$NetBSD$");
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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.48.8.1! jdolecek  413:                /* no VCE support if there is no L2 cache */
        !           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.8.1! jdolecek  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.8.1! jdolecek  423:                            cache_r4k_icache_hit_inv_16;
1.45      matt      424:                        mco->mco_icache_sync_range_index =
1.48.8.1! jdolecek  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.8.1! jdolecek  430:                            cache_r4k_icache_hit_inv_32;
1.45      matt      431:                        mco->mco_icache_sync_range_index =
1.48.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  444:                            cache_r4k_pdcache_hit_wb_inv_16;
1.45      matt      445:                        mco->mco_pdcache_wbinv_range_index =
1.48.8.1! jdolecek  446:                            cache_r4k_pdcache_index_wb_inv_16;
1.45      matt      447:                        mco->mco_pdcache_inv_range =
1.48.8.1! jdolecek  448:                            cache_r4k_pdcache_hit_inv_16;
1.45      matt      449:                        mco->mco_pdcache_wb_range =
1.48.8.1! jdolecek  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.8.1! jdolecek  455:                            cache_r4k_pdcache_hit_wb_inv_32;
1.45      matt      456:                        mco->mco_pdcache_wbinv_range_index =
1.48.8.1! jdolecek  457:                            cache_r4k_pdcache_index_wb_inv_32;
1.45      matt      458:                        mco->mco_pdcache_inv_range =
1.48.8.1! jdolecek  459:                            cache_r4k_pdcache_hit_inv_32;
1.45      matt      460:                        mco->mco_pdcache_wb_range =
1.48.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  505:                        panic("r5k picache line size %u",
1.45      matt      506:                            mci->mci_picache_line_size);
1.2       thorpej   507:                }
                    508:
1.48.8.1! jdolecek  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.8.1! jdolecek  516:                            cache_r4k_pdcache_hit_wb_inv_16;
1.45      matt      517:                        mco->mco_pdcache_inv_range =
1.48.8.1! jdolecek  518:                            cache_r4k_pdcache_hit_inv_16;
1.45      matt      519:                        mco->mco_pdcache_wb_range =
1.48.8.1! jdolecek  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.8.1! jdolecek  529:                            cache_r4k_pdcache_hit_wb_inv_32;
1.45      matt      530:                        mco->mco_pdcache_inv_range =
1.48.8.1! jdolecek  531:                            cache_r4k_pdcache_hit_inv_32;
1.45      matt      532:                        mco->mco_pdcache_wb_range =
1.48.8.1! jdolecek  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.8.1! jdolecek  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.8.1! jdolecek  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)
        !           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.8.1! jdolecek  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.8.1! jdolecek  665: #if (MIPS2 + MIPS3 + MIPS4) > 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.8.1! jdolecek  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.8.1! jdolecek  675: #if (MIPS2 + MIPS3 + MIPS4) > 0
        !           676:                if (mci->mci_cache_virtual_alias)
        !           677:                        mci->mci_cache_alias_mask =
        !           678:                            mci->mci_pdcache_way_mask & -PAGE_SIZE;
        !           679: #endif
1.2       thorpej   680:        }
                    681:
1.48.8.1! jdolecek  682: #if (MIPS2 + MIPS3 + MIPS4) > 0
        !           683:        if (mci->mci_cache_virtual_alias) {
        !           684:                mci->mci_cache_prefer_mask = mci->mci_pdcache_way_mask;
        !           685:
        !           686:                uvmexp.ncolors = (mci->mci_cache_prefer_mask >> PAGE_SHIFT) + 1;
        !           687:        }
        !           688: #endif
        !           689:
1.4       thorpej   690:        mips_dcache_compute_align();
                    691:
1.45      matt      692:        if (mci->mci_sdcache_line_size == 0)
1.2       thorpej   693:                return;
                    694:
                    695:        /*
                    696:         * Configure the secondary cache.
                    697:         */
                    698:        switch (MIPS_PRID_IMPL(cpu_id)) {
1.10      simonb    699: #if defined(MIPS3) || defined(MIPS4)
1.2       thorpej   700:        case MIPS_R4000:
1.7       shin      701:                /*
1.30      tsutsui   702:                 * R4000/R4400 detects virtual alias by VCE as if
                    703:                 * its primary cache size were 32KB, because it always
                    704:                 * compares 3 bits of vaddr[14:12] which causes
                    705:                 * primary cache miss and PIdx[2:0] in the secondary
                    706:                 * cache tag regardless of its primary cache size.
                    707:                 * i.e. VCE could happen even if there is no actual
                    708:                 * virtual alias on its 8KB or 16KB primary cache
                    709:                 * which has only 1 or 2 bit valid PIdx in 4KB page.
                    710:                 * Actual primary cache size is ignored wrt VCE
                    711:                 * and virtual aliases are resolved by the VCE hander,
                    712:                 * but it's still worth to avoid unnecessary VCE by
                    713:                 * setting alias mask and prefer mask to 32K, though
                    714:                 * some other possible aliases (maybe caused by KSEG0
                    715:                 * accesses which can't be managed by PMAP_PREFER(9))
                    716:                 * will still be resolved by the VCED/VCEI handler.
1.27      tsutsui   717:                 */
1.45      matt      718:                mci->mci_cache_alias_mask =
1.30      tsutsui   719:                    (MIPS3_MAX_PCACHE_SIZE - 1) & ~PAGE_MASK;   /* va[14:12] */
1.45      matt      720:                mci->mci_cache_prefer_mask = MIPS3_MAX_PCACHE_SIZE - 1;
1.30      tsutsui   721:
1.48.8.1! jdolecek  722:                mci->mci_icache_virtual_alias = false;
        !           723:                mci->mci_cache_virtual_alias = false;
1.7       shin      724:                /* FALLTHROUGH */
1.2       thorpej   725:        case MIPS_R4600:
                    726: #ifdef ENABLE_MIPS_R4700
                    727:        case MIPS_R4700:
                    728: #endif
1.45      matt      729:                switch (mci->mci_sdcache_ways) {
1.2       thorpej   730:                case 1:
1.48.8.1! jdolecek  731:                        mco->mco_sdcache_wbinv_all =
        !           732:                            r4k_sdcache_wbinv_all_generic;
1.45      matt      733:                        switch (mci->mci_sdcache_line_size) {
1.48.8.1! jdolecek  734:                        case 16:
        !           735:                                mco->mco_sdcache_wbinv_range =
        !           736:                                    cache_r4k_sdcache_hit_wb_inv_16;
        !           737:                                mco->mco_sdcache_wbinv_range_index =
        !           738:                                    cache_r4k_sdcache_index_wb_inv_16;
        !           739:                                mco->mco_sdcache_inv_range =
        !           740:                                    cache_r4k_sdcache_hit_inv_16;
        !           741:                                mco->mco_sdcache_wb_range =
        !           742:                                    cache_r4k_sdcache_hit_wb_16;
        !           743:                                break;
        !           744:
1.2       thorpej   745:                        case 32:
1.45      matt      746:                                mco->mco_sdcache_wbinv_range =
1.48.8.1! jdolecek  747:                                    cache_r4k_sdcache_hit_wb_inv_32;
1.45      matt      748:                                mco->mco_sdcache_wbinv_range_index =
1.48.8.1! jdolecek  749:                                    cache_r4k_sdcache_index_wb_inv_32;
1.45      matt      750:                                mco->mco_sdcache_inv_range =
1.48.8.1! jdolecek  751:                                    cache_r4k_sdcache_hit_inv_32;
1.45      matt      752:                                mco->mco_sdcache_wb_range =
1.48.8.1! jdolecek  753:                                    cache_r4k_sdcache_hit_wb_32;
1.2       thorpej   754:                                break;
                    755:
                    756:                        case 64:
1.45      matt      757:                                mco->mco_sdcache_wbinv_range =
1.48.8.1! jdolecek  758:                                    cache_r4k_sdcache_hit_wb_inv_64;
1.45      matt      759:                                mco->mco_sdcache_wbinv_range_index =
1.48.8.1! jdolecek  760:                                    cache_r4k_sdcache_index_wb_inv_64;
1.45      matt      761:                                mco->mco_sdcache_inv_range =
1.48.8.1! jdolecek  762:                                    cache_r4k_sdcache_hit_inv_64;
1.45      matt      763:                                mco->mco_sdcache_wb_range =
1.48.8.1! jdolecek  764:                                    cache_r4k_sdcache_hit_wb_64;
1.3       thorpej   765:                                break;
                    766:
                    767:                        case 128:
1.45      matt      768:                                mco->mco_sdcache_wbinv_range =
1.48.8.1! jdolecek  769:                                    cache_r4k_sdcache_hit_wb_inv_128;
1.45      matt      770:                                mco->mco_sdcache_wbinv_range_index =
1.48.8.1! jdolecek  771:                                    cache_r4k_sdcache_index_wb_inv_128;
1.45      matt      772:                                mco->mco_sdcache_inv_range =
1.48.8.1! jdolecek  773:                                    cache_r4k_sdcache_hit_inv_128;
1.45      matt      774:                                mco->mco_sdcache_wb_range =
1.48.8.1! jdolecek  775:                                    cache_r4k_sdcache_hit_wb_128;
1.2       thorpej   776:                                break;
                    777:
                    778:                        default:
1.12      provos    779:                                panic("r4k sdcache %d way line size %d",
1.45      matt      780:                                    mci->mci_sdcache_ways, mci->mci_sdcache_line_size);
1.2       thorpej   781:                        }
                    782:                        break;
                    783:
                    784:                default:
1.12      provos    785:                        panic("r4k sdcache %d way line size %d",
1.45      matt      786:                            mci->mci_sdcache_ways, mci->mci_sdcache_line_size);
1.2       thorpej   787:                }
1.18      rafal     788:                break;
                    789: #ifndef ENABLE_MIPS_R3NKK
                    790:        case MIPS_R5000:
                    791: #endif
                    792:        case MIPS_RM5200:
1.45      matt      793:                mci->mci_sdcache_write_through = true;
                    794:                mco->mco_sdcache_wbinv_all =
1.18      rafal     795:                    r5k_sdcache_wbinv_all;
1.45      matt      796:                mco->mco_sdcache_wbinv_range =
1.18      rafal     797:                    r5k_sdcache_wbinv_range;
1.45      matt      798:                mco->mco_sdcache_wbinv_range_index =
1.25      sekiya    799:                    r5k_sdcache_wbinv_range_index;
1.45      matt      800:                mco->mco_sdcache_inv_range =
1.18      rafal     801:                    r5k_sdcache_wbinv_range;
1.48.8.1! jdolecek  802:                mco->mco_sdcache_wb_range = no_cache_op_range;
1.2       thorpej   803:                break;
1.21      tsutsui   804: #ifdef ENABLE_MIPS4_CACHE_R10K
                    805:        case MIPS_R10000:
1.23      shin      806:        case MIPS_R12000:
                    807:        case MIPS_R14000:
1.45      matt      808:                mco->mco_sdcache_wbinv_all =
1.23      shin      809:                    r10k_sdcache_wbinv_all;
1.45      matt      810:                mco->mco_sdcache_wbinv_range =
1.23      shin      811:                    r10k_sdcache_wbinv_range;
1.45      matt      812:                mco->mco_sdcache_wbinv_range_index =
1.23      shin      813:                    r10k_sdcache_wbinv_range_index;
1.45      matt      814:                mco->mco_sdcache_inv_range =
1.23      shin      815:                    r10k_sdcache_inv_range;
1.45      matt      816:                mco->mco_sdcache_wb_range =
1.23      shin      817:                    r10k_sdcache_wb_range;
1.21      tsutsui   818:                break;
                    819: #endif /* ENABLE_MIPS4_CACHE_R10K */
1.36      matt      820: #ifdef MIPS3_LOONGSON2
1.34      matt      821:        case MIPS_LOONGSON2:
1.47      bouyer    822:                mci->mci_sdcache_ways = 4;
                    823:                mci->mci_sdcache_size = 512*1024;
                    824:                mci->mci_scache_unified = 1;
1.34      matt      825:
1.47      bouyer    826:                mco->mco_sdcache_wbinv_all =
1.39      matt      827:                    ls2_sdcache_wbinv_all;
1.47      bouyer    828:                mco->mco_sdcache_wbinv_range =
1.39      matt      829:                    ls2_sdcache_wbinv_range;
1.47      bouyer    830:                mco->mco_sdcache_wbinv_range_index =
1.39      matt      831:                    ls2_sdcache_wbinv_range_index;
1.47      bouyer    832:                mco->mco_sdcache_inv_range =
1.39      matt      833:                    ls2_sdcache_inv_range;
1.47      bouyer    834:                mco->mco_sdcache_wb_range =
1.39      matt      835:                    ls2_sdcache_wb_range;
1.37      matt      836:
                    837:                /*
                    838:                 * The secondary cache is physically indexed and tagged
                    839:                 */
1.34      matt      840:                break;
                    841: #endif
1.36      matt      842: #endif /* MIPS3 || MIPS4 */
1.2       thorpej   843:
                    844:        default:
1.12      provos    845:                panic("can't handle secondary cache on impl 0x%x",
1.2       thorpej   846:                    MIPS_PRID_IMPL(cpu_id));
                    847:        }
                    848:
                    849:        /*
                    850:         * Compute the "way mask" for each secondary cache.
                    851:         */
1.45      matt      852:        if (mci->mci_sdcache_size) {
                    853:                KASSERT(mci->mci_sdcache_ways != 0);
1.48.8.1! jdolecek  854:                mci->mci_sdcache_way_size = mci->mci_sdcache_size / mci->mci_sdcache_ways;
1.45      matt      855:                mci->mci_sdcache_way_mask = mci->mci_sdcache_way_size - 1;
1.2       thorpej   856:        }
1.4       thorpej   857:
                    858:        mips_dcache_compute_align();
1.2       thorpej   859: }
                    860:
1.44      uebayasi  861: #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4)
1.43      pooka     862: void
                    863: mips_config_cache_emips(void)
                    864: {
1.45      matt      865:        struct mips_cache_info * const mci = &mips_cache_info;
                    866:        struct mips_cache_ops * const mco = &mips_cache_ops;
                    867:        const mips_prid_t cpu_id = mips_options.mips_cpu_id;
1.43      pooka     868:        KASSERT(PAGE_SIZE != 0);
                    869:
                    870:        /*
                    871:         * Configure primary caches.
                    872:         */
                    873:        switch (MIPS_PRID_IMPL(cpu_id)) {
                    874:        case MIPS_eMIPS:
1.45      matt      875:                mci->mci_picache_size = 0;
                    876:                mci->mci_pdcache_size = 0;
1.43      pooka     877:
1.45      matt      878:                mci->mci_picache_line_size = 4;
                    879:                mci->mci_pdcache_line_size = 4;
1.43      pooka     880:
1.45      matt      881:                mci->mci_picache_ways = 1;
                    882:                mci->mci_pdcache_ways = 1;
1.43      pooka     883:
1.48.8.1! jdolecek  884:                mci->mci_pdcache_write_through = true;
1.45      matt      885:
                    886:                mco->mco_icache_sync_all = no_cache_op;
                    887:                mco->mco_icache_sync_range = no_cache_op_range;
1.48.8.1! jdolecek  888:                mco->mco_icache_sync_range_index = no_cache_op_range_index;
1.45      matt      889:
                    890:                mco->mco_pdcache_wbinv_all = no_cache_op;
                    891:                mco->mco_pdcache_wbinv_range = no_cache_op_range;
1.48.8.1! jdolecek  892:                mco->mco_pdcache_wbinv_range_index = no_cache_op_range_index;
1.45      matt      893:                mco->mco_pdcache_inv_range = no_cache_op_range;
                    894:                mco->mco_pdcache_wb_range = no_cache_op_range;
1.43      pooka     895:
                    896:                uvmexp.ncolors = 1;
                    897:                break;
                    898:
                    899:        default:
1.45      matt      900:                panic("%s: unsupported eMIPS", __func__);
1.43      pooka     901:        }
                    902: }
1.44      uebayasi  903: #endif
1.43      pooka     904:
1.2       thorpej   905: #ifdef MIPS1
                    906: #ifdef ENABLE_MIPS_TX3900
                    907: /*
                    908:  * tx3900_get_cache_config:
                    909:  *
                    910:  *     Fetch cache size information for the TX3900.
                    911:  */
                    912: void
                    913: tx3900_get_cache_config(void)
                    914: {
1.45      matt      915:        struct mips_cache_info * const mci = &mips_cache_info;
1.2       thorpej   916:        uint32_t config;
                    917:
                    918:        config = tx3900_cp0_config_read();
                    919:
1.45      matt      920:        mci->mci_picache_size = R3900_C_SIZE_MIN <<
1.2       thorpej   921:            ((config & R3900_CONFIG_ICS_MASK) >> R3900_CONFIG_ICS_SHIFT);
                    922:
1.45      matt      923:        mci->mci_pdcache_size = R3900_C_SIZE_MIN <<
1.2       thorpej   924:            ((config & R3900_CONFIG_DCS_MASK) >> R3900_CONFIG_DCS_SHIFT);
                    925: }
                    926:
                    927: /*
                    928:  * tx3920_get_cache_config:
                    929:  *
                    930:  *     Fetch cache size information for the TX3920.
                    931:  */
                    932: void
                    933: tx3920_get_cache_config(void)
                    934: {
1.45      matt      935:        struct mips_cache_info * const mci = &mips_cache_info;
1.2       thorpej   936:
                    937:        /* Size is the same as TX3900. */
                    938:        tx3900_get_cache_config();
                    939:
                    940:        /* Now determine write-through/write-back mode. */
                    941:        if ((tx3900_cp0_config_read() & R3900_CONFIG_WBON) == 0)
1.45      matt      942:                mci->mci_pdcache_write_through = true;
1.2       thorpej   943: }
1.9       uch       944:
                    945: /*
                    946:  * tx39_cache_config_write_through:
                    947:  *
                    948:  *     TX3922 write-through D-cache mode.
                    949:  *     for TX3912, no meaning. (no write-back mode)
                    950:  */
                    951: void
                    952: tx39_cache_config_write_through(void)
                    953: {
                    954:        u_int32_t r;
                    955:
                    956:        mips_dcache_wbinv_all();
                    957:
1.33      perry     958:        __asm volatile("mfc0 %0, $3" : "=r"(r));
1.9       uch       959:        r &= 0xffffdfff;
1.33      perry     960:        __asm volatile("mtc0 %0, $3" : : "r"(r));
1.9       uch       961: }
                    962:
1.2       thorpej   963: #endif /* ENABLE_MIPS_TX3900 */
                    964: #endif /* MIPS1 */
                    965:
1.10      simonb    966: #if defined(MIPS3) || defined(MIPS4)
1.2       thorpej   967: /*
                    968:  * mips3_get_cache_config:
                    969:  *
                    970:  *     Fetch the cache config information for a MIPS-3 or MIPS-4
                    971:  *     processor (virtually-indexed cache).
                    972:  *
                    973:  *     NOTE: Fetching the size of the secondary cache is something
                    974:  *     that platform specific code has to do.  We'd appreciate it
                    975:  *     if they initialized the size before now.
                    976:  *
                    977:  *     ALSO NOTE: The number of ways in the cache must already be
                    978:  *     initialized.
                    979:  */
                    980: void
                    981: mips3_get_cache_config(int csizebase)
                    982: {
1.45      matt      983:        struct mips_cache_info * const mci = &mips_cache_info;
                    984:        const mips_prid_t cpu_id = mips_options.mips_cpu_id;
                    985:        bool has_sdcache_enable = false;
1.2       thorpej   986:        uint32_t config = mips3_cp0_config_read();
                    987:
1.45      matt      988:        mci->mci_picache_size = MIPS3_CONFIG_CACHE_SIZE(config,
1.2       thorpej   989:            MIPS3_CONFIG_IC_MASK, csizebase, MIPS3_CONFIG_IC_SHIFT);
1.45      matt      990:        mci->mci_picache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config,
1.2       thorpej   991:            MIPS3_CONFIG_IB);
                    992:
1.45      matt      993:        mci->mci_pdcache_size = MIPS3_CONFIG_CACHE_SIZE(config,
1.2       thorpej   994:            MIPS3_CONFIG_DC_MASK, csizebase, MIPS3_CONFIG_DC_SHIFT);
1.45      matt      995:        mci->mci_pdcache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config,
1.2       thorpej   996:            MIPS3_CONFIG_DB);
                    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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 1075: #ifdef MIPS64_OCTEON
        !          1076:                mci->mci_pdcache_line_size = 128;
        !          1077:                mci->mci_pdcache_way_size = 256;
        !          1078:                mci->mci_pdcache_ways = 64;
        !          1079:                mci->mci_pdcache_write_through = true;
        !          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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 1159:        if (mci->mci_pdcache_line_size == 0) {
1.10      simonb   1160:                printf("MIPS32/64 params: no Dcache\n");
1.48.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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;
        !          1211:        case 128:
        !          1212: #ifdef MIPS64_OCTEON
        !          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;
        !          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;
        !          1224: #endif
        !          1225:                break;
1.10      simonb   1226:        default:
1.48.8.1! jdolecek 1227:                panic("no Icache ops for %dB lines",
1.45      matt     1228:                    mci->mci_picache_line_size);
1.10      simonb   1229:        }
                   1230:
1.48.8.1! jdolecek 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.8.1! jdolecek 1237:                    cache_r4k_pdcache_hit_wb_inv_16;
1.45      matt     1238:                mco->mco_pdcache_inv_range =
1.48.8.1! jdolecek 1239:                    cache_r4k_pdcache_hit_inv_16;
1.45      matt     1240:                mco->mco_pdcache_wb_range =
1.48.8.1! jdolecek 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.8.1! jdolecek 1249:                    cache_r4k_pdcache_hit_wb_inv_32;
1.45      matt     1250:                mco->mco_pdcache_inv_range =
1.48.8.1! jdolecek 1251:                    cache_r4k_pdcache_hit_inv_32;
1.45      matt     1252:                mco->mco_pdcache_wb_range =
1.48.8.1! jdolecek 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.8.1! jdolecek 1259:        case 64:
1.45      matt     1260:                mco->mco_pdcache_wbinv_range =
1.48.8.1! jdolecek 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 */
1.45      matt     1268:                mco->mco_intern_pdcache_wbinv_range_index =
1.48.8.1! jdolecek 1269:                    cache_r4k_pdcache_index_wb_inv_64;
        !          1270:        case 128:
        !          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
        !          1278:                mco->mco_pdcache_wbinv_range =
        !          1279:                    cache_r4k_pdcache_hit_wb_inv_128;
1.45      matt     1280:                mco->mco_pdcache_inv_range =
1.48.8.1! jdolecek 1281:                    cache_r4k_pdcache_hit_inv_128;
1.45      matt     1282:                mco->mco_pdcache_wb_range =
1.48.8.1! jdolecek 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;
        !          1288: #endif
        !          1289:                break;
        !          1290: #ifdef MIPS_DISABLE_L1_CACHE
        !          1291:        case 0:
        !          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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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.8.1! jdolecek 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>