Blame view
arch/arm/include/asm/cacheflush.h
10.9 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
4baa99224 [ARM] move includ... |
2 |
* arch/arm/include/asm/cacheflush.h |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 8 9 10 11 |
* * Copyright (C) 1999-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef _ASMARM_CACHEFLUSH_H #define _ASMARM_CACHEFLUSH_H |
1da177e4c Linux-2.6.12-rc2 |
12 |
#include <linux/mm.h> |
753790e71 ARM: move cache/p... |
13 |
#include <asm/glue-cache.h> |
b8a9b66fb [PATCH] ARM: Add ... |
14 |
#include <asm/shmparam.h> |
376e14218 Do not flush the ... |
15 |
#include <asm/cachetype.h> |
33f663ff9 ARM: 5993/1: ARM:... |
16 |
#include <asm/outercache.h> |
b8a9b66fb [PATCH] ARM: Add ... |
17 18 |
#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) |
1da177e4c Linux-2.6.12-rc2 |
19 20 |
/* |
c01778001 ARM: 6379/1: Assu... |
21 22 |
* This flag is used to indicate that the page pointed to by a pte is clean * and does not require cleaning before returning it to the user. |
1da177e4c Linux-2.6.12-rc2 |
23 |
*/ |
c01778001 ARM: 6379/1: Assu... |
24 |
#define PG_dcache_clean PG_arch_1 |
1da177e4c Linux-2.6.12-rc2 |
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
/* * MM Cache Management * =================== * * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files * implement these methods. * * Start addresses are inclusive and end addresses are exclusive; * start addresses should be rounded down, end addresses up. * * See Documentation/cachetlb.txt for more information. * Please note that the implementation of these, and the required * effects are cache-type (VIVT/VIPT/PIPT) specific. * |
81d11955b ARM: 6405/1: Hand... |
40 41 42 43 44 45 |
* flush_icache_all() * * Unconditionally clean and invalidate the entire icache. * Currently only needed for cache-v6.S and cache-v7.S, see * __flush_icache_all for the generic implementation. * |
2045124ff ARM: 5888/1: arm:... |
46 |
* flush_kern_all() |
1da177e4c Linux-2.6.12-rc2 |
47 48 49 |
* * Unconditionally clean and invalidate the entire cache. * |
2045124ff ARM: 5888/1: arm:... |
50 |
* flush_user_all() |
1da177e4c Linux-2.6.12-rc2 |
51 52 53 54 |
* * Clean and invalidate all user space cache entries * before a change of page tables. * |
2045124ff ARM: 5888/1: arm:... |
55 |
* flush_user_range(start, end, flags) |
1da177e4c Linux-2.6.12-rc2 |
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
* * Clean and invalidate a range of cache entries in the * specified address space before a change of page tables. * - start - user start address (inclusive, page aligned) * - end - user end address (exclusive, page aligned) * - flags - vma->vm_flags field * * coherent_kern_range(start, end) * * Ensure coherency between the Icache and the Dcache in the * region described by start, end. If you have non-snooping * Harvard caches, you need to implement this function. * - start - virtual start address * - end - virtual end address * |
2045124ff ARM: 5888/1: arm:... |
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
* coherent_user_range(start, end) * * Ensure coherency between the Icache and the Dcache in the * region described by start, end. If you have non-snooping * Harvard caches, you need to implement this function. * - start - virtual start address * - end - virtual end address * * flush_kern_dcache_area(kaddr, size) * * Ensure that the data held in page is written back. * - kaddr - page address * - size - region size * |
1da177e4c Linux-2.6.12-rc2 |
85 86 87 |
* DMA Cache Coherency * =================== * |
1da177e4c Linux-2.6.12-rc2 |
88 89 90 91 92 93 94 95 |
* dma_flush_range(start, end) * * Clean and invalidate the specified virtual address range. * - start - virtual start address * - end - virtual end address */ struct cpu_cache_fns { |
81d11955b ARM: 6405/1: Hand... |
96 |
void (*flush_icache_all)(void); |
1da177e4c Linux-2.6.12-rc2 |
97 98 99 100 101 102 |
void (*flush_kern_all)(void); void (*flush_user_all)(void); void (*flush_user_range)(unsigned long, unsigned long, unsigned int); void (*coherent_kern_range)(unsigned long, unsigned long); void (*coherent_user_range)(unsigned long, unsigned long); |
2c9b9c849 ARM: add size arg... |
103 |
void (*flush_kern_dcache_area)(void *, size_t); |
1da177e4c Linux-2.6.12-rc2 |
104 |
|
a9c9147eb ARM: dma-mapping:... |
105 106 |
void (*dma_map_area)(const void *, size_t, int); void (*dma_unmap_area)(const void *, size_t, int); |
1da177e4c Linux-2.6.12-rc2 |
107 |
|
7ae5a761d [ARM] Convert DMA... |
108 |
void (*dma_flush_range)(const void *, const void *); |
1da177e4c Linux-2.6.12-rc2 |
109 110 111 112 113 114 115 116 |
}; /* * Select the calling method */ #ifdef MULTI_CACHE extern struct cpu_cache_fns cpu_cache; |
81d11955b ARM: 6405/1: Hand... |
117 |
#define __cpuc_flush_icache_all cpu_cache.flush_icache_all |
1da177e4c Linux-2.6.12-rc2 |
118 119 120 121 122 |
#define __cpuc_flush_kern_all cpu_cache.flush_kern_all #define __cpuc_flush_user_all cpu_cache.flush_user_all #define __cpuc_flush_user_range cpu_cache.flush_user_range #define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range #define __cpuc_coherent_user_range cpu_cache.coherent_user_range |
2c9b9c849 ARM: add size arg... |
123 |
#define __cpuc_flush_dcache_area cpu_cache.flush_kern_dcache_area |
1da177e4c Linux-2.6.12-rc2 |
124 125 126 127 128 129 130 |
/* * These are private to the dma-mapping API. Do not use directly. * Their sole purpose is to ensure that data held in the cache * is visible to DMA, or data written by DMA to system memory is * visible to the CPU. */ |
a9c9147eb ARM: dma-mapping:... |
131 |
#define dmac_map_area cpu_cache.dma_map_area |
753790e71 ARM: move cache/p... |
132 |
#define dmac_unmap_area cpu_cache.dma_unmap_area |
1da177e4c Linux-2.6.12-rc2 |
133 134 135 |
#define dmac_flush_range cpu_cache.dma_flush_range #else |
81d11955b ARM: 6405/1: Hand... |
136 |
extern void __cpuc_flush_icache_all(void); |
1da177e4c Linux-2.6.12-rc2 |
137 138 139 140 141 |
extern void __cpuc_flush_kern_all(void); extern void __cpuc_flush_user_all(void); extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); extern void __cpuc_coherent_user_range(unsigned long, unsigned long); |
2c9b9c849 ARM: add size arg... |
142 |
extern void __cpuc_flush_dcache_area(void *, size_t); |
1da177e4c Linux-2.6.12-rc2 |
143 144 145 146 147 148 149 |
/* * These are private to the dma-mapping API. Do not use directly. * Their sole purpose is to ensure that data held in the cache * is visible to DMA, or data written by DMA to system memory is * visible to the CPU. */ |
a9c9147eb ARM: dma-mapping:... |
150 151 |
extern void dmac_map_area(const void *, size_t, int); extern void dmac_unmap_area(const void *, size_t, int); |
7ae5a761d [ARM] Convert DMA... |
152 |
extern void dmac_flush_range(const void *, const void *); |
1da177e4c Linux-2.6.12-rc2 |
153 154 155 156 |
#endif /* |
1da177e4c Linux-2.6.12-rc2 |
157 158 159 160 |
* Copy user data from/to a page which is mapped into a different * processes address space. Really, we want to allow our "user * space" model to handle this. */ |
2ef7f3dbd ARM: Fix ptrace a... |
161 162 |
extern void copy_to_user_page(struct vm_area_struct *, struct page *, unsigned long, void *, const void *, unsigned long); |
1da177e4c Linux-2.6.12-rc2 |
163 164 |
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ do { \ |
1da177e4c Linux-2.6.12-rc2 |
165 166 167 168 169 170 |
memcpy(dst, src, len); \ } while (0) /* * Convert calls to our calling convention. */ |
81d11955b ARM: 6405/1: Hand... |
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
/* Invalidate I-cache */ #define __flush_icache_all_generic() \ asm("mcr p15, 0, %0, c7, c5, 0" \ : : "r" (0)); /* Invalidate I-cache inner shareable */ #define __flush_icache_all_v7_smp() \ asm("mcr p15, 0, %0, c7, c1, 0" \ : : "r" (0)); /* * Optimized __flush_icache_all for the common cases. Note that UP ARMv7 * will fall through to use __flush_icache_all_generic. */ |
e399b1a4e ARM: v6k: introdu... |
186 187 |
#if (defined(CONFIG_CPU_V7) && \ (defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K))) || \ |
81d11955b ARM: 6405/1: Hand... |
188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
defined(CONFIG_SMP_ON_UP) #define __flush_icache_preferred __cpuc_flush_icache_all #elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP) #define __flush_icache_preferred __flush_icache_all_v7_smp #elif __LINUX_ARM_ARCH__ == 6 && defined(CONFIG_ARM_ERRATA_411920) #define __flush_icache_preferred __cpuc_flush_icache_all #else #define __flush_icache_preferred __flush_icache_all_generic #endif static inline void __flush_icache_all(void) { __flush_icache_preferred(); } |
1da177e4c Linux-2.6.12-rc2 |
202 |
#define flush_cache_all() __cpuc_flush_kern_all() |
2f0b19263 ARM: Avoid duplic... |
203 204 |
static inline void vivt_flush_cache_mm(struct mm_struct *mm) |
1da177e4c Linux-2.6.12-rc2 |
205 |
{ |
56f8ba83a cpumask: use mm_c... |
206 |
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) |
1da177e4c Linux-2.6.12-rc2 |
207 208 209 210 |
__cpuc_flush_user_all(); } static inline void |
2f0b19263 ARM: Avoid duplic... |
211 |
vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) |
1da177e4c Linux-2.6.12-rc2 |
212 |
{ |
56f8ba83a cpumask: use mm_c... |
213 |
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) |
1da177e4c Linux-2.6.12-rc2 |
214 215 216 217 218 |
__cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), vma->vm_flags); } static inline void |
2f0b19263 ARM: Avoid duplic... |
219 |
vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) |
1da177e4c Linux-2.6.12-rc2 |
220 |
{ |
56f8ba83a cpumask: use mm_c... |
221 |
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { |
1da177e4c Linux-2.6.12-rc2 |
222 223 224 225 |
unsigned long addr = user_addr & PAGE_MASK; __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); } } |
a188ad2bc [ARM] 3762/1: Fix... |
226 |
|
2f0b19263 ARM: Avoid duplic... |
227 228 229 230 231 232 233 |
#ifndef CONFIG_CPU_CACHE_VIPT #define flush_cache_mm(mm) \ vivt_flush_cache_mm(mm) #define flush_cache_range(vma,start,end) \ vivt_flush_cache_range(vma,start,end) #define flush_cache_page(vma,addr,pfn) \ vivt_flush_cache_page(vma,addr,pfn) |
d7b6b3589 [ARM] Fix ARMv6 V... |
234 235 236 237 238 |
#else extern void flush_cache_mm(struct mm_struct *mm); extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn); #endif |
1da177e4c Linux-2.6.12-rc2 |
239 |
|
ec8c0446b [PATCH] Optimize ... |
240 |
#define flush_cache_dup_mm(mm) flush_cache_mm(mm) |
1da177e4c Linux-2.6.12-rc2 |
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
/* * flush_cache_user_range is used when we want to ensure that the * Harvard caches are synchronised for the user space address range. * This is used for the ARM private sys_cacheflush system call. */ #define flush_cache_user_range(vma,start,end) \ __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) /* * Perform necessary cache operations to ensure that data previously * stored within this range of addresses can be executed by the CPU. */ #define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e) /* * Perform necessary cache operations to ensure that the TLB will * see data written in the specified area. */ #define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size) /* * flush_dcache_page is used when the kernel has written to the page * cache page at virtual address page->virtual. * * If this page isn't mapped (ie, page_mapping == NULL), or it might * have userspace mappings, then we _must_ always clean + invalidate * the dcache entries associated with the kernel mapping. * * Otherwise we can defer the operation, and clean the cache when we are * about to change to user space. This is the same method as used on SPARC64. * See update_mmu_cache for the user space part. */ |
2d4dc890b block: add helper... |
273 |
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
1da177e4c Linux-2.6.12-rc2 |
274 |
extern void flush_dcache_page(struct page *); |
252a9afff arm: add mm API f... |
275 276 277 278 279 280 281 282 283 284 |
static inline void flush_kernel_vmap_range(void *addr, int size) { if ((cache_is_vivt() || cache_is_vipt_aliasing())) __cpuc_flush_dcache_area(addr, (size_t)size); } static inline void invalidate_kernel_vmap_range(void *addr, int size) { if ((cache_is_vivt() || cache_is_vipt_aliasing())) __cpuc_flush_dcache_area(addr, (size_t)size); } |
826cbdaff [ARM] 5092/1: Fix... |
285 |
|
6020dff09 [ARM] Resolve fus... |
286 287 288 289 290 291 292 293 294 |
#define ARCH_HAS_FLUSH_ANON_PAGE static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) { extern void __flush_anon_page(struct vm_area_struct *vma, struct page *, unsigned long); if (PageAnon(page)) __flush_anon_page(vma, page, vmaddr); } |
73be15915 [ARM] 5545/2: add... |
295 296 297 |
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE static inline void flush_kernel_dcache_page(struct page *page) { |
73be15915 [ARM] 5545/2: add... |
298 |
} |
1da177e4c Linux-2.6.12-rc2 |
299 |
#define flush_dcache_mmap_lock(mapping) \ |
19fd62312 mm: spinlock tree... |
300 |
spin_lock_irq(&(mapping)->tree_lock) |
1da177e4c Linux-2.6.12-rc2 |
301 |
#define flush_dcache_mmap_unlock(mapping) \ |
19fd62312 mm: spinlock tree... |
302 |
spin_unlock_irq(&(mapping)->tree_lock) |
1da177e4c Linux-2.6.12-rc2 |
303 304 305 306 307 308 309 310 311 |
#define flush_icache_user_range(vma,page,addr,len) \ flush_dcache_page(page) /* * We don't appear to need to do anything here. In fact, if we did, we'd * duplicate cache flushing elsewhere performed by flush_dcache_page(). */ #define flush_icache_page(vma,page) do { } while (0) |
376e14218 Do not flush the ... |
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
/* * flush_cache_vmap() is used when creating mappings (eg, via vmap, * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT * caches, since the direct-mappings of these pages may contain cached * data, we need to do a full cache flush to ensure that writebacks * don't corrupt data placed into these pages via the new mappings. */ static inline void flush_cache_vmap(unsigned long start, unsigned long end) { if (!cache_is_vipt_nonaliasing()) flush_cache_all(); else /* * set_pte_at() called from vmap_pte_range() does not * have a DSB after cleaning the cache line. */ dsb(); } static inline void flush_cache_vunmap(unsigned long start, unsigned long end) { if (!cache_is_vipt_nonaliasing()) flush_cache_all(); } |
1da177e4c Linux-2.6.12-rc2 |
336 |
#endif |