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 r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
53 /* Check to see if the address is aligned. */
55 andi. r8,r8,(CACHE_LINE_SIZE-1)
57 addi r4,r4,CACHE_LINE_SIZE
58 li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
63 cmpwi r4, CACHE_LINE_SIZE
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
71 /* loop to flush the data cache */
73 subic r4, r4, CACHE_LINE_SIZE
75 bdnz .L_sync_data_loop
80 /* loop to invalidate the instruction cache */
83 addic r4, r4, CACHE_LINE_SIZE
84 bdnz .L_sync_inval_loop
87 sync /* Finish physical writes */
88 mtmsr r6 /* Restore original translations */
89 isync /* Ensure data translations are on */
99 * extern void flush_dcache(vm_offset_t addr, unsigned count, boolean phys);
101 * flush_dcache takes a virtual or physical address and count to flush
102 * and (can be called for multiple virtual pages).
104 * it flushes the data cache
105 * cache for the address range in question
107 * if 'phys' is non-zero then physical addresses will be used
110 ENTRY(flush_dcache, TAG_NO_FRAME_USED)
112 /* optionally switch off data translations */
117 rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
122 /* Check to see if the address is aligned. */
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 */
131 .L_flush_dcache_check:
132 cmpwi r4, CACHE_LINE_SIZE
133 ble .L_flush_dcache_one_line
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
140 .L_flush_dcache_flush_loop:
141 subic r4, r4, CACHE_LINE_SIZE
143 bdnz .L_flush_dcache_flush_loop
145 .L_flush_dcache_done:
146 /* Sync restore msr if it was modified */
148 sync /* make sure invalidates have completed */
150 mtmsr r6 /* Restore original translations */
151 isync /* Ensure data translations are on */
155 .L_flush_dcache_one_line:
158 b .L_flush_dcache_done
162 * extern void invalidate_dcache(vm_offset_t va, unsigned count, boolean phys);
164 * invalidate_dcache takes a virtual or physical address and count to
165 * invalidate and (can be called for multiple virtual pages).
167 * it invalidates the data cache for the address range in question
170 ENTRY(invalidate_dcache, TAG_NO_FRAME_USED)
172 /* optionally switch off data translations */
177 rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
182 /* Check to see if the address is aligned. */
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 */
191 .L_invalidate_dcache_check:
192 cmpwi r4, CACHE_LINE_SIZE
193 ble .L_invalidate_dcache_one_line
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
200 .L_invalidate_dcache_invalidate_loop:
201 subic r4, r4, CACHE_LINE_SIZE
203 bdnz .L_invalidate_dcache_invalidate_loop
205 .L_invalidate_dcache_done:
206 /* Sync restore msr if it was modified */
208 sync /* make sure invalidates have completed */
210 mtmsr r6 /* Restore original translations */
211 isync /* Ensure data translations are on */
215 .L_invalidate_dcache_one_line:
218 b .L_invalidate_dcache_done
221 * extern void invalidate_icache(vm_offset_t addr, unsigned cnt, boolean phys);
223 * invalidate_icache takes a virtual or physical address and
224 * count to invalidate, (can be called for multiple virtual pages).
226 * it invalidates the instruction cache for the address range in question.
229 ENTRY(invalidate_icache, TAG_NO_FRAME_USED)
231 /* optionally switch off data translations */
235 rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
240 /* Check to see if the address is aligned. */
242 andi. r8,r8,(CACHE_LINE_SIZE-1)
243 beq- .L_invalidate_icache_check
244 addi r4,r4,CACHE_LINE_SIZE
245 li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
249 .L_invalidate_icache_check:
250 cmpwi r4, CACHE_LINE_SIZE
251 ble .L_invalidate_icache_one_line
253 /* Make ctr hold count of how many times we should loop */
254 addi r8, r4, (CACHE_LINE_SIZE-1)
255 srwi r8, r8, CACHE_LINE_POW2
258 .L_invalidate_icache_invalidate_loop:
259 subic r4, r4, CACHE_LINE_SIZE
261 bdnz .L_invalidate_icache_invalidate_loop
263 .L_invalidate_icache_done:
264 sync /* make sure invalidates have completed */
265 mtmsr r6 /* Restore original translations */
266 isync /* Ensure data translations are on */
269 .L_invalidate_icache_one_line:
272 b .L_invalidate_icache_done