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

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

1.1       nbrk        1: /*     $OpenBSD: cache_r10k.S,v 1.5 2007/06/18 20:25:55 miod Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 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:  *  Processors supported:
                     31:  *  R10000
                     32:  *  R12000
                     33:  *  R14000     (needs to be tested)
                     34:  */
                     35:
                     36: #include <sys/errno.h>
                     37: #include <sys/syscall.h>
                     38:
                     39: #include <machine/param.h>
                     40: #include <machine/psl.h>
                     41: #include <machine/asm.h>
                     42: #include <machine/cpu.h>
                     43: #include <machine/regnum.h>
                     44: #include <machine/pte.h>
                     45:
                     46: #include "assym.h"
                     47:
                     48:        .set    mips3
                     49:
                     50: #define        LOAD_XKPHYS(reg, cca) \
                     51:        li      reg, cca | 0x10; \
                     52:        dsll    reg, reg, 59
                     53:
                     54: /*
                     55:  *  Skip the .h file. Noone else need to know!
                     56:  */
                     57:
                     58: #define        IndexInvalidate_I       0x00
                     59: #define        IndexWBInvalidate_D     0x01
                     60: #define        IndexFlashInvalidate_T  0x02
                     61: #define        IndexWBInvalidate_S     0x03
                     62:
                     63: #define        IndexLoadTag_I          0x04
                     64: #define        IndexLoadTag_D          0x05
                     65: #define        IndexLoadTag_S          0x07
                     66:
                     67: #define        IndexStoreTag_I         0x08
                     68: #define        IndexStoreTag_D         0x09
                     69: #define        IndexStoreTag_S         0x0b
                     70:
                     71: #define        CreateDirtyExclusive    0x09
                     72:
                     73: #define        HitInvalidate_I         0x10
                     74: #define        HitInvalidate_D         0x11
                     75: #define        HitInvalidate_S         0x13
                     76:
                     77: #define        Fill_I                  0x14
                     78: #define        HitWBInvalidate_D       0x15
                     79: #define        HitWBInvalidate_S       0x17
                     80:
                     81: #define        HitWB_I                 0x18
                     82: #define        HitWB_D                 0x19
                     83: #define        HitWB_S                 0x1b
                     84:
                     85: /*
                     86:  *  Define cache type definition bits. NOTE! the 3 lsb may NOT change!
                     87:  */
                     88: #define        CTYPE_DIR               0x0001  /* Cache is direct mapped */
                     89: #define        CTYPE_2WAY              0x0002  /* Cache is TWO way */
                     90: #define        CTYPE_4WAY              0x0004  /* Cache is FOUR way */
                     91: #define        CTYPE_WAYMASK           0x0007
                     92:
                     93: #define        CTYPE_HAS_IL2           0x0100  /* Internal L2 Cache present */
                     94: #define        CTYPE_HAS_XL2           0x0200  /* External L2 Cache present */
                     95: #define        CTYPE_HAS_XL3           0x0400  /* External L3 Cache present */
                     96:
                     97:        .set    noreorder               # Noreorder is default style!
                     98:
                     99: /*----------------------------------------------------------------------------
                    100:  *
                    101:  * Mips10k_ConfigCache --
                    102:  *
                    103:  *     Size and configure the caches.
                    104:  *     NOTE: should only be called from mips_init().
                    105:  *
                    106:  * Results:
                    107:  *     Returns the value of the cpu configuration register.
                    108:  *
                    109:  * Side effects:
                    110:  *     The size of the data cache is stored into CpuPrimaryDataCacheSize.
                    111:  *     The size of instruction cache is stored into CpuPrimaryInstCacheSize.
                    112:  *     Alignment mask for cache aliasing test is stored in CpuCacheAliasMask.
                    113:  *     CpuSecondaryCacheSize is set to the size of the secondary cache.
                    114:  *     CpuTertiaryCacheSize is set to the size of the tertiary cache.
                    115:  *     CpuNWayCache is set to 0 for direct mapped caches, 2 for two way
                    116:  *     caches and 4 for four way caches. This primarily indicates the
                    117:  *     primary cache associativity.
                    118:  *
                    119:  * Allocation:
                    120:  *     ta0, ta1 ta2 used to hold I and D set size and Alias mask.
                    121:  *
                    122:  *----------------------------------------------------------------------------
                    123:  */
                    124: LEAF(Mips10k_ConfigCache, 0)
                    125:        .set    noreorder
                    126:        mfc0    v0, COP_0_CONFIG                # Get configuration register
                    127:
                    128:        srl     t1, v0, 29                      # Get I cache size.
                    129:        and     t1, 7
                    130:        li      t2, 4096
                    131:        sllv    ta0, t2, t1                     # ta0 = Initial I set size.
                    132:
                    133:        li      t2, 64
                    134:        sw      t2, CpuPrimaryInstCacheLSize
                    135:
                    136:        srl     t1, v0, 26                      # Get D cache size.
                    137:        and     t1, 7
                    138:        li      t2, 4096                        # Fixed page size.
                    139:        sllv    ta1, t2, t1
                    140:
                    141:        li      t2, 32                          # Get D cache line size.
                    142:        sw      t2, CpuPrimaryDataCacheLSize
                    143:
                    144:        li      t2, CTYPE_2WAY                  # Assume two way cache
                    145:        li      ta2, 0                          # Secondary size 0.
                    146:        li      ta3, 0                          # Tertiary size 0.
                    147:
                    148:        or      t2, CTYPE_HAS_XL2               # External L2 present.
                    149:        srl     t1, v0, 16                      # Get I cache size.
                    150:        and     t1, 7
                    151:        li      ta2, 512*1024                   # 512k per 'click'.
                    152:        sll     ta2, t1
                    153:
                    154: /*
                    155:  * Get here with t2 = Cache type, ta0 = L1 I size, ta1 = L1 D size.
                    156:  * ta2 = secondary size, ta3 = tertiary size.
                    157:  */
                    158: ConfResult:
                    159:        sw      v0, CpuConfigRegister
                    160:        mfc0    t3, COP_0_STATUS_REG
                    161:        sw      t2, CpuCacheType                # Save cache attributes
                    162:        sw      t3, CpuStatusRegister
                    163:        and     t2, CTYPE_WAYMASK               # isolate number of sets.
                    164:        sw      t2, CpuNWayCache
                    165:        srl     t2, 1                           # get div shift for set size.
                    166:
                    167:        sw      ta2, CpuSecondaryCacheSize
                    168:        sw      ta3, CpuTertiaryCacheSize
                    169:
                    170:        addu    t1, ta0, -1                     # Use icache for alias mask
                    171:        srl     t1, t2
                    172:        and     t1, ~(NBPG - 1)
                    173:        sw      t1, CpuCacheAliasMask
                    174:
                    175:        sw      ta0, CpuPrimaryInstCacheSize    # store cache size.
                    176:        srl     ta0, t2                         # calculate set size.
                    177:        sw      ta0, CpuPrimaryInstSetSize
                    178:
                    179:        sw      ta1, CpuPrimaryDataCacheSize    # store cache size.
                    180:        srl     ta1, t2                         # calculate set size.
                    181:        sw      ta1, CpuPrimaryDataSetSize
                    182:
                    183: #if 0
                    184:        and     v0, 0xfffffff8
                    185:        or      v0, 0x00000003                  # set cachable writeback kseg0
                    186:        mtc0    v0, COP_0_CONFIG                # establish any new config
                    187: #endif
                    188:        j       ra
                    189:        nop
                    190: END(Mips10k_ConfigCache)
                    191:
                    192: /*----------------------------------------------------------------------------
                    193:  *
                    194:  * Mips10k_SyncCache --
                    195:  *
                    196:  *     Sync ALL caches.
                    197:  *     No need to look at number of sets since we are cleaning out
                    198:  *     the entire cache and thus will address all sets anyway.
                    199:  *
                    200:  * Results:
                    201:  *     None.
                    202:  *
                    203:  * Side effects:
                    204:  *     The contents of ALL caches are Invalidated or Synched.
                    205:  *
                    206:  *----------------------------------------------------------------------------
                    207:  */
                    208: LEAF(Mips10k_SyncCache, 0)
                    209:        .set    noreorder
                    210:        lw      t1, CpuPrimaryInstSetSize
                    211:        lw      t2, CpuPrimaryDataSetSize
                    212:
                    213: /*
                    214:  * Sync the instruction cache.
                    215:  */
                    216:
                    217:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    218:        PTR_ADDU t1, t0, t1                     # Compute end address
                    219:        PTR_SUBU t1, 128
                    220:
                    221: 1:
                    222:        cache   IndexInvalidate_I, 0(t0)
                    223:        cache   IndexInvalidate_I, 64(t0)
                    224:
                    225:        cache   IndexInvalidate_I, 1(t0)
                    226:        cache   IndexInvalidate_I, 65(t0)
                    227:
                    228:        bne     t0, t1, 1b
                    229:        PTR_ADDU t0, t0, 128
                    230:
                    231: /*
                    232:  * Sync the data cache. Do L1 first. Indexed only operate on
                    233:  * the selected cache and differs from Hit in that sense.
                    234:  */
                    235:
                    236:        LOAD_XKPHYS(t0, CCA_NONCOHERENT)
                    237:        PTR_ADDU t1, t0, t2                     # End address
                    238:        PTR_SUBU t1, t1, 128
                    239: 1:
                    240:        cache   IndexWBInvalidate_D, 0(t0)
                    241:        cache   IndexWBInvalidate_D, 32(t0)
                    242:        cache   IndexWBInvalidate_D, 64(t0)
                    243:        cache   IndexWBInvalidate_D, 96(t0)
                    244:
                    245:        cache   IndexWBInvalidate_D, 1(t0)
                    246:        cache   IndexWBInvalidate_D, 33(t0)
                    247:        cache   IndexWBInvalidate_D, 65(t0)
                    248:        cache   IndexWBInvalidate_D, 97(t0)
                    249:
                    250:        bne     t0, t1, 1b
                    251:        PTR_ADDU t0, t0, 128
                    252:
                    253: /* Do L2 */
                    254:        LOAD_XKPHYS(t3, CCA_NONCOHERENT)
                    255:        lw      ta0, CpuSecondaryCacheSize      # XXX Need set size here.
                    256: 10:
                    257:        cache   IndexWBInvalidate_S, 0(t3)
                    258:        cache   IndexWBInvalidate_S, 1(t3)
                    259:        PTR_SUBU ta0, 32                        # Fixed cache line size.
                    260:        bgtz    ta0, 10b
                    261:        PTR_ADDU t3, 32
                    262:
                    263:        j       ra
                    264:        nop
                    265: END(Mips10k_SyncCache)
                    266:
                    267: /*----------------------------------------------------------------------------
                    268:  *
                    269:  * Mips10k_InvalidateICachePage --
                    270:  *
                    271:  *     void Mips10k_InvalidateICachePage(addr)
                    272:  *             vaddr_t addr;
                    273:  *
                    274:  *     Invalidate the L1 instruction cache page given by addr.
                    275:  *
                    276:  * Results:
                    277:  *     Void.
                    278:  *
                    279:  * Side effects:
                    280:  *     The contents of the L1 Instruction cache is flushed.
                    281:  *
                    282:  *----------------------------------------------------------------------------
                    283:  */
                    284: LEAF(Mips10k_InvalidateICachePage, 0)
                    285:        lw      v0, CpuNWayCache                # Cache properties
                    286:        and     a0, ~PAGE_MASK                  # Page align start address
                    287:        PTR_ADDU a1, a0, PAGE_SIZE-128          # End address.
                    288:        addiu   v0, -2                          # <0 1way, 0 = two, >0 four
                    289: 1:
                    290:        cache   HitInvalidate_I, 0(a0)
                    291:        cache   HitInvalidate_I, 64(a0)
                    292:
                    293:        bne     a0, a1, 1b
                    294:        PTR_ADDU a0, 128
                    295:
                    296:        j       ra
                    297:        move    v0, zero
                    298: END(Mips10k_InvalidateICachePage)
                    299:
                    300: /*----------------------------------------------------------------------------
                    301:  *
                    302:  * Mips10k_InvalidateICache --
                    303:  *
                    304:  *     void Mips10k_SyncICache(addr, len)
                    305:  *             vaddr_t addr, len;
                    306:  *
                    307:  *     Invalidate the L1 instruction cache for at least range
                    308:  *     of addr to addr + len - 1.
                    309:  *     The address is reduced to a XKPHYS index to avoid TLB faults.
                    310:  *
                    311:  * Results:
                    312:  *     None.
                    313:  *
                    314:  * Side effects:
                    315:  *     The contents of the L1 Instruction cache is flushed.
                    316:  *     Must not touch v0.
                    317:  *
                    318:  *----------------------------------------------------------------------------
                    319:  */
                    320: LEAF(Mips10k_InvalidateICache, 0)
                    321:        LOAD_XKPHYS(a2, CCA_NONCOHERENT)
                    322:        and     a0, 0x00ffffff                  # Reduce addr to cache index
                    323:        PTR_ADDU a1, 63                         # Round up size
                    324:        PTR_ADDU a1, a0                         # Add extra from address
                    325:        and     a0, -64                         # Align start address
                    326:        PTR_SUBU a1, a1, a0
                    327:        PTR_ADDU a0, a2                         # a0 now new XKPHYS address
                    328:        srl     a1, a1, 6                       # Number of unrolled loops
                    329: 1:
                    330:        addu    a1, -1
                    331:
                    332:        cache   IndexInvalidate_I, 0(a0)        # do set A
                    333:        cache   IndexInvalidate_I, 1(a0)        # do set B
                    334:
                    335:        bne     a1, zero, 1b
                    336:        PTR_ADDU a0, 64
                    337:
                    338:        j       ra
                    339:        move    v0, zero
                    340: END(Mips10k_InvalidateICache)
                    341:
                    342: /*----------------------------------------------------------------------------
                    343:  *
                    344:  * Mips10k_SyncDCachePage --
                    345:  *
                    346:  *     void Mips10k_SyncDCachePage(addr)
                    347:  *             vaddr_t addr;
                    348:  *
                    349:  *     Sync the L1 data cache page for address addr.
                    350:  *     The address is reduced to a XKPHYS index to avoid TLB faults.
                    351:  *
                    352:  * Results:
                    353:  *     None.
                    354:  *
                    355:  * Side effects:
                    356:  *     The contents of the cache is written back to primary memory.
                    357:  *     The cache line is invalidated.
                    358:  *
                    359:  *----------------------------------------------------------------------------
                    360:  */
                    361: LEAF(Mips10k_SyncDCachePage, 0)
                    362:        LOAD_XKPHYS(a2, CCA_NONCOHERENT)
                    363:        dsll    a0, 34
                    364:        dsrl    a0, 34
                    365:        PTR_ADDU a0, a2                         # a0 now new XKPHYS address
                    366:        and     a0, ~PAGE_MASK                  # Page align start address
                    367:        PTR_ADDU a1, a0, PAGE_SIZE-128
                    368:
                    369: 1:
                    370:        cache   IndexWBInvalidate_D, 0(a0)      # do set A
                    371:        cache   IndexWBInvalidate_D, 32(a0)
                    372:        cache   IndexWBInvalidate_D, 64(a0)
                    373:        cache   IndexWBInvalidate_D, 96(a0)
                    374:
                    375:        cache   IndexWBInvalidate_D, 1(a0)      # do set B
                    376:        cache   IndexWBInvalidate_D, 33(a0)
                    377:        cache   IndexWBInvalidate_D, 65(a0)
                    378:        cache   IndexWBInvalidate_D, 97(a0)
                    379:
                    380:        bne     a1, a0, 1b
                    381:        PTR_ADDU a0, 128
                    382:
                    383:        j       ra
                    384:        nop
                    385: END(Mips10k_SyncDCachePage)
                    386:
                    387: /*----------------------------------------------------------------------------
                    388:  *
                    389:  * Mips10k_HitSyncDCache --
                    390:  *
                    391:  *     void Mips10k_HitSyncDCache(addr, len)
                    392:  *             vaddr_t addr, len;
                    393:  *
                    394:  *     Sync data cache for range of addr to addr + len - 1.
                    395:  *     The address can be any valid virtual address as long
                    396:  *     as no TLB invalid traps occur. Only lines with matching
                    397:  *     addr are flushed.
                    398:  *
                    399:  *     Note: Use the CpuNWayCache flag to select 16 or 32 byte linesize.
                    400:  *           All Nway cpu's now available have a fixed 32byte linesize.
                    401:  *
                    402:  * Results:
                    403:  *     None.
                    404:  *
                    405:  * Side effects:
                    406:  *     The contents of the L1 cache is written back to primary memory.
                    407:  *     The cache line is invalidated.
                    408:  *
                    409:  *----------------------------------------------------------------------------
                    410:  */
                    411: LEAF(Mips10k_HitSyncDCache, 0)
                    412:        beq     a1, zero, 3f                    # size is zero!
                    413:        PTR_ADDU a1, 31                         # Round up
                    414:        PTR_ADDU a1, a1, a0                     # Add extra from address
                    415:        and     a0, a0, -32                     # align address
                    416:        PTR_SUBU a1, a1, a0
                    417:        srl     a1, a1, 5                       # Compute number of cache lines
                    418:
                    419: 1:
                    420:        PTR_ADDU a1, -1
                    421:        cache   HitWBInvalidate_D, 0(a0)
                    422:        bne     a1, zero, 1b
                    423:        PTR_ADDU a0, 32
                    424:
                    425: 3:
                    426:        j       ra
                    427:        nop
                    428: END(Mips10k_HitSyncDCache)
                    429:
                    430:
                    431: /*----------------------------------------------------------------------------
                    432:  *
                    433:  * Mips10k_HitSyncSCache --
                    434:  *
                    435:  *     void Mips10k_HitSyncSCache(addr, len)
                    436:  *             vaddr_t addr, len;
                    437:  *
                    438:  *     Sync secondary cache for range of addr to addr + len - 1.
                    439:  *     The address can be any valid virtual address as long
                    440:  *     as no TLB invalid traps occur. Only lines with matching
                    441:  *     addr are flushed.
                    442:  *
                    443:  * Results:
                    444:  *     None.
                    445:  *
                    446:  * Side effects:
                    447:  *     The contents of the L2 cache is written back to primary memory.
                    448:  *     The cache line is invalidated.
                    449:  *
                    450:  *----------------------------------------------------------------------------
                    451:  */
                    452: LEAF(Mips10k_HitSyncSCache, 0)
                    453:        beq     a1, zero, 3f                    # size is zero!
                    454:        PTR_ADDU a1, a1, a0                     # Add in extra from align
                    455:        and     a0, a0, -32                     # Align address
                    456:        PTR_SUBU a1, a1, a0
                    457: 1:
                    458:        PTR_ADDU a1, -32
                    459:
                    460:        cache   HitWBInvalidate_S, 0(a0)
                    461:
                    462:        bgtz    a1, 1b
                    463:        PTR_ADDU a0, 32
                    464:
                    465: 3:
                    466:        j       ra
                    467:        nop
                    468: END(Mips10k_HitSyncSCache)
                    469:
                    470: /*----------------------------------------------------------------------------
                    471:  *
                    472:  * Mips10k_HitInvalidateDCache --
                    473:  *
                    474:  *     void Mips10k_HitInvalidateDCache(addr, len)
                    475:  *             vaddr_t addr, len;
                    476:  *
                    477:  *     Invalidate data cache for range of addr to addr + len - 1.
                    478:  *     The address can be any valid address as long as no TLB misses occur.
                    479:  *     (Be sure to use cached K0SEG kernel addresses or mapped addresses)
                    480:  *     Only lines with matching addresses are invalidated.
                    481:  *
                    482:  * Results:
                    483:  *     None.
                    484:  *
                    485:  * Side effects:
                    486:  *     The L1 cache line is invalidated.
                    487:  *
                    488:  *----------------------------------------------------------------------------
                    489:  */
                    490: LEAF(Mips10k_HitInvalidateDCache, 0)
                    491:        beq     a1, zero, 3f                    # size is zero!
                    492:        PTR_ADDU a1, a1, a0                     # Add in extra from align
                    493:        and     a0, a0, -32                     # Align address
                    494:        PTR_SUBU a1, a1, a0
                    495:
                    496: 1:
                    497:        PTR_ADDU a1, -32
                    498:
                    499:        cache   HitInvalidate_D, 0(a0)
                    500:
                    501:        bgtz    a1, 1b
                    502:        PTR_ADDU a0, 32
                    503:
                    504: 3:
                    505:        j       ra
                    506:        nop
                    507: END(Mips10k_HitInvalidateDCache)
                    508:
                    509:
                    510: /*----------------------------------------------------------------------------
                    511:  *
                    512:  * Mips10k_HitInvalidateSCache --
                    513:  *
                    514:  *     void Mips10k_HitInvalidateSCache(addr, len)
                    515:  *             vaddr_t addr, len;
                    516:  *
                    517:  *     Invalidate secondary cache for range of addr to addr + len - 1.
                    518:  *     The address can be any valid address as long as no TLB misses occur.
                    519:  *     (Be sure to use cached K0SEG kernel addresses or mapped addresses)
                    520:  *     Only lines with matching addresses are invalidated.
                    521:  *
                    522:  * Results:
                    523:  *     None.
                    524:  *
                    525:  * Side effects:
                    526:  *     The L2 cache line is invalidated.
                    527:  *
                    528:  *----------------------------------------------------------------------------
                    529:  */
                    530: LEAF(Mips10k_HitInvalidateSCache, 0)
                    531:        beq     a1, zero, 3f                    # size is zero!
                    532:        PTR_ADDU a1, a1, a0                     # Add in extra from align
                    533:        and     a0, a0, -32                     # Align address
                    534:        PTR_SUBU a1, a1, a0
                    535: 1:
                    536:        PTR_ADDU a1, -32
                    537:
                    538:        cache   HitInvalidate_S, 0(a0)
                    539:
                    540:        bgtz    a1, 1b
                    541:        PTR_ADDU a0, 32
                    542:
                    543: 3:
                    544:        j       ra
                    545:        nop
                    546: END(Mips10k_HitInvalidateSCache)
                    547:
                    548: /*----------------------------------------------------------------------------
                    549:  *
                    550:  * Mips10k_IOSyncDCache --
                    551:  *
                    552:  *     void Mips10k_IOSyncDCache(addr, len, rw)
                    553:  *             vaddr_t addr;
                    554:  *             int  len, rw;
                    555:  *
                    556:  *     Invalidate or flush data cache for range of addr to addr + len - 1.
                    557:  *     The address can be any valid address as long as no TLB misses occur.
                    558:  *     (Be sure to use cached K0SEG kernel addresses or mapped addresses)
                    559:  *
                    560:  * Results:
                    561:  *     None.
                    562:  *
                    563:  * Side effects:
                    564:  *     If rw == 0 (read), L1 and L2 caches are invalidated or
                    565:  *             flushed if the area does not match the alignment
                    566:  *             requirements.
                    567:  *     If rw == 1 (write), L1 and L2 caches are written back
                    568:  *             to memory and invalidated.
                    569:  *     If rw == 2 (write-read), L1 and L2 caches are written back
                    570:  *             to memory and invalidated.
                    571:  *
                    572:  *----------------------------------------------------------------------------
                    573:  */
                    574: NON_LEAF(Mips10k_IOSyncDCache, FRAMESZ(CF_SZ+2*REGSZ), ra)
                    575:
                    576:        PTR_SUBU sp, FRAMESZ(CF_SZ+2*REGSZ)
                    577:        PTR_S   ra, CF_RA_OFFS+2*REGSZ(sp)
                    578:        REG_S   a0, CF_ARGSZ(sp)                # save args
                    579:        beqz    a2, SyncRD                      # Sync PREREAD
                    580:        REG_S   a1, CF_ARGSZ+REGSZ(sp)
                    581:        addiu   a2, -1
                    582:        bnez    a2, SyncRDWB                    # Sync PREWRITE+PREREAD
                    583:        nop
                    584:
                    585: SyncWR:
                    586:        jal     Mips10k_HitSyncSCache           # Do L2 cache
                    587:        nop                                     # L1 done in parallel
                    588:        b       SyncDone
                    589:        PTR_L   ra, CF_RA_OFFS+2*REGSZ(sp)
                    590:
                    591: SyncRD:
                    592:        and     t0, a0, 63                      # check if invalidate possible
                    593:        bnez    t0, SyncRDWB                    # both address and size must
                    594:        and     t0, a1, 63                      # be aligned at the cache size
                    595:        bnez    t0, SyncRDWB
                    596:        nop
                    597:
                    598: /*
                    599:  *  Sync for aligned read, no writeback required.
                    600:  */
                    601:        jal     Mips10k_HitInvalidateSCache     # L2 cache
                    602:        nop                                     # L1 done in parallel
                    603:
                    604:        b       SyncDone
                    605:        PTR_L   ra, CF_RA_OFFS+2*REGSZ(sp)
                    606:
                    607: /*
                    608:  *  Sync for unaligned read or write-read.
                    609:  */
                    610: SyncRDWB:
                    611:        jal     Mips10k_HitSyncSCache           # L2 cache
                    612:        nop                                     # L1 done in parallel
                    613:
                    614:        PTR_L   ra, CF_RA_OFFS+2*REGSZ(sp)
                    615:
                    616: SyncDone:
                    617:        j       ra
                    618:        PTR_ADDU sp, FRAMESZ(CF_SZ+2*REGSZ)
                    619: END(Mips10k_IOSyncDCache)

CVSweb