[BACK]Return to cache_r5k.S CVS log [TXT][DIR] Up to [local] / sys / arch / mips64 / mips64

Annotation of sys/arch/mips64/mips64/cache_r5k.S, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: cache_r5k.S,v 1.19 2007/06/18 20:25:55 miod Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 1998-2004 Opsycon AB (www.opsycon.se)
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     16:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     18:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
                     19:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     20:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     21:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     25:  * SUCH DAMAGE.
                     26:  *
                     27:  */
                     28:
                     29: /*
                     30:  *  NOTE!
                     31:  *
                     32:  *  This code does not support caches with other linesize than 32.
                     33:  *  Neither will it support R4000 or R4400 Secondary caches. These
                     34:  *  configurations will need another set of cache functions.
                     35:  *
                     36:  *  Processors supported:
                     37:  *  R4600/R4700
                     38:  *  R5000
                     39:  *  RM52xx
                     40:  *  RM7xxx
                     41:  *  RM9xxx
                     42:  */
                     43:
                     44: #include <sys/errno.h>
                     45: #include <sys/syscall.h>
                     46:
                     47: #include <machine/param.h>
                     48: #include <machine/psl.h>
                     49: #include <machine/asm.h>
                     50: #include <machine/cpu.h>
                     51: #include <machine/regnum.h>
                     52: #include <machine/pte.h>
                     53:
                     54: #include "assym.h"
                     55:
                     56:        .set    mips3
                     57:
                     58: #define        LOAD_XKPHYS(reg, cca) \
                     59:        li      reg, cca | 0x10; \
                     60:        dsll    reg, reg, 59
                     61:
                     62: /*
                     63:  *  Skip the .h file. Noone else need to know!
                     64:  */
                     65:
                     66: #define        IndexInvalidate_I       0x00
                     67: #define        IndexWBInvalidate_D     0x01
                     68: #define        IndexFlashInvalidate_T  0x02
                     69: #define        IndexWBInvalidate_S     0x03
                     70:
                     71: #define        IndexLoadTag_I          0x04
                     72: #define        IndexLoadTag_D          0x05
                     73: #define        IndexLoadTag_T          0x06
                     74: #define        IndexLoadTag_S          0x07
                     75:
                     76: #define        IndexStoreTag_I         0x08
                     77: #define        IndexStoreTag_D         0x09
                     78: #define        IndexStoreTag_T         0x0a
                     79: #define        IndexStoreTag_S         0x0b
                     80:
                     81: #define        CreateDirtyExclusive    0x09
                     82:
                     83: #define        HitInvalidate_I         0x10
                     84: #define        HitInvalidate_D         0x11
                     85: #define        HitInvalidate_S         0x13
                     86:
                     87: #define        Fill_I                  0x14
                     88: #define        HitWBInvalidate_D       0x15
                     89: #define        InvalidatePage_T        0x16
                     90: #define        HitWBInvalidate_S       0x17
                     91:
                     92: #define        HitWB_I                 0x18
                     93: #define        HitWB_D                 0x19
                     94: #define        HitWB_S                 0x1b
                     95:
                     96: #define        InvalidateSecondaryPage 0x17    /* Only RM527[0-1] */
                     97:
                     98:
                     99:
                    100: /*
                    101:  *  R5000 config register bits.
                    102:  */
                    103: #define        CF_5_SE         (1 << 12)       /* Secondary cache enable */
                    104: #define        CF_5_SC         (1 << 17)       /* Secondary cache not present */
                    105: #define        CF_5_SS         (3 << 20)       /* Secondary cache size */
                    106: #define        CF_5_SS_AL      20              /* Shift to align */
                    107:
                    108: /*
                    109:  *  RM52xx config register bits. (like R5000)
                    110:  */
                    111: #define        CF_52_SE        (1 << 12)       /* Secondary cache enable */
                    112: #define        CF_52_SC        (1 << 17)       /* Secondary cache not present */
                    113: #define        CF_52_SS        (3 << 20)       /* Secondary cache size */
                    114: #define        CF_52_SS_AL     20              /* Shift to align */
                    115:
                    116: /*
                    117:  *  RM7000 config register bits.
                    118:  */
                    119: #define        CF_7_SE         (1 << 3)        /* Secondary cache enable */
                    120: #define        CF_7_SC         (1 << 31)       /* Secondary cache not present */
                    121: #define        CF_7_TE         (1 << 12)       /* Tertiary cache enable */
                    122: #define        CF_7_TC         (1 << 17)       /* Tertiary cache not present */
                    123: #define        CF_7_TS         (3 << 20)       /* Tertiary cache size */
                    124: #define        CF_7_TS_AL      20              /* Shift to align */
                    125:
                    126: /*
                    127:  *  Define cache type definition bits. NOTE! the 3 lsb may NOT change!
                    128:  */
                    129: #define        CTYPE_DIR               0x0001  /* Cache is direct mapped */
                    130: #define        CTYPE_2WAY              0x0002  /* Cache is TWO way */
                    131: #define        CTYPE_4WAY              0x0004  /* Cache is FOUR way */
                    132: #define        CTYPE_WAYMASK           0x0007
                    133:
                    134: #define        CTYPE_HAS_IL2           0x0100  /* Internal L2 Cache present */
                    135: #define        CTYPE_HAS_XL2           0x0200  /* External L2 Cache present */
                    136: #define        CTYPE_HAS_XL3           0x0400  /* External L3 Cache present */
                    137:
                    138: /*
                    139:  *  Due to a flaw in RM7000 1.x processors a pipleine 'drain' is
                    140:  *  required after some mtc0 instructions.
                    141:  *  Ten nops in sequence does the trick.
                    142:  */
                    143: #define NOP10  nop;nop;nop;nop;nop;\
                    144:                nop;nop;nop;nop;nop     /* Two cycles for dual issue machine */
                    145:
                    146:        .set    noreorder               # Noreorder is default style!
                    147:
                    148: /*----------------------------------------------------------------------------
                    149:  *
                    150:  * Mips5k_ConfigCache --
                    151:  *
                    152:  *     Size and configure the caches.
                    153:  *     NOTE: should only be called from mips_init().
                    154:  *
                    155:  * Results:
                    156:  *     Returns the value of the cpu configuration register.
                    157:  *
                    158:  * Side effects:
                    159:  *     The size of the data cache is stored into CpuPrimaryDataCacheSize.
                    160:  *     The size of instruction cache is stored into CpuPrimaryInstCacheSize.
                    161:  *     Alignment mask for cache aliasing test is stored in CpuCacheAliasMask.
                    162:  *     CpuSecondaryCacheSize is set to the size of the secondary cache.
                    163:  *     CpuTertiaryCacheSize is set to the size of the tertiary cache.
                    164:  *     CpuNWayCache is set to 0 for direct mapped caches, 2 for two way
                    165:  *     caches and 4 for four way caches. This primarily indicates the
                    166:  *     primary cache associativity.
                    167:  *
                    168:  * Allocation:
                    169:  *     ta0, ta1 ta2 used to hold I and D set size and Alias mask.
                    170:  *
                    171:  *----------------------------------------------------------------------------
                    172:  */
                    173: LEAF(Mips5k_ConfigCache, 0)
                    174:        .set    noreorder
                    175:        LA      v0, 1f
                    176:        LA      v1, KSEG1_BASE
                    177:        or      v0, v1
                    178:        jr      v0                              # Switch to uncached.
                    179:        nop
                    180: 1:
                    181:        mfc0    v1, COP_0_PRID                  # read processor ID register
                    182:        mfc0    v0, COP_0_CONFIG                # Get configuration register
                    183:
                    184:        srl     t1, v0, 9                       # Get I cache size.
                    185:        and     t1, 3
                    186:        li      t2, 4096
                    187:        sllv    ta0, t2, t1                     # ta0 = Initial I set size.
                    188:
                    189:        and     t2, v0, 0x20
                    190:        srl     t2, t2, 1                       # Get I cache line size.
                    191:        addu    t2, t2, 16
                    192:        sw      t2, CpuPrimaryInstCacheLSize
                    193:
                    194:        srl     t1, v0, 6                       # Get D cache size.
                    195:        and     t1, 3
                    196:        li      t2, 4096                        # Fixed page size.
                    197:        sllv    ta1, t2, t1
                    198:
                    199:        and     t2, v0, 0x10
                    200:        addu    t2, t2, 16                      # Get D cache line size.
                    201:        sw      t2, CpuPrimaryDataCacheLSize
                    202:
                    203:        li      t2, CTYPE_2WAY                  # Assume two way cache
                    204:        li      ta2, 0                          # Secondary size 0.
                    205:        li      ta3, 0                          # Tertiary size 0.
                    206:
                    207:        and     v1, 0xff00                      # Recognize CPU's with
                    208:        li      t1, (MIPS_R4600 << 8)           # N way L1 caches only.
                    209:        beq     v1, t1, ConfResult              # R4K 2 way, no L2 control
                    210:        li      t1, (MIPS_R4700 << 8)
                    211:        beq     v1, t1, ConfResult              # R4K 2 way, No L2 control
                    212:        li      t1, (MIPS_R5000 << 8)
                    213:        beq     v1, t1, Conf5K                  # R5K 2 way, check L2
                    214:        li      t1, (MIPS_RM52X0 << 8)
                    215:        beq     v1, t1, Conf52K                 # R52K 2 way, check L2
                    216:        li      t1, (MIPS_RM7000 << 8)
                    217:        beq     v1, t1, Conf7K
                    218:        li      t1, (MIPS_RM9000 << 8)
                    219:        beq     v1, t1, Conf7K
                    220:        nop
                    221:                                                # R4000PC/R4400PC or unknown.
                    222:        li      t2, CTYPE_DIR                   # default direct mapped cache
                    223:        b       ConfResult
                    224:        nop
                    225:
                    226: #---- R5K ------------------------------
                    227: Conf5K:                                                # R5xxx type, check for L2 cache
                    228:        and     t1, v0, CF_5_SC
                    229:        bnez    t1, ConfResult                  # not enabled
                    230:        li      ta2, 0                          # set size to 0.
                    231:
                    232:        li      t3, CF_5_SS
                    233:        and     t1, t3, v0
                    234:        beq     t1, t3, ConfResult              # No L2 cache
                    235:        srl     t1, CF_5_SS_AL
                    236:
                    237:        li      t3, CF_5_SE                     # Set SE in conf
                    238:        or      v0, t3                          # Update config register
                    239:        li      ta2, 512*1024                   # 512k per 'click'.
                    240:        sll     ta2, t1
                    241:
                    242:        mtc0    v0, COP_0_CONFIG                # Enable L2 cache
                    243:        or      t2, CTYPE_HAS_XL2               # External L2 present.
                    244:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    245:        PTR_ADDU t1, t0, ta2
                    246: 1:
                    247:        cache   InvalidateSecondaryPage, 0(t0)
                    248:        PTR_ADDU t0, 4096
                    249:        bne     t0, t1, 1b
                    250:        nop
                    251:
                    252:        b       ConfResult
                    253:        nop
                    254:
                    255:
                    256: #---- R52K ------------------------------
                    257: Conf52K:                                       # R5200 type, check for L2 cache
                    258:        and     t1, v0, CF_52_SC
                    259:        bnez    t1, ConfResult                  # not present
                    260:        li      ta2, 0                          # set size to 0.
                    261:
                    262:        li      t3, CF_52_SS
                    263:        and     t1, t3, v0
                    264:        beq     t1, t3, ConfResult              # No L2 cache
                    265:        srl     t1, CF_52_SS_AL
                    266:
                    267:        li      t3, CF_52_SE                    # Set SE in conf
                    268:        or      v0, t3                          # Update config register
                    269:        li      ta2, 512*1024                   # 512k per 'click'.
                    270:        sll     ta2, t1
                    271:
                    272:        mtc0    v0, COP_0_CONFIG                # Enable L2 cache
                    273:        or      t2, CTYPE_HAS_XL2               # External L2 present.
                    274:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    275:        PTR_ADDU t1, t0, ta2
                    276: 1:
                    277:        cache   InvalidateSecondaryPage, 0(t0)
                    278:        PTR_ADDU t0, 4096
                    279:        bne     t0, t1, 1b
                    280:        nop
                    281:
                    282:        b       ConfResult
                    283:        nop
                    284:
                    285:
                    286: #---- RM7K -----------------------------
                    287: Conf7K:                                        # RM7000, check for L2 and L3 cache
                    288:        li      t2, CTYPE_4WAY                  # 4-way cache
                    289:        and     t1, v0, CF_7_TC
                    290:        bnez    t1, Conf7KL2                    # No L3 cache if set
                    291:        li      ta3, 0                          # Set size = 0
                    292:
                    293: #ifndef L3SZEXT
                    294:        li      t3, CF_7_TS
                    295:        and     t1, t3, v0
                    296:        beq     t1, t3, Conf7KL2                # No L3 cache
                    297:        srl     t1, CF_7_TS_AL
                    298:
                    299:        or      t2, CTYPE_HAS_XL3               # External L2 present.
                    300:        li      t3, CF_7_TE                     # Set SE in conf
                    301:        or      v0, t3                          # Update config register
                    302:        li      ta3, 512*1024                   # 512k per 'click'.
                    303:        sll     ta3, t1
                    304: #else
                    305:        lw      ta3, CpuTertiaryCacheSize
                    306:        and     t2, ~CTYPE_HAS_XL3
                    307:        beqz    ta3, Conf7KL2                   # No L3 cache present
                    308:        nop
                    309:
                    310:        li      t3, CF_7_TE                     # Set SE in conf
                    311:        or      v0, t3                          # Update config register
                    312:        mtc0    v0, COP_0_CONFIG                # Enable L3 cache
                    313:        or      t2, CTYPE_HAS_XL3
                    314: #endif
                    315:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    316:        PTR_ADDU t1, t0, ta3
                    317: 1:
                    318:        cache   InvalidatePage_T, 0(t0)
                    319:        PTR_ADDU t0, 4096
                    320:        bne     t0, t1, 1b
                    321:        nop
                    322:
                    323:
                    324: Conf7KL2:
                    325:        and     t1, v0, CF_7_SC                 # check for L2 cache
                    326:        bnez    t1, ConfResult
                    327:        li      ta2, 0                          # No L2?
                    328:
                    329:        and     t1, v0, CF_7_SE
                    330:        bnez    t1, 3f
                    331:        ori     v0, CF_7_SE
                    332:
                    333:        mtc0    v0, COP_0_CONFIG                # Enable and init L2 cache
                    334:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    335:        PTR_ADDU t1, t0, ta3
                    336: 1:
                    337:        PTR_ADDU t0, 32
                    338:        bne     t0, t1, 1b
                    339:        cache   IndexStoreTag_S, -4(t0)
                    340:        sync
                    341:
                    342:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    343:        PTR_ADDU t1, t0, ta3
                    344: 1:
                    345:        PTR_ADDU t0, 32
                    346:        bne     t0, t1, 1b
                    347:        lw      zero, -4(t0)
                    348:        sync
                    349:
                    350:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    351:        PTR_ADDU t1, t0, ta3
                    352: 1:
                    353:        PTR_ADDU t0, 32
                    354:        bne     t0, t1, 1b
                    355:        cache   IndexStoreTag_S, -4(t0)
                    356:        sync
                    357:
                    358: 3:
                    359:        or      t2, CTYPE_HAS_IL2               # L2 is on chip
                    360:        b       ConfResult
                    361:        li      ta2, 256*1024                   # L2 size = 256k
                    362:
                    363: /*
                    364:  * Get here with t2 = Cache type, ta0 = L1 I size, ta1 = L1 D size.
                    365:  * ta2 = secondary size, ta3 = tertiary size.
                    366:  */
                    367: ConfResult:
                    368:        sw      v0, CpuConfigRegister
                    369:        mfc0    t3, COP_0_STATUS_REG
                    370:        sw      t2, CpuCacheType                # Save cache attributes
                    371:        sw      t3, CpuStatusRegister
                    372:        and     t2, CTYPE_WAYMASK               # isolate number of sets.
                    373:        sw      t2, CpuNWayCache
                    374:        srl     t2, 1                           # get div shift for set size.
                    375:
                    376:        sw      ta2, CpuSecondaryCacheSize
                    377:        sw      ta3, CpuTertiaryCacheSize
                    378:
                    379:        addu    t1, ta0, -1                     # Use icache for alias mask
                    380:        srl     t1, t2                          # Some cpus have different
                    381:        and     t1, ~(NBPG - 1)                 # i and d cache sizes...
                    382:        sw      t1, CpuCacheAliasMask
                    383:
                    384:        sw      ta0, CpuPrimaryInstCacheSize    # store cache size.
                    385:        srl     ta0, t2                         # calculate set size.
                    386:        sw      ta0, CpuPrimaryInstSetSize
                    387:
                    388:        sw      ta1, CpuPrimaryDataCacheSize    # store cache size.
                    389:        srl     ta1, t2                         # calculate set size.
                    390:        sw      ta1, CpuPrimaryDataSetSize
                    391:
                    392:        and     v0, 0xfffffff8
                    393:        or      v0, 0x00000003                  # set cachable writeback kseg0
                    394:        mtc0    v0, COP_0_CONFIG                # establish any new config
                    395:        NOP10
                    396:        j       ra
                    397:        nop
                    398: END(Mips5k_ConfigCache)
                    399:
                    400: /*----------------------------------------------------------------------------
                    401:  *
                    402:  * Mips5k_SyncCache --
                    403:  *
                    404:  *     Sync ALL caches.
                    405:  *     No need to look at number of sets since we are cleaning out
                    406:  *     the entire cache and thus will address all sets anyway.
                    407:  *
                    408:  * Results:
                    409:  *     None.
                    410:  *
                    411:  * Side effects:
                    412:  *     The contents of ALL caches are Invalidated or Synched.
                    413:  *
                    414:  *----------------------------------------------------------------------------
                    415:  */
                    416: LEAF(Mips5k_SyncCache, 0)
                    417:        .set    noreorder
                    418:        lw      t1, CpuPrimaryInstCacheSize
                    419:        lw      t2, CpuPrimaryDataCacheSize
                    420:
                    421: /*
                    422:  * Sync the instruction cache.
                    423:  */
                    424: #ifdef CPUR4600
                    425:        mfc0    v1, COP_0_STATUS_REG            # Save the status register.
                    426:        li      v0, SR_DIAG_DE
                    427:        mtc0    v0, COP_0_STATUS_REG            # Disable interrupts
                    428: #endif
                    429:
                    430:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    431:        PTR_ADDU t1, t0, t1                     # Compute end address
                    432:        PTR_SUBU t1, 128
                    433:
                    434: 1:
                    435:        cache   IndexInvalidate_I, 0(t0)
                    436:        cache   IndexInvalidate_I, 32(t0)
                    437:        cache   IndexInvalidate_I, 64(t0)
                    438:        cache   IndexInvalidate_I, 96(t0)
                    439:
                    440:        bne     t0, t1, 1b
                    441:        PTR_ADDU t0, t0, 128
                    442:
                    443: /*
                    444:  * Sync the data cache. Do L1 first. Indexed only operate on
                    445:  * the selected cache and differs from Hit in that sense.
                    446:  */
                    447:
                    448:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    449:        PTR_ADDU t1, t0, t2                     # End address
                    450:        PTR_SUBU t1, t1, 128
                    451: 1:
                    452:        cache   IndexWBInvalidate_D, 0(t0)
                    453:        cache   IndexWBInvalidate_D, 32(t0)
                    454:        cache   IndexWBInvalidate_D, 64(t0)
                    455:        cache   IndexWBInvalidate_D, 96(t0)
                    456:
                    457:        bne     t0, t1, 1b
                    458:        PTR_ADDU t0, t0, 128
                    459:
                    460: /* Do on chip L2 if present */
                    461:        lw      t0, CpuCacheType
                    462:        and     t0, CTYPE_HAS_IL2
                    463:        beqz    t0, 20f
                    464:        nop
                    465:
                    466: 3:
                    467:        LOAD_XKPHYS(t3, CCA_NONCOHERENT)
                    468:        lw      ta0, CpuSecondaryCacheSize
                    469: 10:
                    470:        cache   IndexWBInvalidate_S, 0(t3)
                    471:        PTR_SUBU ta0, 32                        # Fixed cache line size.
                    472:        bgtz    ta0, 10b
                    473:        PTR_ADDU t3, 32
                    474:
                    475: /* Do off chip L2 if present */
                    476: 20:
                    477:        lw      t0, CpuCacheType
                    478:        and     t0, CTYPE_HAS_XL2
                    479:        beqz    t0, 30f
                    480:        nop
                    481:
                    482:        mtc0    zero, COP_0_TAG_LO
                    483:        LOAD_XKPHYS(t3, CCA_NONCOHERENT)
                    484:        lw      ta0, CpuSecondaryCacheSize
                    485: 21:
                    486:        cache   InvalidateSecondaryPage, 0(t3)
                    487:        PTR_SUBU ta0, 4096                      # Fixed cache page size.
                    488:        bgtz    ta0, 21b
                    489:        PTR_ADDU t3, 4096
                    490:
                    491: /* Do off chip L3 if present */
                    492: 30:
                    493:        lw      t0, CpuCacheType
                    494:        and     t0, CTYPE_HAS_XL3
                    495:        beqz    t0, 99f
                    496:        nop
                    497:
                    498:        mtc0    zero, COP_0_TAG_LO
                    499:        LOAD_XKPHYS(t3, CCA_NONCOHERENT)
                    500:        lw      ta0, CpuTertiaryCacheSize
                    501: 31:
                    502:        cache   InvalidatePage_T, 0(t3)
                    503:        PTR_SUBU ta0, 4096                      # Fixed cache page size.
                    504:        bgtz    ta0, 31b
                    505:        PTR_ADDU t3, 4096
                    506:
                    507: 99:
                    508: #ifdef CPUR4600
                    509:        mtc0    v1, COP_0_STATUS_REG    # Restore the status register.
                    510:        NOP10
                    511: #endif
                    512:        j       ra
                    513:        nop
                    514: END(Mips5k_SyncCache)
                    515:
                    516: /*----------------------------------------------------------------------------
                    517:  *
                    518:  * Mips5k_InvalidateICachePage --
                    519:  *
                    520:  *     void Mips5k_InvalidateICachePage(addr)
                    521:  *             vaddr_t addr;
                    522:  *
                    523:  *     Invalidate the L1 instruction cache page given by addr.
                    524:  *
                    525:  * Results:
                    526:  *     Void.
                    527:  *
                    528:  * Side effects:
                    529:  *     The contents of the L1 Instruction cache is flushed.
                    530:  *
                    531:  *----------------------------------------------------------------------------
                    532:  */
                    533: LEAF(Mips5k_InvalidateICachePage, 0)
                    534: #ifdef CPUR4600
                    535:        mfc0    v1, COP_0_STATUS_REG            # Save the status register.
                    536:        li      v0, SR_DIAG_DE
                    537:        mtc0    v0, COP_0_STATUS_REG            # Disable interrupts
                    538: #endif
                    539:        lw      v0, CpuNWayCache                # Cache properties
                    540:        lw      t0, CpuPrimaryInstSetSize       # Set size
                    541:        and     a0, ~PAGE_MASK                  # Page align start address
                    542:        PTR_ADDU a1, a0, PAGE_SIZE-128          # End address.
                    543:        addiu   v0, -2                          # <0 1way, 0 = two, >0 four
                    544: 1:
                    545:        cache   HitInvalidate_I, 0(a0)
                    546:        cache   HitInvalidate_I, 32(a0)
                    547:        cache   HitInvalidate_I, 64(a0)
                    548:        cache   HitInvalidate_I, 96(a0)
                    549:
                    550:        bne     a0, a1, 1b
                    551:        PTR_ADDU a0, 128
                    552:
                    553: #ifdef CPUR4600
                    554:        mtc0    v1, COP_0_STATUS_REG    # Restore the status register.
                    555:        NOP10
                    556: #endif
                    557:        j       ra
                    558:        move    v0, zero
                    559: END(Mips5k_InvalidateICachePage)
                    560:
                    561: /*----------------------------------------------------------------------------
                    562:  *
                    563:  * Mips5k_InvalidateICache --
                    564:  *
                    565:  *     void Mips5k_SyncICache(addr, len)
                    566:  *             vaddr_t addr, len;
                    567:  *
                    568:  *     Invalidate the L1 instruction cache for at least range
                    569:  *     of addr to addr + len - 1.
                    570:  *     The address is reduced to a XKPHYS index to avoid TLB faults.
                    571:  *
                    572:  * Results:
                    573:  *     None.
                    574:  *
                    575:  * Side effects:
                    576:  *     The contents of the L1 Instruction cache is flushed.
                    577:  *     Must not touch v0.
                    578:  *
                    579:  *----------------------------------------------------------------------------
                    580:  */
                    581: LEAF(Mips5k_InvalidateICache, 0)
                    582: #ifdef CPUR4600
                    583:        mfc0    v1, COP_0_STATUS_REG            # Save the status register.
                    584:        li      v0, SR_DIAG_DE
                    585:        mtc0    v0, COP_0_STATUS_REG            # Disable interrupts
                    586: #endif
                    587:        lw      v0, CpuNWayCache                # Cache properties
                    588:        lw      t0, CpuPrimaryInstSetSize       # Set size
                    589:        and     a0, 0x00ffffff                  # Reduce addr to cache index
                    590:        LOAD_XKPHYS(a2, CCA_NONCOHERENT)
                    591:        PTR_ADDU a1, 31                         # Round up size
                    592:        PTR_ADDU a1, a0                         # Add extra from address
                    593:        and     a0, -32                         # Align start address
                    594:        PTR_SUBU a1, a1, a0
                    595:        PTR_ADDU a0, a2                         # a0 now new XKPHYS address
                    596:        srl     a1, a1, 5                       # Number of unrolled loops
                    597:        addiu   v0, -2                          # <0 1way, 0 = two, >0 four
                    598: 1:
                    599:        bltz    v0, 3f
                    600:        addu    a1, -1
                    601:
                    602: 2:
                    603:        PTR_ADDU t1, t0, a0                     # Nway cache, flush set B.
                    604:        cache   IndexInvalidate_I, 0(t1)
                    605:        beqz    v0, 3f                          # Is two way do set A
                    606:        PTR_ADDU t1, t0                         # else step to set C.
                    607:
                    608:        cache   IndexInvalidate_I, 0(t1)
                    609:
                    610:        PTR_ADDU t1, t0                         # step to set D
                    611:        cache   IndexInvalidate_I, 0(t1)
                    612:
                    613: 3:
                    614:        cache   IndexInvalidate_I, 0(a0)        # do set (A if NWay)
                    615:
                    616:        bne     a1, zero, 1b
                    617:        PTR_ADDU a0, 32
                    618:
                    619: #ifdef CPUR4600
                    620:        mtc0    v1, COP_0_STATUS_REG    # Restore the status register.
                    621:        NOP10
                    622: #endif
                    623:        j       ra
                    624:        move    v0, zero
                    625: END(Mips5k_InvalidateICache)
                    626:
                    627: /*----------------------------------------------------------------------------
                    628:  *
                    629:  * Mips5k_SyncDCachePage --
                    630:  *
                    631:  *     void Mips5k_SyncDCachePage(addr)
                    632:  *             vaddr_t addr;
                    633:  *
                    634:  *     Sync the L1 data cache page for address addr.
                    635:  *     The address is reduced to a XKPHYS index to avoid TLB faults.
                    636:  *
                    637:  * Results:
                    638:  *     None.
                    639:  *
                    640:  * Side effects:
                    641:  *     The contents of the cache is written back to primary memory.
                    642:  *     The cache line is invalidated.
                    643:  *
                    644:  *----------------------------------------------------------------------------
                    645:  */
                    646: LEAF(Mips5k_SyncDCachePage, 0)
                    647: #ifdef CPUR4600
                    648:        mfc0    v1, COP_0_STATUS_REG            # Save the status register.
                    649:        li      v0, SR_DIAG_DE
                    650:        mtc0    v0, COP_0_STATUS_REG            # Disable interrupts
                    651: #endif
                    652:        LOAD_XKPHYS(a2, CCA_NONCOHERENT)
                    653:        lw      v0, CpuNWayCache
                    654:        dsll    a0, 34
                    655:        dsrl    a0, 34
                    656:        PTR_ADDU a0, a2                         # a0 now new XKPHYS address
                    657:        and     a0, ~PAGE_MASK                  # Page align start address
                    658:        PTR_ADDU a1, a0, PAGE_SIZE-128
                    659:        addiu   v0, -2                          # <0 1way, 0 = two, >0 four
                    660:        lw      a2, CpuPrimaryDataSetSize
                    661:
                    662: 1:
                    663:        bltz    v0, 3f
                    664:        PTR_ADDU t1, a0, a2                     # flush set B.
                    665:        cache   IndexWBInvalidate_D, 0(t1)
                    666:        cache   IndexWBInvalidate_D, 32(t1)
                    667:        cache   IndexWBInvalidate_D, 64(t1)
                    668:        cache   IndexWBInvalidate_D, 96(t1)
                    669:        beqz    v0, 3f                          # Two way, do set A,
                    670:        PTR_ADDU t1, a2
                    671:
                    672:        cache   IndexWBInvalidate_D, 0(t1)      # do set C
                    673:        cache   IndexWBInvalidate_D, 32(t1)
                    674:        cache   IndexWBInvalidate_D, 64(t1)
                    675:        cache   IndexWBInvalidate_D, 96(t1)
                    676:
                    677:        PTR_ADDU t1, a2                         # do set D
                    678:        cache   IndexWBInvalidate_D, 0(t1)
                    679:        cache   IndexWBInvalidate_D, 32(t1)
                    680:        cache   IndexWBInvalidate_D, 64(t1)
                    681:        cache   IndexWBInvalidate_D, 96(t1)
                    682:
                    683: 3:
                    684:        cache   IndexWBInvalidate_D, 0(a0)      # do set A
                    685:        cache   IndexWBInvalidate_D, 32(a0)
                    686:        cache   IndexWBInvalidate_D, 64(a0)
                    687:        cache   IndexWBInvalidate_D, 96(a0)
                    688:
                    689:        bne     a1, a0, 1b
                    690:        PTR_ADDU a0, 128
                    691:
                    692: #ifdef CPUR4600
                    693:        mtc0    v1, COP_0_STATUS_REG    # Restore the status register.
                    694: #endif
                    695:        j       ra
                    696:        nop
                    697: END(Mips5k_SyncDCachePage)
                    698:
                    699: /*----------------------------------------------------------------------------
                    700:  *
                    701:  * Mips5k_HitSyncDCache --
                    702:  *
                    703:  *     void Mips5k_HitSyncDCache(addr, len)
                    704:  *             vaddr_t addr, len;
                    705:  *
                    706:  *     Sync data cache for range of addr to addr + len - 1.
                    707:  *     The address can be any valid virtual address as long
                    708:  *     as no TLB invalid traps occur. Only lines with matching
                    709:  *     addr are flushed.
                    710:  *
                    711:  *     Note: Use the CpuNWayCache flag to select 16 or 32 byte linesize.
                    712:  *           All Nway cpu's now available have a fixed 32byte linesize.
                    713:  *
                    714:  * Results:
                    715:  *     None.
                    716:  *
                    717:  * Side effects:
                    718:  *     The contents of the L1 cache is written back to primary memory.
                    719:  *     The cache line is invalidated.
                    720:  *
                    721:  * IMPORTANT NOTE:
                    722:  *     Since orphaned L1 cache entries will not be synched it is
                    723:  *     mandatory to pass over the L1 cache once after the L2 is done.
                    724:  *
                    725:  *----------------------------------------------------------------------------
                    726:  */
                    727: LEAF(Mips5k_HitSyncDCache, 0)
                    728: #ifdef CPUR4600
                    729:        mfc0    v1, COP_0_STATUS_REG            # Save the status register.
                    730:        li      v0, SR_DIAG_DE
                    731:        mtc0    v0, COP_0_STATUS_REG            # Disable interrupts
                    732: #endif
                    733:
                    734:        beq     a1, zero, 3f                    # size is zero!
                    735:        PTR_ADDU a1, 31                         # Round up
                    736:        PTR_ADDU a1, a1, a0                     # Add extra from address
                    737:        and     a0, a0, -32                     # align address
                    738:        PTR_SUBU a1, a1, a0
                    739:        srl     a1, a1, 5                       # Compute number of cache lines
                    740:
                    741: 1:
                    742:        PTR_ADDU a1, -1
                    743:        cache   HitWBInvalidate_D, 0(a0)
                    744:        bne     a1, zero, 1b
                    745:        PTR_ADDU a0, 32
                    746:
                    747: 3:
                    748: #ifdef CPUR4600
                    749:        mtc0    v1, COP_0_STATUS_REG    # Restore the status register.
                    750:        NOP10
                    751: #endif
                    752:        j       ra
                    753:        nop
                    754: END(Mips5k_HitSyncDCache)
                    755:
                    756:
                    757: /*----------------------------------------------------------------------------
                    758:  *
                    759:  * Mips5k_HitSyncSCache --
                    760:  *
                    761:  *     void Mips5k_HitSyncSCache(addr, len)
                    762:  *             vaddr_t addr, len;
                    763:  *
                    764:  *     Sync secondary cache for range of addr to addr + len - 1.
                    765:  *     The address can be any valid virtual address as long
                    766:  *     as no TLB invalid traps occur. Only lines with matching
                    767:  *     addr are flushed.
                    768:  *
                    769:  * Results:
                    770:  *     None.
                    771:  *
                    772:  * Side effects:
                    773:  *     The contents of the L2 cache is written back to primary memory.
                    774:  *     The cache line is invalidated.
                    775:  *
                    776:  * IMPORTANT NOTE:
                    777:  *     Since orphaned L1 cache entries will not be synched it is
                    778:  *     mandatory to pass over the L1 cache once after the L2 is done.
                    779:  *
                    780:  *----------------------------------------------------------------------------
                    781:  */
                    782: LEAF(Mips5k_HitSyncSCache, 0)
                    783: #ifdef CPUR4600
                    784:        mfc0    v1, COP_0_STATUS_REG            # Save the status register.
                    785:        li      v0, SR_DIAG_DE
                    786:        mtc0    v0, COP_0_STATUS_REG            # Disable interrupts
                    787: #endif
                    788:
                    789:        beq     a1, zero, 3f                    # size is zero!
                    790:        PTR_ADDU a1, a1, a0                     # Add in extra from align
                    791:        and     a0, a0, -32                     # Align address
                    792:        PTR_SUBU a1, a1, a0
                    793: 1:
                    794:        PTR_ADDU a1, -32
                    795:
                    796:        cache   HitWBInvalidate_S, 0(a0)
                    797:        cache   HitWBInvalidate_D, 0(a0)        # Kill any orphans...
                    798:
                    799:        bgtz    a1, 1b
                    800:        PTR_ADDU a0, 32
                    801:
                    802: 3:
                    803: #ifdef CPUR4600
                    804:        mtc0    v1, COP_0_STATUS_REG    # Restore the status register.
                    805:        NOP10
                    806: #endif
                    807:        j       ra
                    808:        nop
                    809: END(Mips5k_HitSyncSCache)
                    810:
                    811: /*----------------------------------------------------------------------------
                    812:  *
                    813:  * Mips5k_HitInvalidateDCache --
                    814:  *
                    815:  *     void Mips5k_HitInvalidateDCache(addr, len)
                    816:  *             vaddr_t addr, len;
                    817:  *
                    818:  *     Invalidate data cache for range of addr to addr + len - 1.
                    819:  *     The address can be any valid address as long as no TLB misses occur.
                    820:  *     (Be sure to use cached K0SEG kernel addresses or mapped addresses)
                    821:  *     Only lines with matching addresses are invalidated.
                    822:  *
                    823:  * Results:
                    824:  *     None.
                    825:  *
                    826:  * Side effects:
                    827:  *     The L1 cache line is invalidated.
                    828:  *
                    829:  *----------------------------------------------------------------------------
                    830:  */
                    831: LEAF(Mips5k_HitInvalidateDCache, 0)
                    832: #ifdef CPUR4600
                    833:        mfc0    v1, COP_0_STATUS_REG            # Save the status register.
                    834:        li      v0, SR_DIAG_DE
                    835:        mtc0    v0, COP_0_STATUS_REG            # Disable interrupts
                    836: #endif
                    837:
                    838:        beq     a1, zero, 3f                    # size is zero!
                    839:        PTR_ADDU a1, a1, a0                     # Add in extra from align
                    840:        and     a0, a0, -32                     # Align address
                    841:        PTR_SUBU a1, a1, a0
                    842:
                    843: 1:
                    844:        PTR_ADDU a1, -32
                    845:
                    846:        cache   HitInvalidate_D, 0(a0)
                    847:
                    848:        bgtz    a1, 1b
                    849:        PTR_ADDU a0, 32
                    850:
                    851: 3:
                    852: #ifdef CPUR4600
                    853:        mtc0    v1, COP_0_STATUS_REG            # Restore the status register.
                    854:        NOP10
                    855: #endif
                    856:        j       ra
                    857:        nop
                    858: END(Mips5k_HitInvalidateDCache)
                    859:
                    860:
                    861: /*----------------------------------------------------------------------------
                    862:  *
                    863:  * Mips5k_HitInvalidateSCache --
                    864:  *
                    865:  *     void Mips5k_HitInvalidateSCache(addr, len)
                    866:  *             vaddr_t addr, len;
                    867:  *
                    868:  *     Invalidate secondary cache for range of addr to addr + len - 1.
                    869:  *     The address can be any valid address as long as no TLB misses occur.
                    870:  *     (Be sure to use cached K0SEG kernel addresses or mapped addresses)
                    871:  *     Only lines with matching addresses are invalidated.
                    872:  *
                    873:  * Results:
                    874:  *     None.
                    875:  *
                    876:  * Side effects:
                    877:  *     The L2 cache line is invalidated.
                    878:  *
                    879:  *----------------------------------------------------------------------------
                    880:  */
                    881: LEAF(Mips5k_HitInvalidateSCache, 0)
                    882: #ifdef CPUR4600
                    883:        mfc0    v1, COP_0_STATUS_REG            # Save the status register.
                    884:        li      v0, SR_DIAG_DE
                    885:        mtc0    v0, COP_0_STATUS_REG            # Disable interrupts
                    886: #endif
                    887:
                    888:        beq     a1, zero, 3f                    # size is zero!
                    889:        PTR_ADDU a1, a1, a0                     # Add in extra from align
                    890:        and     a0, a0, -32                     # Align address
                    891:        PTR_SUBU a1, a1, a0
                    892: 1:
                    893:        PTR_ADDU a1, -32
                    894:
                    895:        cache   HitInvalidate_S, 0(a0)
                    896:        cache   HitInvalidate_D, 0(a0)          # Orphans in L1
                    897:
                    898:        bgtz    a1, 1b
                    899:        PTR_ADDU a0, 32
                    900:
                    901: 3:
                    902: #ifdef CPUR4600
                    903:        mtc0    v1, COP_0_STATUS_REG    # Restore the status register.
                    904:        NOP10
                    905: #endif
                    906:        j       ra
                    907:        nop
                    908: END(Mips5k_HitInvalidateSCache)
                    909:
                    910: /*----------------------------------------------------------------------------
                    911:  *
                    912:  * Mips5k_IOSyncDCache --
                    913:  *
                    914:  *     void Mips5k_IOSyncDCache(addr, len, rw)
                    915:  *             vaddr_t addr;
                    916:  *             int  len, rw;
                    917:  *
                    918:  *     Invalidate or flush data cache for range of addr to addr + len - 1.
                    919:  *     The address can be any valid address as long as no TLB misses occur.
                    920:  *     (Be sure to use cached K0SEG kernel addresses or mapped addresses)
                    921:  *
                    922:  *     In case of the existence of an external cache we invalidate pages
                    923:  *     which are in the given range ONLY if transfer direction is READ.
                    924:  *     The assumption here is a 'write through' external cache which is
                    925:  *     true for all now supported processors.
                    926:  *
                    927:  * Results:
                    928:  *     None.
                    929:  *
                    930:  * Side effects:
                    931:  *     If rw == 0 (read), L1 and on-chip L2 caches are invalidated or
                    932:  *             flushed if the area does not match the alignment
                    933:  *             requirements. Writethrough L2 and L3 cache are
                    934:  *             invalidated for the address range.
                    935:  *     If rw == 1 (write), L1 and on-chip L2 caches are written back
                    936:  *             to memory and invalidated. Writethrough L2 and L3 caches
                    937:  *             are left alone.
                    938:  *     If rw == 2 (write-read), L1 and on-chip L2 caches are written back
                    939:  *             to memory and invalidated. Writethrough L2 and L3 caches
                    940:  *             are invalidated.
                    941:  *
                    942:  *----------------------------------------------------------------------------
                    943:  */
                    944: NON_LEAF(Mips5k_IOSyncDCache, FRAMESZ(CF_SZ+2*REGSZ), ra)
                    945:
                    946:        PTR_SUBU sp, FRAMESZ(CF_SZ+2*REGSZ)
                    947:        PTR_S   ra, CF_RA_OFFS+2*REGSZ(sp)
                    948:        REG_S   a0, CF_ARGSZ(sp)                # save args
                    949:        beqz    a2, SyncRD                      # Sync PREREAD
                    950:        REG_S   a1, CF_ARGSZ+REGSZ(sp)
                    951:        addiu   a2, -1
                    952:        bnez    a2, SyncRDWB                    # Sync PREWRITE+PREREAD
                    953:        nop
                    954:
                    955:        lw      t0, CpuCacheType                # Sync PREWRITE
                    956:        and     t0, CTYPE_HAS_IL2               # Have internal L2?
                    957:        bnez    t0, SyncSC                      # Yes
                    958:        nop
                    959:        jal      Mips5k_HitSyncDCache           # No flush L1.
                    960:        nop
                    961:        b       SyncDone
                    962:        PTR_L   ra, CF_RA_OFFS+2*REGSZ(sp)
                    963:
                    964: SyncSC:
                    965:        jal     Mips5k_HitSyncSCache            # Do internal L2 cache
                    966:        nop                                     # L1 done in parallel
                    967:        b       SyncDone
                    968:        PTR_L   ra, CF_RA_OFFS+2*REGSZ(sp)
                    969:
                    970: SyncRD:
                    971:        and     t0, a0, 31                      # check if invalidate possible
                    972:        bnez    t0, SyncRDWB                    # both address and size must
                    973:        and     t0, a1, 31                      # be aligned at the cache size
                    974:        bnez    t0, SyncRDWB
                    975:        nop
                    976:
                    977: /*
                    978:  *  Sync for aligned read, no writeback required.
                    979:  */
                    980:        lw      t0, CpuCacheType                # Aligned, do invalidate
                    981:        and     t0, CTYPE_HAS_IL2               # Have internal L2?
                    982:        bnez    t0, SyncRDL2
                    983:        nop
                    984:
                    985:        jal     Mips5k_HitInvalidateDCache      # External L2 or no L2. Do L1.
                    986:        nop
                    987:
                    988:        b       SyncRDXL2
                    989:        PTR_L   ra, CF_RA_OFFS+2*REGSZ(sp)      # External L2 if present
                    990:
                    991: SyncRDL2:
                    992:        jal     Mips5k_HitInvalidateSCache      # Internal L2 cache
                    993:        nop                                     # L1 done in parallel
                    994:
                    995:        b       SyncRDL3
                    996:        PTR_L   ra, CF_RA_OFFS+2*REGSZ(sp)              # L3 invalidate if present
                    997:
                    998: /*
                    999:  *  Sync for unaligned read or write-read.
                   1000:  */
                   1001: SyncRDWB:
                   1002:        lw      t0, CpuCacheType
                   1003:        and     t0, CTYPE_HAS_IL2               # Have internal L2?
                   1004:        bnez    t0, SyncRDWBL2                  # Yes, do L2
                   1005:        nop
                   1006:
                   1007:        jal     Mips5k_HitSyncDCache
                   1008:        nop
                   1009:
                   1010:        b       SyncRDXL2
                   1011:        PTR_L   ra, CF_RA_OFFS+2*REGSZ(sp)              # External L2 if present
                   1012:
                   1013: SyncRDWBL2:
                   1014:        jal     Mips5k_HitSyncSCache            # Internal L2 cache
                   1015:        nop                                     # L1 done in parallel
                   1016:
                   1017:        b       SyncRDL3
                   1018:        PTR_L   ra, CF_RA_OFFS+2*REGSZ(sp)              # L3 invalidate if present
                   1019:
                   1020: SyncRDXL2:
                   1021:        lw      t0, CpuCacheType
                   1022:        and     t0, CTYPE_HAS_XL2               # Have external L2?
                   1023:        beqz    t0, SyncRDL3                    # Nope.
                   1024:        REG_L   a0, CF_ARGSZ(sp)
                   1025:        REG_L   a1, CF_ARGSZ+REGSZ(sp)
                   1026:        and     a2, a0, 4095                    # align on page size
                   1027:        PTR_SUBU a0, a2
                   1028:        PTR_ADDU a1, a2
                   1029: 50:
                   1030:        blez    a1, SyncDone
                   1031:        PTR_SUBU a1, 4096                       # Fixed cache page size.
                   1032:
                   1033:        cache   InvalidateSecondaryPage, 0(a0)
                   1034:        b       50b
                   1035:        PTR_ADDU a0, 4096
                   1036:
                   1037: SyncRDL3:
                   1038:        lw      t0, CpuCacheType
                   1039:        and     t0, CTYPE_HAS_XL3               # Have L3?
                   1040:        beqz    t0, SyncDone                    # Nope.
                   1041:        REG_L   a0, CF_ARGSZ(sp)
                   1042:        REG_L   a1, CF_ARGSZ+REGSZ(sp)
                   1043:        and     a2, a0, 4095                    # align on page size
                   1044:        PTR_SUBU a0, a2
                   1045:        PTR_ADDU a1, a2
                   1046: 40:
                   1047:        blez    a1, SyncDone
                   1048:        PTR_SUBU a1, 4096                       # Fixed cache page size.
                   1049:
                   1050:        cache   InvalidatePage_T, 0(a0)
                   1051:        b       40b
                   1052:        PTR_ADDU a0, 4096
                   1053:
                   1054: SyncDone:
                   1055:        j       ra
                   1056:        PTR_ADDU sp, FRAMESZ(CF_SZ+2*REGSZ)
                   1057: END(Mips5k_IOSyncDCache)

CVSweb