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

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

CVSweb <webmaster@jp.NetBSD.org>