Annotation of kernel/machdep/ppc/cache.s, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  * HISTORY
                     27:  * 25-Feb-1998 Umesh Vaishampayan ([email protected])
                     28:  *     Optimized flush_cache(), flush_cache_v().
                     29:  *     Moved kdp_flush_icache() to this file.
                     30:  *
                     31:  * Revision 1.1.1.1  1997/09/30 02:45:20  wsanchez
                     32:  * Import of kernel from umeshv/kernel
                     33:  *
                     34:  * Revision 1.1.1.1  1997/05/15  22:25:00  rvega
                     35:  *     Remove invalidate_tlb. cleanupuse of sync/isync
                     36:  *     [1997/05/15  22:25:00  rvega]
                     37:  *
                     38:  * Revision 1.1.1.1  1997/04/30  15:55:55  rvega
                     39:  *     Add required context synchronization around tlbie. Remove unnecessary
                     40:  *     sr diddling.
                     41:  *     [1997/04/30  16:55:55  rvega]
                     42:  *
                     43:  */
                     44:  
                     45:  /*
                     46:  * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991  
                     47:  *              All Rights Reserved 
                     48:  *  
                     49:  * Permission to use, copy, modify, and distribute this software and 
                     50:  * its documentation for any purpose and without fee is hereby granted, 
                     51:  * provided that the above copyright notice appears in all copies and 
                     52:  * that both the copyright notice and this permission notice appear in 
                     53:  * supporting documentation. 
                     54:  *  
                     55:  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
                     56:  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
                     57:  * FOR A PARTICULAR PURPOSE. 
                     58:  *  
                     59:  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
                     60:  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
                     61:  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
                     62:  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
                     63:  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
                     64:  */
                     65: /*
                     66:  * MKLINUX-1.0DR2
                     67:  */
                     68: 
                     69: #include <machdep/ppc/asm.h>
                     70: #include <machdep/ppc/proc_reg.h>
                     71: #include <cpus.h>
                     72: #include <assym.h>
                     73: #include <mach/ppc/vm_param.h>
                     74: 
                     75: /*
                     76:  * extern void flush_cache(vm_offset_t pa, unsigned count);
                     77:  *
                     78:  * flush_cache takes a physical address and count to flush, thus
                     79:  * must not be called for multiple virtual pages.
                     80:  *
                     81:  * it flushes the data cache and invalidates the instruction
                     82:  * cache for the address range in question
                     83:  */
                     84: 
                     85: ENTRY(flush_cache, TAG_NO_FRAME_USED)
                     86: 
                     87:        /* Switch off data translations */
                     88:        mfmsr   r6
                     89:        rlwinm  r7,     r6,     0,      MSR_DR_BIT+1,   MSR_DR_BIT-1
                     90:        mtmsr   r7
                     91:        isync
                     92: 
                     93:        /* Check to see if the address is aligned. */
                     94:        add     r8, ARG0,ARG1
                     95:        andi.   r8,r8,(CACHE_LINE_SIZE-1)
                     96:        beq-    L_flush_check
                     97:        addi    ARG1,ARG1,CACHE_LINE_SIZE
                     98: 
                     99: L_flush_check:
                    100:        /* Make ctr hold count of how many times we should loop */
                    101:        srwi.   r8,     ARG1,   CACHE_LINE_POW2
                    102:        /* If less than 32 to do, jump over loop */
                    103:        beq- L_flush_cache_done
                    104:        mr      r7, r8          /* remember r8 for the icbi loop */
                    105:        mr      r9, ARG1        /* remember ARG1 for icbi loop */
                    106:        mtctr   r8                      /* the loop count */
                    107: 
                    108: L_flush_loop:
                    109:        subic   ARG1,   ARG1,   CACHE_LINE_SIZE
                    110: #ifndef        UNCACHED_DATA_604
                    111:        //dcbf  ARG0,   ARG1
                    112:        dcbst   ARG0,   ARG1
                    113: #endif /* UNCACHED_DATA_604 */
                    114:        bdnz    L_flush_loop
                    115:        sync
                    116: 
                    117:        mr      ARG1, r9        /* restore ARG1 */
                    118:        mtctr   r7              /* restore the loop count */
                    119: L_invalidate_loop:
                    120:        subic   ARG1,   ARG1,   CACHE_LINE_SIZE
                    121: #ifndef        UNCACHED_INST_604
                    122:        icbi    ARG0,   ARG1
                    123: #endif /* UNCACHED_INST_604 */
                    124:        bdnz    L_invalidate_loop
                    125:        sync
                    126:        isync
                    127: 
                    128: L_flush_cache_done:
                    129: #ifndef        UNCACHED_DATA_604
                    130:        //dcbf  0,ARG0
                    131:        dcbst   0,ARG0
                    132:        sync
                    133: #endif /* UNCACHED_DATA_604 */
                    134: #ifndef        UNCACHED_INST_604
                    135:        icbi    0,ARG0
                    136: 
                    137:        sync                    /* Finish physical writes */
                    138:        isync                   /* Ensure data translations are on */
                    139: #endif /* UNCACHED_INST_604 */
                    140: 
                    141:        mtmsr   r6              /* Restore original translations */
                    142:        isync                   /* Ensure data translations are on */
                    143: 
                    144:        blr
                    145: 
                    146: /*
                    147:  * extern void flush_cache_v(vm_offset_t pa, unsigned count);
                    148:  *
                    149:  * flush_cache_v takes a virtual address and count to flush, thus
                    150:  * can be called for multiple virtual pages.
                    151:  *
                    152:  * it flushes the data cache and invalidates the instruction
                    153:  * cache for the address range in question
                    154:  */
                    155: 
                    156: ENTRY(flush_cache_v, TAG_NO_FRAME_USED)
                    157:        /* Check to see if the address is aligned. */
                    158:        add     r8, ARG0,ARG1
                    159:        andi.   r8,r8,(CACHE_LINE_SIZE-1)
                    160:        beq-    L_flushv_check
                    161:        addi    ARG1,ARG1,CACHE_LINE_SIZE
                    162: 
                    163: L_flushv_check:
                    164:        /* Make ctr hold count of how many times we should loop */
                    165:        srwi.   r8,     ARG1,   CACHE_LINE_POW2
                    166:        /* If less than 32 to do, jump over loop */
                    167:        beq- L_flush_cache_v_done
                    168:        mr      r7, r8          /* remember r8 for the icbi loop */
                    169:        mr      r9, ARG1        /* remember ARG1 for icbi loop */
                    170:        mtctr   r8
                    171: 
                    172: L_flushv_loop:
                    173:        subic   ARG1,   ARG1,   CACHE_LINE_SIZE
                    174: #ifndef        UNCACHED_DATA_604
                    175:        //dcbf  ARG0,   ARG1
                    176:        dcbst   ARG0,   ARG1
                    177: #endif /* UNCACHED_DATA_604 */
                    178:        bdnz    L_flushv_loop
                    179:        sync
                    180: 
                    181:        mr      ARG1, r9        /* restore ARG1 */
                    182:        mtctr   r7              /* restore the loop count */
                    183: L_cachev_invalidate_loop:
                    184:        subic   ARG1,   ARG1,   CACHE_LINE_SIZE
                    185: #ifndef        UNCACHED_INST_604
                    186:        icbi    ARG0,   ARG1
                    187: #endif /* UNCACHED_INST_604 */
                    188:        bdnz    L_cachev_invalidate_loop
                    189:        sync
                    190:        isync
                    191: 
                    192: L_flush_cache_v_done:
                    193: #ifndef        UNCACHED_DATA_604
                    194:        //dcbf  0,ARG0
                    195:        dcbst   0,ARG0
                    196:        sync
                    197: #endif /* UNCACHED_DATA_604 */
                    198: #ifndef        UNCACHED_INST_604
                    199:        icbi    0,ARG0
                    200: 
                    201:        sync            /* make sure flushes have completed */
                    202:        isync
                    203: #endif /* UNCACHED_INST_604 */
                    204: 
                    205:        blr
                    206: 
                    207: /*
                    208:  * extern void invalidate_cache_v(vm_offset_t pa, unsigned count);
                    209:  */
                    210: 
                    211: ENTRY(invalidate_cache_v, TAG_NO_FRAME_USED)
                    212:        /* Check to see if the address is aligned. */
                    213:        add     r8, ARG0,ARG1
                    214:        andi.   r8,r8,(CACHE_LINE_SIZE-1)
                    215:        beq-    L_invalidate_checkv
                    216:        addi    ARG1,ARG1,CACHE_LINE_SIZE
                    217: 
                    218: L_invalidate_checkv:
                    219:        /* Make ctr hold count of how many times we should loop */
                    220:        srwi.   r8,     ARG1,   CACHE_LINE_POW2
                    221:        /* If less than 32 to do, jump over loop */
                    222:        beq- L_invalidate_cache_v_done
                    223:        mr      r7, r8          /* remember r8 for the icbi loop */
                    224:        mr      r9, ARG1        /* remember ARG1 for icbi loop */
                    225:        mtctr   r8
                    226: 
                    227: L_invalidatev_loop:
                    228:        subic   ARG1,   ARG1,   CACHE_LINE_SIZE
                    229: #ifndef        UNCACHED_DATA_604
                    230:        dcbi    ARG0,   ARG1
                    231:        dcbi    ARG0,   ARG1    /* fix for dcbi bug */
                    232: #endif /* UNCACHED_DATA_604 */
                    233:        bdnz    L_invalidatev_loop
                    234:        sync
                    235: 
                    236:        mr      ARG1, r9        /* restore ARG1 */
                    237:        mtctr   r7              /* restore the loop count */
                    238: L_invalidatev_loop2:
                    239:        subic   ARG1,   ARG1,   CACHE_LINE_SIZE
                    240: #ifndef        UNCACHED_INST_604
                    241:        icbi    ARG0,   ARG1
                    242: #endif /* UNCACHED_INST_604 */
                    243:        bdnz    L_invalidatev_loop2
                    244:        sync
                    245:        isync
                    246: 
                    247: L_invalidate_cache_v_done:
                    248: #ifndef        UNCACHED_DATA_604
                    249:        dcbi    0,ARG0
                    250:        dcbi    0,ARG0          /* fix for dcbi bug */
                    251:        sync
                    252: #endif /* UNCACHED_DATA_604 */
                    253: #ifndef        UNCACHED_INST_604
                    254:        icbi    0,ARG0
                    255: 
                    256:        sync            /* make sure invalidates have completed */
                    257:        isync
                    258: #endif /* UNCACHED_INST_604 */
                    259: 
                    260:        blr
                    261: 
                    262: 
                    263: /*
                    264:  * void        kdp_flush_icache(caddr_t addr,  unsigned count)
                    265:  * 
                    266:  * Flush the data cache, invalidate the code cache for all cache lines in the
                    267:  * specified range.  This enables execution of the instructions stored via the
                    268:  * data cache (e.g. code read in by noncoherent logical I/O or code generated
                    269:  * "on-the-fly").
                    270:  * 
                    271:  * NOTE: The dcbf instruction takes a logical address.  This means that addr
                    272:  * must be valid in the current address space.  Further, it "acts as a store
                    273:  * to the addressed byte with respect to address translation and protection. 
                    274:  * The reference and changed bits are set accordingly."  So, make sure the
                    275:  * page is not read-only!  Use the static mapping.
                    276:  */
                    277: .set kLog2CacheLineSize, 5
                    278: .set kCacheLineSize, 32
                    279: 
                    280: ENTRY(kdp_flush_icache, TAG_NO_FRAME_USED)
                    281:        cmpi    CR0,0,r4,0                      // is this zero length?
                    282:        add     r4,r3,r4                        // calculate last byte + 1
                    283:        subi    r4,r4,1                         // calculate last byte
                    284: 
                    285:        srwi    r5,r3,kLog2CacheLineSize        // calc first cache line index
                    286:        srwi    r4,r4,kLog2CacheLineSize        // calc last cache line index
                    287:        beq     cr0, LdataToCodeDone            // done if zero length
                    288: 
                    289:        subf    r4,r5,r4                        // calc diff (# lines minus 1)
                    290:        addi    r4,r4,1                         // # of cache lines to flush
                    291:        slwi    r5,r5,kLog2CacheLineSize        // calc addr of first cache line
                    292: 
                    293:        // flush the data cache lines
                    294:        mr      r3,r5                           // starting address for loop
                    295:        mtctr   r4                              // loop count
                    296: LdataToCodeFlushLoop:
                    297: #ifndef UNCACHED_DATA_604
                    298:        //dcbf  0, r3                           // flush the data cache line
                    299:        dcbst   0, r3                           // flush the data cache line
                    300: #endif
                    301:        addi    r3,r3,kCacheLineSize            // advance to next cache line
                    302:        bdnz    LdataToCodeFlushLoop            // loop until count is zero
                    303:        sync                                    // wait until RAM is valid
                    304: 
                    305:        // invalidate the code cache lines
                    306:        mr      r3,r5                           // starting address for loop
                    307:        mtctr   r4                              // loop count
                    308: LdataToCodeInvalidateLoop:
                    309: #ifndef UNCACHED_INST_604
                    310:        icbi    0, r3                           // invalidate code cache line
                    311: #endif
                    312:        addi    r3,r3,kCacheLineSize            // advance to next cache line
                    313:        bdnz    LdataToCodeInvalidateLoop       // loop until count is zero
                    314:        sync                                    // wait until last icbi completes
                    315:        isync                                   // discard prefetched instructions, too
                    316: 
                    317: LdataToCodeDone:
                    318:        blr                                     // return nothing

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.