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