Annotation of XNU/osfmk/ppc/cache.s, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: 
                     26: #include <cpus.h>
                     27: 
                     28: #include <ppc/asm.h>
                     29: #include <ppc/proc_reg.h>
                     30: #include <cpus.h>
                     31: #include <assym.s>
                     32: #include <mach_debug.h>
                     33: #include <mach/ppc/vm_param.h>
                     34: 
                     35: /*
                     36:  * extern void sync_cache(vm_offset_t pa, unsigned count);
                     37:  *
                     38:  * sync_cache takes a physical address and count to sync, thus
                     39:  * must not be called for multiple virtual pages.
                     40:  *
                     41:  * it writes out the data cache and invalidates the instruction
                     42:  * cache for the address range in question
                     43:  */
                     44: 
                     45: ENTRY(sync_cache, TAG_NO_FRAME_USED)
                     46: 
                     47:        /* Switch off data translations */
                     48:        mfmsr   r6
                     49:        rlwinm  r7,     r6,     0,      MSR_DR_BIT+1,   MSR_DR_BIT-1
                     50:        mtmsr   r7
                     51:        isync
                     52: 
                     53:        /* Check to see if the address is aligned. */
                     54:        add     r8, r3,r4
                     55:        andi.   r8,r8,(CACHE_LINE_SIZE-1)
                     56:        beq-    .L_sync_check
                     57:        addi    r4,r4,CACHE_LINE_SIZE
                     58:        li      r7,(CACHE_LINE_SIZE-1)  /* Align buffer & count - avoid overflow problems */
                     59:        andc    r4,r4,r7
                     60:        andc    r3,r3,r7
                     61: 
                     62: .L_sync_check:
                     63:        cmpwi   r4,     CACHE_LINE_SIZE
                     64:        ble     .L_sync_one_line
                     65:        
                     66:        /* Make ctr hold count of how many times we should loop */
                     67:        addi    r8,     r4,     (CACHE_LINE_SIZE-1)
                     68:        srwi    r8,     r8,     CACHE_LINE_POW2
                     69:        mtctr   r8
                     70: 
                     71:        /* loop to flush the data cache */
                     72: .L_sync_data_loop:
                     73:        subic   r4,     r4,     CACHE_LINE_SIZE
                     74:        dcbst   r3,     r4
                     75:        bdnz    .L_sync_data_loop
                     76:        
                     77:        sync
                     78:        mtctr   r8
                     79: 
                     80:        /* loop to invalidate the instruction cache */
                     81: .L_sync_inval_loop:
                     82:        icbi    r3,     r4
                     83:        addic   r4,     r4,     CACHE_LINE_SIZE
                     84:        bdnz    .L_sync_inval_loop
                     85: 
                     86: .L_sync_cache_done:
                     87:        sync                    /* Finish physical writes */
                     88:        mtmsr   r6              /* Restore original translations */
                     89:        isync                   /* Ensure data translations are on */
                     90:        blr
                     91: 
                     92: .L_sync_one_line:
                     93:        dcbst   0,r3
                     94:        sync
                     95:        icbi    0,r3
                     96:        b       .L_sync_cache_done
                     97: 
                     98: /*
                     99:  * extern void flush_dcache(vm_offset_t addr, unsigned count, boolean phys);
                    100:  *
                    101:  * flush_dcache takes a virtual or physical address and count to flush
                    102:  * and (can be called for multiple virtual pages).
                    103:  *
                    104:  * it flushes the data cache
                    105:  * cache for the address range in question
                    106:  *
                    107:  * if 'phys' is non-zero then physical addresses will be used
                    108:  */
                    109: 
                    110: ENTRY(flush_dcache, TAG_NO_FRAME_USED)
                    111: 
                    112:        /* optionally switch off data translations */
                    113: 
                    114:        cmpwi   r5,     0
                    115:        mfmsr   r6
                    116:        beq+    0f
                    117:        rlwinm  r7,     r6,     0,      MSR_DR_BIT+1,   MSR_DR_BIT-1
                    118:        mtmsr   r7
                    119:        isync
                    120: 0:     
                    121: 
                    122:        /* Check to see if the address is aligned. */
                    123:        add     r8, r3,r4
                    124:        andi.   r8,r8,(CACHE_LINE_SIZE-1)
                    125:        beq-    .L_flush_dcache_check
                    126:        addi    r4,r4,CACHE_LINE_SIZE
                    127:        li      r7,(CACHE_LINE_SIZE-1)  /* Align buffer & count - avoid overflow problems */
                    128:        andc    r4,r4,r7
                    129:        andc    r3,r3,r7
                    130: 
                    131: .L_flush_dcache_check:
                    132:        cmpwi   r4,     CACHE_LINE_SIZE
                    133:        ble     .L_flush_dcache_one_line
                    134:        
                    135:        /* Make ctr hold count of how many times we should loop */
                    136:        addi    r8,     r4,     (CACHE_LINE_SIZE-1)
                    137:        srwi    r8,     r8,     CACHE_LINE_POW2
                    138:        mtctr   r8
                    139: 
                    140: .L_flush_dcache_flush_loop:
                    141:        subic   r4,     r4,     CACHE_LINE_SIZE
                    142:        dcbf    r3,     r4
                    143:        bdnz    .L_flush_dcache_flush_loop
                    144: 
                    145: .L_flush_dcache_done:
                    146:        /* Sync restore msr if it was modified */
                    147:        cmpwi   r5,     0
                    148:        sync                    /* make sure invalidates have completed */
                    149:        beq+    0f
                    150:        mtmsr   r6              /* Restore original translations */
                    151:        isync                   /* Ensure data translations are on */
                    152: 0:
                    153:        blr
                    154: 
                    155: .L_flush_dcache_one_line:
                    156:        xor     r4,r4,r4
                    157:        dcbf    0,r3
                    158:        b       .L_flush_dcache_done
                    159: 
                    160: 
                    161: /*
                    162:  * extern void invalidate_dcache(vm_offset_t va, unsigned count, boolean phys);
                    163:  *
                    164:  * invalidate_dcache takes a virtual or physical address and count to
                    165:  * invalidate and (can be called for multiple virtual pages).
                    166:  *
                    167:  * it invalidates the data cache for the address range in question
                    168:  */
                    169: 
                    170: ENTRY(invalidate_dcache, TAG_NO_FRAME_USED)
                    171: 
                    172:        /* optionally switch off data translations */
                    173: 
                    174:        cmpwi   r5,     0
                    175:        mfmsr   r6
                    176:        beq+    0f
                    177:        rlwinm  r7,     r6,     0,      MSR_DR_BIT+1,   MSR_DR_BIT-1
                    178:        mtmsr   r7
                    179:        isync
                    180: 0:     
                    181: 
                    182:        /* Check to see if the address is aligned. */
                    183:        add     r8, r3,r4
                    184:        andi.   r8,r8,(CACHE_LINE_SIZE-1)
                    185:        beq-    .L_invalidate_dcache_check
                    186:        addi    r4,r4,CACHE_LINE_SIZE
                    187:        li      r7,(CACHE_LINE_SIZE-1)  /* Align buffer & count - avoid overflow problems */
                    188:        andc    r4,r4,r7
                    189:        andc    r3,r3,r7
                    190: 
                    191: .L_invalidate_dcache_check:
                    192:        cmpwi   r4,     CACHE_LINE_SIZE
                    193:        ble     .L_invalidate_dcache_one_line
                    194:        
                    195:        /* Make ctr hold count of how many times we should loop */
                    196:        addi    r8,     r4,     (CACHE_LINE_SIZE-1)
                    197:        srwi    r8,     r8,     CACHE_LINE_POW2
                    198:        mtctr   r8
                    199: 
                    200: .L_invalidate_dcache_invalidate_loop:
                    201:        subic   r4,     r4,     CACHE_LINE_SIZE
                    202:        dcbi    r3,     r4
                    203:        dcbi    r3,     r4
                    204:        bdnz    .L_invalidate_dcache_invalidate_loop
                    205: 
                    206: .L_invalidate_dcache_done:
                    207:        /* Sync restore msr if it was modified */
                    208:        cmpwi   r5,     0
                    209:        sync                    /* make sure invalidates have completed */
                    210:        beq+    0f
                    211:        mtmsr   r6              /* Restore original translations */
                    212:        isync                   /* Ensure data translations are on */
                    213: 0:
                    214:        blr
                    215: 
                    216: .L_invalidate_dcache_one_line:
                    217:        xor     r4,r4,r4
                    218:        dcbi    0,r3
                    219:        dcbi    0,r3
                    220:        b       .L_invalidate_dcache_done
                    221: 
                    222: /*
                    223:  * extern void invalidate_icache(vm_offset_t addr, unsigned cnt, boolean phys);
                    224:  *
                    225:  * invalidate_icache takes a virtual or physical address and
                    226:  * count to invalidate, (can be called for multiple virtual pages).
                    227:  *
                    228:  * it invalidates the instruction cache for the address range in question.
                    229:  */
                    230: 
                    231: ENTRY(invalidate_icache, TAG_NO_FRAME_USED)
                    232: 
                    233:        /* optionally switch off data translations */
                    234:        cmpwi   r5,     0
                    235:        mfmsr   r6
                    236:        beq+    0f
                    237:        rlwinm  r7,     r6,     0,      MSR_DR_BIT+1,   MSR_DR_BIT-1
                    238:        mtmsr   r7
                    239:        isync
                    240: 0:     
                    241: 
                    242:        /* Check to see if the address is aligned. */
                    243:        add     r8, r3,r4
                    244:        andi.   r8,r8,(CACHE_LINE_SIZE-1)
                    245:        beq-    .L_invalidate_icache_check
                    246:        addi    r4,r4,CACHE_LINE_SIZE
                    247:        li      r7,(CACHE_LINE_SIZE-1)  /* Align buffer & count - avoid overflow problems */
                    248:        andc    r4,r4,r7
                    249:        andc    r3,r3,r7
                    250: 
                    251: .L_invalidate_icache_check:
                    252:        cmpwi   r4,     CACHE_LINE_SIZE
                    253:        ble     .L_invalidate_icache_one_line
                    254:        
                    255:        /* Make ctr hold count of how many times we should loop */
                    256:        addi    r8,     r4,     (CACHE_LINE_SIZE-1)
                    257:        srwi    r8,     r8,     CACHE_LINE_POW2
                    258:        mtctr   r8
                    259: 
                    260: .L_invalidate_icache_invalidate_loop:
                    261:        subic   r4,     r4,     CACHE_LINE_SIZE
                    262:        icbi    r3,     r4
                    263:        icbi    r3,     r4
                    264:        bdnz    .L_invalidate_icache_invalidate_loop
                    265: 
                    266: .L_invalidate_icache_done:
                    267:        /* Sync restore msr if it was modified */
                    268:        cmpwi   r5,     0
                    269:        sync                    /* make sure invalidates have completed */
                    270:        beq+    0f
                    271:        mtmsr   r6              /* Restore original translations */
                    272:        isync                   /* Ensure data translations are on */
                    273: 0:
                    274:        blr
                    275: 
                    276: .L_invalidate_icache_one_line:
                    277:        xor     r4,r4,r4
                    278:        icbi    0,r3
                    279:        icbi    0,r3
                    280:        b       .L_invalidate_icache_done

unix.superglobalmegacorp.com

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