Annotation of XNU/osfmk/ppc/cache.s, revision 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.