2 * Copyright (c) 2010 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <machine/asm.h>
30 #include <arm/proc_reg.h>
32 #include <sys/errno.h>
34 #include "caches_macros.s"
38 * void invalidate_mmu_cache(void)
40 * Invalidate d-cache and i-cache
44 .globl EXT(invalidate_mmu_cache)
45 LEXT(invalidate_mmu_cache)
48 mcr p15, 0, r0, c7, c7, 0 // Invalidate caches
54 * void invalidate_mmu_dcache(void)
60 .globl EXT(invalidate_mmu_dcache)
61 LEXT(invalidate_mmu_dcache)
64 mcr p15, 0, r0, c7, c6, 0 // Invalidate dcache
69 * void invalidate_mmu_dcache_region(vm_offset_t va, unsigned length)
71 * Invalidate d-cache region
75 .globl EXT(invalidate_mmu_dcache_region)
76 LEXT(invalidate_mmu_dcache_region)
77 and r2, r0, #((1<<MMU_CLINE)-1)
78 bic r0, r0, #((1<<MMU_CLINE)-1) // Cached aligned
81 mov r1, r1, LSR #MMU_CLINE // Set cache line counter
84 mcr p15, 0, r0, c7, c14, 1 // Invalidate dcache line
85 add r0, r0, #1<<MMU_CLINE // Get next cache aligned addr
86 subs r1, r1, #1 // Decrementer cache line counter
87 bpl fmdr_loop // Loop in counter not null
92 * void InvalidatePoU_Icache(void)
98 .globl EXT(InvalidatePoU_Icache)
99 .globl EXT(invalidate_mmu_icache)
100 LEXT(InvalidatePoU_Icache)
101 LEXT(invalidate_mmu_icache)
104 mcr p15, 0, r0, c7, c5, 0 // Invalidate icache
110 * void InvalidatePoU_IcacheRegion(vm_offset_t va, unsigned length)
112 * Invalidate icache region
116 .globl EXT(InvalidatePoU_IcacheRegion)
117 LEXT(InvalidatePoU_IcacheRegion)
120 bl EXT(CleanPoU_DcacheRegion)
121 and r2, r0, #((1<<MMU_I_CLINE)-1)
122 bic r0, r0, #((1<<MMU_I_CLINE)-1) // Cached aligned
125 mov r1, r1, LSR #MMU_I_CLINE // Set cache line counter
127 mcr p15, 0, r0, c7, c5, 1 // Invalidate icache line
128 add r0, r0, #1<<MMU_I_CLINE // Get next cache aligned addr
129 subs r1, r1, #1 // Decrementer cache line counter
130 bpl fmir_loop // Loop in counter not null
136 * void CleanPoC_Dcache(void)
142 .globl EXT(CleanPoC_Dcache)
143 .globl EXT(clean_mmu_dcache)
144 LEXT(CleanPoC_Dcache)
145 LEXT(clean_mmu_dcache)
146 #if !defined(__ARM_L1_WT_CACHE__)
148 GET_CACHE_CONFIG r0, r1, r2, r3
153 mcr p15, 0, r0, c7, c10, 2 // clean dcache line by way/set
154 add r0, r0, r1 // increment set index
155 tst r0, r2 // look for overflow
157 bic r0, r0, r2 // clear set overflow
158 adds r0, r0, r3 // increment way
159 bcc clean_dcacheway // loop
163 beq clean_skipl2dcache
165 GET_CACHE_CONFIG r0, r1, r2, r3
170 mcr p15, 0, r0, c7, c10, 2 // clean dcache line by way/set
171 add r0, r0, r1 // increment set index
172 tst r0, r2 // look for overflow
173 beq clean_l2dcacheline
174 bic r0, r0, r2 // clear set overflow
175 adds r0, r0, r3 // increment way
176 bcc clean_l2dcacheway // loop
182 * void CleanPoU_Dcache(void)
184 * Clean D-cache to Point of Unification
188 .globl EXT(CleanPoU_Dcache)
189 LEXT(CleanPoU_Dcache)
190 #if !defined(__ARM_PoU_WT_CACHE__)
192 GET_CACHE_CONFIG r0, r1, r2, r3
195 clean_dcacheway_idle:
196 clean_dcacheline_idle:
197 mcr p15, 0, r0, c7, c10, 2 // clean dcache line by way/set
198 add r0, r0, r1 // increment set index
199 tst r0, r2 // look for overflow
200 beq clean_dcacheline_idle
201 bic r0, r0, r2 // clear set overflow
202 adds r0, r0, r3 // increment way
203 bcc clean_dcacheway_idle // loop
209 * void CleanPoU_DcacheRegion(vm_offset_t va, unsigned length)
211 * Clean d-cache region to Point of Unification
215 .globl EXT(CleanPoU_DcacheRegion)
216 LEXT(CleanPoU_DcacheRegion)
217 #if !defined(__ARM_PoU_WT_CACHE__)
219 and r2, r0, #((1<<MMU_CLINE)-1)
220 bic r3, r0, #((1<<MMU_CLINE)-1) // Cached aligned
223 mov r12, r12, LSR #MMU_CLINE // Set cache line counter
226 mcr p15, 0, r3, c7, c11, 1 // Clean dcache line to PoU
227 add r3, r3, #1<<MMU_CLINE // Get next cache aligned addr
228 subs r12, r12, #1 // Decrementer cache line counter
229 bpl cudr_loop // Loop in counter not null
236 * void CleanPoC_DcacheRegion(vm_offset_t va, size_t length)
238 * Clean d-cache region to Point of Coherency
242 .globl EXT(CleanPoC_DcacheRegion)
243 .globl EXT(CleanPoC_DcacheRegion_Force)
244 LEXT(CleanPoC_DcacheRegion)
245 LEXT(CleanPoC_DcacheRegion_Force)
246 and r2, r0, #((1<<MMU_CLINE)-1)
247 bic r0, r0, #((1<<MMU_CLINE)-1) // Cached aligned
250 mov r1, r1, LSR #MMU_CLINE // Set cache line counter
252 mcr p15, 0, r0, c7, c10, 1 // Clean dcache line to PoC
253 add r0, r0, #1<<MMU_CLINE // Get next cache aligned addr
254 subs r1, r1, #1 // Decrementer cache line counter
255 bpl ccdr_loop // Loop in counter not null
260 * void FlushPoC_Dcache(void)
262 * Clean and Invalidate dcaches to Point of Coherency
266 .globl EXT(FlushPoC_Dcache)
267 LEXT(FlushPoC_Dcache)
269 GET_CACHE_CONFIG r0, r1, r2, r3
272 cleanflush_dcacheway:
273 cleanflush_dcacheline:
274 mcr p15, 0, r0, c7, c14, 2 // cleanflush dcache line by way/set
275 add r0, r0, r1 // increment set index
276 tst r0, r2 // look for overflow
277 beq cleanflush_dcacheline
278 bic r0, r0, r2 // clear set overflow
279 adds r0, r0, r3 // increment way
280 bcc cleanflush_dcacheway // loop
283 beq cleanflush_skipl2dcache
285 GET_CACHE_CONFIG r0, r1, r2, r3
288 cleanflush_l2dcacheway:
289 cleanflush_l2dcacheline:
290 mcr p15, 0, r0, c7, c14, 2 // cleanflush dcache line by way/set
291 add r0, r0, r1 // increment set index
292 tst r0, r2 // look for overflow
293 beq cleanflush_l2dcacheline
294 bic r0, r0, r2 // clear set overflow
295 adds r0, r0, r3 // increment way
296 bcc cleanflush_l2dcacheway // loop
297 cleanflush_skipl2dcache:
302 * void FlushPoU_Dcache(void)
304 * Flush D-cache to Point of Unification
308 .globl EXT(FlushPoU_Dcache)
309 LEXT(FlushPoU_Dcache)
311 GET_CACHE_CONFIG r0, r1, r2, r3
316 mcr p15, 0, r0, c7, c14, 2 // cleanflush dcache line by way/set
317 add r0, r0, r1 // increment set index
318 tst r0, r2 // look for overflow
320 bic r0, r0, r2 // clear set overflow
321 adds r0, r0, r3 // increment way
327 * void FlushPoC_DcacheRegion(vm_offset_t va, unsigned length)
329 * Clean and Invalidate d-cache region to Point of Coherency
333 .globl EXT(FlushPoC_DcacheRegion)
334 LEXT(FlushPoC_DcacheRegion)
335 and r2, r0, #((1<<MMU_CLINE)-1)
336 bic r0, r0, #((1<<MMU_CLINE)-1) // Cached aligned
339 mov r1, r1, LSR #MMU_CLINE // Set cache line counter
342 mcr p15, 0, r0, c7, c14, 1 // Clean & invalidate dcache line
343 add r0, r0, #1<<MMU_CLINE // Get next cache aligned addr
344 subs r1, r1, #1 // Decrementer cache line counter
345 bpl cfmdr_loop // Loop in counter not null
350 * void flush_dcache64(addr64_t addr, unsigned length, boolean_t phys)
354 .globl EXT(flush_dcache64)
358 LOAD_ADDR_PC(flush_dcache)
361 * void clean_dcache64(addr64_t addr, unsigned length, boolean_t phys)
365 .globl EXT(clean_dcache64)
369 LOAD_ADDR_PC(clean_dcache)
372 * void invalidate_icache(vm_offset_t va, unsigned length, boolean_t phys)
373 * void invalidate_icache64(addr64_t va, unsigned length, boolean_t phys)
377 .globl EXT(invalidate_icache64)
378 .globl EXT(invalidate_icache)
379 LEXT(invalidate_icache64)
382 LEXT(invalidate_icache)
383 cmp r2, #0 // Is it physical?
384 COND_EXTERN_BEQ(InvalidatePoU_IcacheRegion)
385 LOAD_ADDR(r2, gPhysBase)
388 LOAD_ADDR(r2, gVirtBase)
391 b EXT(InvalidatePoU_IcacheRegion)
394 #include "globals_asm.h"
396 LOAD_ADDR_GEN_DEF(flush_dcache)
397 LOAD_ADDR_GEN_DEF(clean_dcache)