~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/mm/cache-v6.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  *  linux/arch/arm/mm/cache-v6.S
  4  *
  5  *  Copyright (C) 2001 Deep Blue Solutions Ltd.
  6  *
  7  *  This is the "shell" of the ARMv6 processor support.
  8  */
  9 #include <linux/linkage.h>
 10 #include <linux/init.h>
 11 #include <linux/cfi_types.h>
 12 #include <asm/assembler.h>
 13 #include <asm/errno.h>
 14 #include <asm/unwind.h>
 15 
 16 #include "proc-macros.S"
 17 
 18 #define HARVARD_CACHE
 19 #define CACHE_LINE_SIZE         32
 20 #define D_CACHE_LINE_SIZE       32
 21 #define BTB_FLUSH_SIZE          8
 22 
 23 .arch armv6
 24 
 25 /*
 26  *      v6_flush_icache_all()
 27  *
 28  *      Flush the whole I-cache.
 29  *
 30  *      ARM1136 erratum 411920 - Invalidate Instruction Cache operation can fail.
 31  *      This erratum is present in 1136, 1156 and 1176. It does not affect the
 32  *      MPCore.
 33  *
 34  *      Registers:
 35  *      r0 - set to 0
 36  *      r1 - corrupted
 37  */
 38 SYM_TYPED_FUNC_START(v6_flush_icache_all)
 39         mov     r0, #0
 40 #ifdef CONFIG_ARM_ERRATA_411920
 41         mrs     r1, cpsr
 42         cpsid   ifa                             @ disable interrupts
 43         mcr     p15, 0, r0, c7, c5, 0           @ invalidate entire I-cache
 44         mcr     p15, 0, r0, c7, c5, 0           @ invalidate entire I-cache
 45         mcr     p15, 0, r0, c7, c5, 0           @ invalidate entire I-cache
 46         mcr     p15, 0, r0, c7, c5, 0           @ invalidate entire I-cache
 47         msr     cpsr_cx, r1                     @ restore interrupts
 48         .rept   11                              @ ARM Ltd recommends at least
 49         nop                                     @ 11 NOPs
 50         .endr
 51 #else
 52         mcr     p15, 0, r0, c7, c5, 0           @ invalidate I-cache
 53 #endif
 54         ret     lr
 55 SYM_FUNC_END(v6_flush_icache_all)
 56 
 57 /*
 58  *      v6_flush_cache_all()
 59  *
 60  *      Flush the entire cache.
 61  *
 62  *      It is assumed that:
 63  */
 64 SYM_TYPED_FUNC_START(v6_flush_kern_cache_all)
 65         mov     r0, #0
 66 #ifdef HARVARD_CACHE
 67         mcr     p15, 0, r0, c7, c14, 0          @ D cache clean+invalidate
 68 #ifndef CONFIG_ARM_ERRATA_411920
 69         mcr     p15, 0, r0, c7, c5, 0           @ I+BTB cache invalidate
 70 #else
 71         b       v6_flush_icache_all
 72 #endif
 73 #else
 74         mcr     p15, 0, r0, c7, c15, 0          @ Cache clean+invalidate
 75 #endif
 76         ret     lr
 77 SYM_FUNC_END(v6_flush_kern_cache_all)
 78 
 79 /*
 80  *      v6_flush_cache_all()
 81  *
 82  *      Flush all TLB entries in a particular address space
 83  *
 84  *      - mm    - mm_struct describing address space
 85  */
 86 SYM_TYPED_FUNC_START(v6_flush_user_cache_all)
 87         ret     lr
 88 SYM_FUNC_END(v6_flush_user_cache_all)
 89 
 90 /*
 91  *      v6_flush_cache_range(start, end, flags)
 92  *
 93  *      Flush a range of TLB entries in the specified address space.
 94  *
 95  *      - start - start address (may not be aligned)
 96  *      - end   - end address (exclusive, may not be aligned)
 97  *      - flags - vm_area_struct flags describing address space
 98  *
 99  *      It is assumed that:
100  *      - we have a VIPT cache.
101  */
102 SYM_TYPED_FUNC_START(v6_flush_user_cache_range)
103         ret     lr
104 SYM_FUNC_END(v6_flush_user_cache_range)
105 
106 /*
107  *      v6_coherent_kern_range(start,end)
108  *
109  *      Ensure that the I and D caches are coherent within specified
110  *      region.  This is typically used when code has been written to
111  *      a memory region, and will be executed.
112  *
113  *      - start   - virtual start address of region
114  *      - end     - virtual end address of region
115  *
116  *      It is assumed that:
117  *      - the Icache does not read data from the write buffer
118  */
119 SYM_TYPED_FUNC_START(v6_coherent_kern_range)
120 #ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
121         b       v6_coherent_user_range
122 #endif
123 SYM_FUNC_END(v6_coherent_kern_range)
124 
125 /*
126  *      v6_coherent_user_range(start,end)
127  *
128  *      Ensure that the I and D caches are coherent within specified
129  *      region.  This is typically used when code has been written to
130  *      a memory region, and will be executed.
131  *
132  *      - start   - virtual start address of region
133  *      - end     - virtual end address of region
134  *
135  *      It is assumed that:
136  *      - the Icache does not read data from the write buffer
137  */
138 SYM_TYPED_FUNC_START(v6_coherent_user_range)
139  UNWIND(.fnstart                )
140 #ifdef HARVARD_CACHE
141         bic     r0, r0, #CACHE_LINE_SIZE - 1
142 1:
143  USER(  mcr     p15, 0, r0, c7, c10, 1  )       @ clean D line
144         add     r0, r0, #CACHE_LINE_SIZE
145         cmp     r0, r1
146         blo     1b
147 #endif
148         mov     r0, #0
149 #ifdef HARVARD_CACHE
150         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
151 #ifndef CONFIG_ARM_ERRATA_411920
152         mcr     p15, 0, r0, c7, c5, 0           @ I+BTB cache invalidate
153 #else
154         b       v6_flush_icache_all
155 #endif
156 #else
157         mcr     p15, 0, r0, c7, c5, 6           @ invalidate BTB
158 #endif
159         ret     lr
160 
161 /*
162  * Fault handling for the cache operation above. If the virtual address in r0
163  * isn't mapped, fail with -EFAULT.
164  */
165 9001:
166         mov     r0, #-EFAULT
167         ret     lr
168  UNWIND(.fnend          )
169 SYM_FUNC_END(v6_coherent_user_range)
170 
171 /*
172  *      v6_flush_kern_dcache_area(void *addr, size_t size)
173  *
174  *      Ensure that the data held in the page kaddr is written back
175  *      to the page in question.
176  *
177  *      - addr  - kernel address
178  *      - size  - region size
179  */
180 SYM_TYPED_FUNC_START(v6_flush_kern_dcache_area)
181         add     r1, r0, r1
182         bic     r0, r0, #D_CACHE_LINE_SIZE - 1
183 1:
184 #ifdef HARVARD_CACHE
185         mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
186 #else
187         mcr     p15, 0, r0, c7, c15, 1          @ clean & invalidate unified line
188 #endif  
189         add     r0, r0, #D_CACHE_LINE_SIZE
190         cmp     r0, r1
191         blo     1b
192 #ifdef HARVARD_CACHE
193         mov     r0, #0
194         mcr     p15, 0, r0, c7, c10, 4
195 #endif
196         ret     lr
197 SYM_FUNC_END(v6_flush_kern_dcache_area)
198 
199 /*
200  *      v6_dma_inv_range(start,end)
201  *
202  *      Invalidate the data cache within the specified region; we will
203  *      be performing a DMA operation in this region and we want to
204  *      purge old data in the cache.
205  *
206  *      - start   - virtual start address of region
207  *      - end     - virtual end address of region
208  */
209 v6_dma_inv_range:
210         tst     r0, #D_CACHE_LINE_SIZE - 1
211         bic     r0, r0, #D_CACHE_LINE_SIZE - 1
212 #ifdef HARVARD_CACHE
213         mcrne   p15, 0, r0, c7, c10, 1          @ clean D line
214 #else
215         mcrne   p15, 0, r0, c7, c11, 1          @ clean unified line
216 #endif
217         tst     r1, #D_CACHE_LINE_SIZE - 1
218         bic     r1, r1, #D_CACHE_LINE_SIZE - 1
219 #ifdef HARVARD_CACHE
220         mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D line
221 #else
222         mcrne   p15, 0, r1, c7, c15, 1          @ clean & invalidate unified line
223 #endif
224 1:
225 #ifdef HARVARD_CACHE
226         mcr     p15, 0, r0, c7, c6, 1           @ invalidate D line
227 #else
228         mcr     p15, 0, r0, c7, c7, 1           @ invalidate unified line
229 #endif
230         add     r0, r0, #D_CACHE_LINE_SIZE
231         cmp     r0, r1
232         blo     1b
233         mov     r0, #0
234         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
235         ret     lr
236 
237 /*
238  *      v6_dma_clean_range(start,end)
239  *      - start   - virtual start address of region
240  *      - end     - virtual end address of region
241  */
242 v6_dma_clean_range:
243         bic     r0, r0, #D_CACHE_LINE_SIZE - 1
244 1:
245 #ifdef HARVARD_CACHE
246         mcr     p15, 0, r0, c7, c10, 1          @ clean D line
247 #else
248         mcr     p15, 0, r0, c7, c11, 1          @ clean unified line
249 #endif
250         add     r0, r0, #D_CACHE_LINE_SIZE
251         cmp     r0, r1
252         blo     1b
253         mov     r0, #0
254         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
255         ret     lr
256 
257 /*
258  *      v6_dma_flush_range(start,end)
259  *      - start   - virtual start address of region
260  *      - end     - virtual end address of region
261  */
262 SYM_TYPED_FUNC_START(v6_dma_flush_range)
263         bic     r0, r0, #D_CACHE_LINE_SIZE - 1
264 1:
265 #ifdef HARVARD_CACHE
266         mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
267 #else
268         mcr     p15, 0, r0, c7, c15, 1          @ clean & invalidate line
269 #endif
270         add     r0, r0, #D_CACHE_LINE_SIZE
271         cmp     r0, r1
272         blo     1b
273         mov     r0, #0
274         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
275         ret     lr
276 SYM_FUNC_END(v6_dma_flush_range)
277 
278 /*
279  *      dma_map_area(start, size, dir)
280  *      - start - kernel virtual start address
281  *      - size  - size of region
282  *      - dir   - DMA direction
283  */
284 SYM_TYPED_FUNC_START(v6_dma_map_area)
285         add     r1, r1, r0
286         teq     r2, #DMA_FROM_DEVICE
287         beq     v6_dma_inv_range
288         b       v6_dma_clean_range
289 SYM_FUNC_END(v6_dma_map_area)
290 
291 /*
292  *      dma_unmap_area(start, size, dir)
293  *      - start - kernel virtual start address
294  *      - size  - size of region
295  *      - dir   - DMA direction
296  */
297 SYM_TYPED_FUNC_START(v6_dma_unmap_area)
298         add     r1, r1, r0
299         teq     r2, #DMA_TO_DEVICE
300         bne     v6_dma_inv_range
301         ret     lr
302 SYM_FUNC_END(v6_dma_unmap_area)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php