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

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

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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.9 ] ~ [ 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-fa.S
  4  *
  5  *  Copyright (C) 2005 Faraday Corp.
  6  *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
  7  *
  8  * Based on cache-v4wb.S:
  9  *  Copyright (C) 1997-2002 Russell king
 10  *
 11  *  Processors: FA520 FA526 FA626       
 12  */
 13 #include <linux/linkage.h>
 14 #include <linux/init.h>
 15 #include <linux/cfi_types.h>
 16 #include <asm/assembler.h>
 17 #include <asm/page.h>
 18 
 19 #include "proc-macros.S"
 20 
 21 /*
 22  * The size of one data cache line.
 23  */
 24 #define CACHE_DLINESIZE 16
 25 
 26 /*
 27  * The total size of the data cache.
 28  */
 29 #ifdef CONFIG_ARCH_GEMINI
 30 #define CACHE_DSIZE     8192
 31 #else
 32 #define CACHE_DSIZE     16384 
 33 #endif 
 34 
 35 /* FIXME: put optimal value here. Current one is just estimation */
 36 #define CACHE_DLIMIT    (CACHE_DSIZE * 2)
 37 
 38 /*
 39  *      flush_icache_all()
 40  *
 41  *      Unconditionally clean and invalidate the entire icache.
 42  */
 43 SYM_TYPED_FUNC_START(fa_flush_icache_all)
 44         mov     r0, #0
 45         mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
 46         ret     lr
 47 SYM_FUNC_END(fa_flush_icache_all)
 48 
 49 /*
 50  *      flush_user_cache_all()
 51  *
 52  *      Clean and invalidate all cache entries in a particular address
 53  *      space.
 54  */
 55 SYM_FUNC_ALIAS(fa_flush_user_cache_all, fa_flush_kern_cache_all)
 56 
 57 /*
 58  *      flush_kern_cache_all()
 59  *
 60  *      Clean and invalidate the entire cache.
 61  */
 62 SYM_TYPED_FUNC_START(fa_flush_kern_cache_all)
 63         mov     ip, #0
 64         mov     r2, #VM_EXEC
 65 __flush_whole_cache:
 66         mcr     p15, 0, ip, c7, c14, 0          @ clean/invalidate D cache
 67         tst     r2, #VM_EXEC
 68         mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
 69         mcrne   p15, 0, ip, c7, c5, 6           @ invalidate BTB
 70         mcrne   p15, 0, ip, c7, c10, 4          @ drain write buffer
 71         mcrne   p15, 0, ip, c7, c5, 4           @ prefetch flush
 72         ret     lr
 73 SYM_FUNC_END(fa_flush_kern_cache_all)
 74 
 75 /*
 76  *      flush_user_cache_range(start, end, flags)
 77  *
 78  *      Invalidate a range of cache entries in the specified
 79  *      address space.
 80  *
 81  *      - start - start address (inclusive, page aligned)
 82  *      - end   - end address (exclusive, page aligned)
 83  *      - flags - vma_area_struct flags describing address space
 84  */
 85 SYM_TYPED_FUNC_START(fa_flush_user_cache_range)
 86         mov     ip, #0
 87         sub     r3, r1, r0                      @ calculate total size
 88         cmp     r3, #CACHE_DLIMIT               @ total size >= limit?
 89         bhs     __flush_whole_cache             @ flush whole D cache
 90 
 91 1:      tst     r2, #VM_EXEC
 92         mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I line
 93         mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
 94         add     r0, r0, #CACHE_DLINESIZE
 95         cmp     r0, r1
 96         blo     1b
 97         tst     r2, #VM_EXEC
 98         mcrne   p15, 0, ip, c7, c5, 6           @ invalidate BTB
 99         mcrne   p15, 0, ip, c7, c10, 4          @ data write barrier
100         mcrne   p15, 0, ip, c7, c5, 4           @ prefetch flush
101         ret     lr
102 SYM_FUNC_END(fa_flush_user_cache_range)
103 
104 /*
105  *      coherent_kern_range(start, end)
106  *
107  *      Ensure coherency between the Icache and the Dcache in the
108  *      region described by start.  If you have non-snooping
109  *      Harvard caches, you need to implement this function.
110  *
111  *      - start  - virtual start address
112  *      - end    - virtual end address
113  */
114 SYM_TYPED_FUNC_START(fa_coherent_kern_range)
115 #ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
116         b       fa_coherent_user_range
117 #endif
118 SYM_FUNC_END(fa_coherent_kern_range)
119 
120 /*
121  *      coherent_user_range(start, end)
122  *
123  *      Ensure coherency between the Icache and the Dcache in the
124  *      region described by start.  If you have non-snooping
125  *      Harvard caches, you need to implement this function.
126  *
127  *      - start  - virtual start address
128  *      - end    - virtual end address
129  */
130 SYM_TYPED_FUNC_START(fa_coherent_user_range)
131         bic     r0, r0, #CACHE_DLINESIZE - 1
132 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
133         mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
134         add     r0, r0, #CACHE_DLINESIZE
135         cmp     r0, r1
136         blo     1b
137         mov     r0, #0
138         mcr     p15, 0, r0, c7, c5, 6           @ invalidate BTB
139         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
140         mcr     p15, 0, r0, c7, c5, 4           @ prefetch flush
141         ret     lr
142 SYM_FUNC_END(fa_coherent_user_range)
143 
144 /*
145  *      flush_kern_dcache_area(void *addr, size_t size)
146  *
147  *      Ensure that the data held in the page kaddr is written back
148  *      to the page in question.
149  *
150  *      - addr  - kernel address
151  *      - size  - size of region
152  */
153 SYM_TYPED_FUNC_START(fa_flush_kern_dcache_area)
154         add     r1, r0, r1
155 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
156         add     r0, r0, #CACHE_DLINESIZE
157         cmp     r0, r1
158         blo     1b
159         mov     r0, #0
160         mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
161         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
162         ret     lr
163 SYM_FUNC_END(fa_flush_kern_dcache_area)
164 
165 /*
166  *      dma_inv_range(start, end)
167  *
168  *      Invalidate (discard) the specified virtual address range.
169  *      May not write back any entries.  If 'start' or 'end'
170  *      are not cache line aligned, those lines must be written
171  *      back.
172  *
173  *      - start  - virtual start address
174  *      - end    - virtual end address
175  */
176 fa_dma_inv_range:
177         tst     r0, #CACHE_DLINESIZE - 1
178         bic     r0, r0, #CACHE_DLINESIZE - 1
179         mcrne   p15, 0, r0, c7, c14, 1          @ clean & invalidate D entry
180         tst     r1, #CACHE_DLINESIZE - 1
181         bic     r1, r1, #CACHE_DLINESIZE - 1
182         mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D entry
183 1:      mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
184         add     r0, r0, #CACHE_DLINESIZE
185         cmp     r0, r1
186         blo     1b
187         mov     r0, #0
188         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
189         ret     lr
190 
191 /*
192  *      dma_clean_range(start, end)
193  *
194  *      Clean (write back) the specified virtual address range.
195  *
196  *      - start  - virtual start address
197  *      - end    - virtual end address
198  */
199 fa_dma_clean_range:
200         bic     r0, r0, #CACHE_DLINESIZE - 1
201 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
202         add     r0, r0, #CACHE_DLINESIZE
203         cmp     r0, r1
204         blo     1b
205         mov     r0, #0  
206         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
207         ret     lr
208 
209 /*
210  *      dma_flush_range(start,end)
211  *      - start   - virtual start address of region
212  *      - end     - virtual end address of region
213  */
214 SYM_TYPED_FUNC_START(fa_dma_flush_range)
215         bic     r0, r0, #CACHE_DLINESIZE - 1
216 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D entry
217         add     r0, r0, #CACHE_DLINESIZE
218         cmp     r0, r1
219         blo     1b
220         mov     r0, #0  
221         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
222         ret     lr
223 SYM_FUNC_END(fa_dma_flush_range)
224 
225 /*
226  *      dma_map_area(start, size, dir)
227  *      - start - kernel virtual start address
228  *      - size  - size of region
229  *      - dir   - DMA direction
230  */
231 SYM_TYPED_FUNC_START(fa_dma_map_area)
232         add     r1, r1, r0
233         cmp     r2, #DMA_TO_DEVICE
234         beq     fa_dma_clean_range
235         bcs     fa_dma_inv_range
236         b       fa_dma_flush_range
237 SYM_FUNC_END(fa_dma_map_area)
238 
239 /*
240  *      dma_unmap_area(start, size, dir)
241  *      - start - kernel virtual start address
242  *      - size  - size of region
243  *      - dir   - DMA direction
244  */
245 SYM_TYPED_FUNC_START(fa_dma_unmap_area)
246         ret     lr
247 SYM_FUNC_END(fa_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