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

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

CVSweb <webmaster@jp.NetBSD.org>