1
2
3
4
5
6
7
8
9
10#ifndef _ASMARM_CACHEFLUSH_H
11#define _ASMARM_CACHEFLUSH_H
12
13#include <linux/config.h>
14#include <linux/sched.h>
15#include <linux/mm.h>
16
17#include <asm/mman.h>
18#include <asm/glue.h>
19
20
21
22
23
24#undef _CACHE
25#undef MULTI_CACHE
26
27#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
28# ifdef _CACHE
29# define MULTI_CACHE 1
30# else
31# define _CACHE v3
32# endif
33#endif
34
35#if defined(CONFIG_CPU_ARM720T)
36# ifdef _CACHE
37# define MULTI_CACHE 1
38# else
39# define _CACHE v4
40# endif
41#endif
42
43#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
44 defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020)
45# define MULTI_CACHE 1
46#endif
47
48#if defined(CONFIG_CPU_ARM926T)
49# ifdef _CACHE
50# define MULTI_CACHE 1
51# else
52# define _CACHE arm926
53# endif
54#endif
55
56#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
57# ifdef _CACHE
58# define MULTI_CACHE 1
59# else
60# define _CACHE v4wb
61# endif
62#endif
63
64#if defined(CONFIG_CPU_XSCALE)
65# ifdef _CACHE
66# define MULTI_CACHE 1
67# else
68# define _CACHE xscale
69# endif
70#endif
71
72#if defined(CONFIG_CPU_V6)
73
74# define MULTI_CACHE 1
75
76
77
78#endif
79
80#if !defined(_CACHE) && !defined(MULTI_CACHE)
81#error Unknown cache maintainence model
82#endif
83
84
85
86
87
88#define PG_dcache_dirty PG_arch_1
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154struct cpu_cache_fns {
155 void (*flush_kern_all)(void);
156 void (*flush_user_all)(void);
157 void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
158
159 void (*coherent_kern_range)(unsigned long, unsigned long);
160 void (*coherent_user_range)(unsigned long, unsigned long);
161 void (*flush_kern_dcache_page)(void *);
162
163 void (*dma_inv_range)(unsigned long, unsigned long);
164 void (*dma_clean_range)(unsigned long, unsigned long);
165 void (*dma_flush_range)(unsigned long, unsigned long);
166};
167
168
169
170
171#ifdef MULTI_CACHE
172
173extern struct cpu_cache_fns cpu_cache;
174
175#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
176#define __cpuc_flush_user_all cpu_cache.flush_user_all
177#define __cpuc_flush_user_range cpu_cache.flush_user_range
178#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range
179#define __cpuc_coherent_user_range cpu_cache.coherent_user_range
180#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page
181
182
183
184
185
186
187
188#define dmac_inv_range cpu_cache.dma_inv_range
189#define dmac_clean_range cpu_cache.dma_clean_range
190#define dmac_flush_range cpu_cache.dma_flush_range
191
192#else
193
194#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
195#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
196#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
197#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
198#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
199#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page)
200
201extern void __cpuc_flush_kern_all(void);
202extern void __cpuc_flush_user_all(void);
203extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
204extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
205extern void __cpuc_coherent_user_range(unsigned long, unsigned long);
206extern void __cpuc_flush_dcache_page(void *);
207
208
209
210
211
212
213
214#define dmac_inv_range __glue(_CACHE,_dma_inv_range)
215#define dmac_clean_range __glue(_CACHE,_dma_clean_range)
216#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
217
218extern void dmac_inv_range(unsigned long, unsigned long);
219extern void dmac_clean_range(unsigned long, unsigned long);
220extern void dmac_flush_range(unsigned long, unsigned long);
221
222#endif
223
224
225
226
227
228
229
230
231#define flush_cache_vmap(start, end) flush_cache_all()
232#define flush_cache_vunmap(start, end) flush_cache_all()
233
234
235
236
237
238
239#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
240 do { \
241 flush_cache_page(vma, vaddr); \
242 memcpy(dst, src, len); \
243 flush_dcache_page(page); \
244 } while (0)
245
246#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
247 do { \
248 flush_cache_page(vma, vaddr); \
249 memcpy(dst, src, len); \
250 } while (0)
251
252
253
254
255#define flush_cache_all() __cpuc_flush_kern_all()
256
257static inline void flush_cache_mm(struct mm_struct *mm)
258{
259 if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
260 __cpuc_flush_user_all();
261}
262
263static inline void
264flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
265{
266 if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask))
267 __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
268 vma->vm_flags);
269}
270
271static inline void
272flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr)
273{
274 if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
275 unsigned long addr = user_addr & PAGE_MASK;
276 __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
277 }
278}
279
280
281
282
283
284
285#define flush_cache_user_range(vma,start,end) \
286 __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
287
288
289
290
291
292#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
293
294
295
296
297
298#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size)
299
300
301
302
303
304
305
306
307
308
309
310
311
312extern void flush_dcache_page(struct page *);
313
314#define flush_dcache_mmap_lock(mapping) \
315 spin_lock_irq(&(mapping)->tree_lock)
316#define flush_dcache_mmap_unlock(mapping) \
317 spin_unlock_irq(&(mapping)->tree_lock)
318
319#define flush_icache_user_range(vma,page,addr,len) \
320 flush_dcache_page(page)
321
322
323
324
325
326#define flush_icache_page(vma,page) do { } while (0)
327
328#define __cacheid_present(val) (val != read_cpuid(CPUID_ID))
329#define __cacheid_vivt(val) ((val & (15 << 25)) != (14 << 25))
330#define __cacheid_vipt(val) ((val & (15 << 25)) == (14 << 25))
331#define __cacheid_vipt_nonaliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25))
332#define __cacheid_vipt_aliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23))
333
334#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)
335
336#define cache_is_vivt() 1
337#define cache_is_vipt() 0
338#define cache_is_vipt_nonaliasing() 0
339#define cache_is_vipt_aliasing() 0
340
341#elif defined(CONFIG_CPU_CACHE_VIPT)
342
343#define cache_is_vivt() 0
344#define cache_is_vipt() 1
345#define cache_is_vipt_nonaliasing() \
346 ({ \
347 unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
348 __cacheid_vipt_nonaliasing(__val); \
349 })
350
351#define cache_is_vipt_aliasing() \
352 ({ \
353 unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
354 __cacheid_vipt_aliasing(__val); \
355 })
356
357#else
358
359#define cache_is_vivt() \
360 ({ \
361 unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
362 (!__cacheid_present(__val)) || __cacheid_vivt(__val); \
363 })
364
365#define cache_is_vipt() \
366 ({ \
367 unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
368 __cacheid_present(__val) && __cacheid_vipt(__val); \
369 })
370
371#define cache_is_vipt_nonaliasing() \
372 ({ \
373 unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
374 __cacheid_present(__val) && \
375 __cacheid_vipt_nonaliasing(__val); \
376 })
377
378#define cache_is_vipt_aliasing() \
379 ({ \
380 unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
381 __cacheid_present(__val) && \
382 __cacheid_vipt_aliasing(__val); \
383 })
384
385#endif
386
387#endif
388