2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
29 #include <ppc/proc_reg.h>
32 #include <mach_debug.h>
33 #include <mach/ppc/vm_param.h>
36 * extern void sync_cache(vm_offset_t pa, unsigned count);
38 * sync_cache takes a physical address and count to sync, thus
39 * must not be called for multiple virtual pages.
41 * it writes out the data cache and invalidates the instruction
42 * cache for the address range in question
45 ENTRY(sync_cache, TAG_NO_FRAME_USED)
47 /* Switch off data translations */
49 rlwinm r6,r6,0,MSR_FP_BIT+1,MSR_FP_BIT-1 ; Force floating point off
50 rlwinm r6,r6,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1 ; Force vectors off
51 rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
55 /* Check to see if the address is aligned. */
57 andi. r8,r8,(CACHE_LINE_SIZE-1)
59 addi r4,r4,CACHE_LINE_SIZE
60 li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
65 cmpwi r4, CACHE_LINE_SIZE
68 /* Make ctr hold count of how many times we should loop */
69 addi r8, r4, (CACHE_LINE_SIZE-1)
70 srwi r8, r8, CACHE_LINE_POW2
73 /* loop to flush the data cache */
75 subic r4, r4, CACHE_LINE_SIZE
77 bdnz .L_sync_data_loop
82 /* loop to invalidate the instruction cache */
85 addic r4, r4, CACHE_LINE_SIZE
86 bdnz .L_sync_inval_loop
89 sync /* Finish physical writes */
90 mtmsr r6 /* Restore original translations */
91 isync /* Ensure data translations are on */
101 * extern void flush_dcache(vm_offset_t addr, unsigned count, boolean phys);
103 * flush_dcache takes a virtual or physical address and count to flush
104 * and (can be called for multiple virtual pages).
106 * it flushes the data cache
107 * cache for the address range in question
109 * if 'phys' is non-zero then physical addresses will be used
112 ENTRY(flush_dcache, TAG_NO_FRAME_USED)
114 /* optionally switch off data translations */
119 rlwinm r6,r6,0,MSR_FP_BIT+1,MSR_FP_BIT-1 ; Force floating point off
120 rlwinm r6,r6,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1 ; Force vectors off
121 rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
126 /* Check to see if the address is aligned. */
128 andi. r8,r8,(CACHE_LINE_SIZE-1)
129 beq- .L_flush_dcache_check
130 addi r4,r4,CACHE_LINE_SIZE
131 li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
135 .L_flush_dcache_check:
136 cmpwi r4, CACHE_LINE_SIZE
137 ble .L_flush_dcache_one_line
139 /* Make ctr hold count of how many times we should loop */
140 addi r8, r4, (CACHE_LINE_SIZE-1)
141 srwi r8, r8, CACHE_LINE_POW2
144 .L_flush_dcache_flush_loop:
145 subic r4, r4, CACHE_LINE_SIZE
147 bdnz .L_flush_dcache_flush_loop
149 .L_flush_dcache_done:
150 /* Sync restore msr if it was modified */
152 sync /* make sure invalidates have completed */
154 mtmsr r6 /* Restore original translations */
155 isync /* Ensure data translations are on */
159 .L_flush_dcache_one_line:
162 b .L_flush_dcache_done
166 * extern void invalidate_dcache(vm_offset_t va, unsigned count, boolean phys);
168 * invalidate_dcache takes a virtual or physical address and count to
169 * invalidate and (can be called for multiple virtual pages).
171 * it invalidates the data cache for the address range in question
174 ENTRY(invalidate_dcache, TAG_NO_FRAME_USED)
176 /* optionally switch off data translations */
181 rlwinm r6,r6,0,MSR_FP_BIT+1,MSR_FP_BIT-1 ; Force floating point off
182 rlwinm r6,r6,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1 ; Force vectors off
183 rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
188 /* Check to see if the address is aligned. */
190 andi. r8,r8,(CACHE_LINE_SIZE-1)
191 beq- .L_invalidate_dcache_check
192 addi r4,r4,CACHE_LINE_SIZE
193 li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
197 .L_invalidate_dcache_check:
198 cmpwi r4, CACHE_LINE_SIZE
199 ble .L_invalidate_dcache_one_line
201 /* Make ctr hold count of how many times we should loop */
202 addi r8, r4, (CACHE_LINE_SIZE-1)
203 srwi r8, r8, CACHE_LINE_POW2
206 .L_invalidate_dcache_invalidate_loop:
207 subic r4, r4, CACHE_LINE_SIZE
209 bdnz .L_invalidate_dcache_invalidate_loop
211 .L_invalidate_dcache_done:
212 /* Sync restore msr if it was modified */
214 sync /* make sure invalidates have completed */
216 mtmsr r6 /* Restore original translations */
217 isync /* Ensure data translations are on */
221 .L_invalidate_dcache_one_line:
224 b .L_invalidate_dcache_done
227 * extern void invalidate_icache(vm_offset_t addr, unsigned cnt, boolean phys);
229 * invalidate_icache takes a virtual or physical address and
230 * count to invalidate, (can be called for multiple virtual pages).
232 * it invalidates the instruction cache for the address range in question.
235 ENTRY(invalidate_icache, TAG_NO_FRAME_USED)
237 /* optionally switch off data translations */
241 rlwinm r6,r6,0,MSR_FP_BIT+1,MSR_FP_BIT-1 ; Force floating point off
242 rlwinm r6,r6,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1 ; Force vectors off
243 rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
248 /* Check to see if the address is aligned. */
250 andi. r8,r8,(CACHE_LINE_SIZE-1)
251 beq- .L_invalidate_icache_check
252 addi r4,r4,CACHE_LINE_SIZE
253 li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
257 .L_invalidate_icache_check:
258 cmpwi r4, CACHE_LINE_SIZE
259 ble .L_invalidate_icache_one_line
261 /* Make ctr hold count of how many times we should loop */
262 addi r8, r4, (CACHE_LINE_SIZE-1)
263 srwi r8, r8, CACHE_LINE_POW2
266 .L_invalidate_icache_invalidate_loop:
267 subic r4, r4, CACHE_LINE_SIZE
269 bdnz .L_invalidate_icache_invalidate_loop
271 .L_invalidate_icache_done:
272 sync /* make sure invalidates have completed */
273 mtmsr r6 /* Restore original translations */
274 isync /* Ensure data translations are on */
277 .L_invalidate_icache_one_line:
280 b .L_invalidate_icache_done