diff options
-rw-r--r-- | arch/parisc/kernel/cache.c | 45 | ||||
-rw-r--r-- | include/asm-parisc/cacheflush.h | 30 | ||||
-rw-r--r-- | include/asm-parisc/page.h | 22 | ||||
-rw-r--r-- | include/asm-parisc/processor.h | 13 |
4 files changed, 87 insertions, 23 deletions
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index bc7c4a4e26a1..7e8d697aef36 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c | |||
@@ -91,7 +91,8 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) | |||
91 | 91 | ||
92 | flush_kernel_dcache_page(page); | 92 | flush_kernel_dcache_page(page); |
93 | clear_bit(PG_dcache_dirty, &page->flags); | 93 | clear_bit(PG_dcache_dirty, &page->flags); |
94 | } | 94 | } else if (parisc_requires_coherency()) |
95 | flush_kernel_dcache_page(page); | ||
95 | } | 96 | } |
96 | 97 | ||
97 | void | 98 | void |
@@ -370,3 +371,45 @@ void parisc_setup_cache_timing(void) | |||
370 | 371 | ||
371 | printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus()); | 372 | printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus()); |
372 | } | 373 | } |
374 | |||
375 | extern void purge_kernel_dcache_page(unsigned long); | ||
376 | extern void clear_user_page_asm(void *page, unsigned long vaddr); | ||
377 | |||
378 | void | ||
379 | clear_user_page(void *page, unsigned long vaddr, struct page *pg) | ||
380 | { | ||
381 | purge_kernel_dcache_page((unsigned long)page); | ||
382 | purge_tlb_start(); | ||
383 | pdtlb_kernel(page); | ||
384 | purge_tlb_end(); | ||
385 | clear_user_page_asm(page, vaddr); | ||
386 | } | ||
387 | |||
388 | void flush_kernel_dcache_page_addr(void *addr) | ||
389 | { | ||
390 | flush_kernel_dcache_page_asm(addr); | ||
391 | purge_tlb_start(); | ||
392 | pdtlb_kernel(addr); | ||
393 | purge_tlb_end(); | ||
394 | } | ||
395 | EXPORT_SYMBOL(flush_kernel_dcache_page_addr); | ||
396 | |||
397 | void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, | ||
398 | struct page *pg) | ||
399 | { | ||
400 | /* no coherency needed (all in kmap/kunmap) */ | ||
401 | copy_user_page_asm(vto, vfrom); | ||
402 | if (!parisc_requires_coherency()) | ||
403 | flush_kernel_dcache_page_asm(vto); | ||
404 | } | ||
405 | EXPORT_SYMBOL(copy_user_page); | ||
406 | |||
407 | #ifdef CONFIG_PA8X00 | ||
408 | |||
409 | void kunmap_parisc(void *addr) | ||
410 | { | ||
411 | if (parisc_requires_coherency()) | ||
412 | flush_kernel_dcache_page_addr(addr); | ||
413 | } | ||
414 | EXPORT_SYMBOL(kunmap_parisc); | ||
415 | #endif | ||
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h index 0b459cdfbd6f..2bc41f2e0271 100644 --- a/include/asm-parisc/cacheflush.h +++ b/include/asm-parisc/cacheflush.h | |||
@@ -191,16 +191,38 @@ flush_anon_page(struct page *page, unsigned long vmaddr) | |||
191 | } | 191 | } |
192 | #define ARCH_HAS_FLUSH_ANON_PAGE | 192 | #define ARCH_HAS_FLUSH_ANON_PAGE |
193 | 193 | ||
194 | static inline void | 194 | #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE |
195 | flush_kernel_dcache_page(struct page *page) | 195 | void flush_kernel_dcache_page_addr(void *addr); |
196 | static inline void flush_kernel_dcache_page(struct page *page) | ||
196 | { | 197 | { |
197 | flush_kernel_dcache_page_asm(page_address(page)); | 198 | flush_kernel_dcache_page_addr(page_address(page)); |
198 | } | 199 | } |
199 | #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE | ||
200 | 200 | ||
201 | #ifdef CONFIG_DEBUG_RODATA | 201 | #ifdef CONFIG_DEBUG_RODATA |
202 | void mark_rodata_ro(void); | 202 | void mark_rodata_ro(void); |
203 | #endif | 203 | #endif |
204 | 204 | ||
205 | #ifdef CONFIG_PA8X00 | ||
206 | /* Only pa8800, pa8900 needs this */ | ||
207 | #define ARCH_HAS_KMAP | ||
208 | |||
209 | void kunmap_parisc(void *addr); | ||
210 | |||
211 | static inline void *kmap(struct page *page) | ||
212 | { | ||
213 | might_sleep(); | ||
214 | return page_address(page); | ||
215 | } | ||
216 | |||
217 | #define kunmap(page) kunmap_parisc(page_address(page)) | ||
218 | |||
219 | #define kmap_atomic(page, idx) page_address(page) | ||
220 | |||
221 | #define kunmap_atomic(addr, idx) kunmap_parisc(addr) | ||
222 | |||
223 | #define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn)) | ||
224 | #define kmap_atomic_to_page(ptr) virt_to_page(ptr) | ||
225 | #endif | ||
226 | |||
205 | #endif /* _PARISC_CACHEFLUSH_H */ | 227 | #endif /* _PARISC_CACHEFLUSH_H */ |
206 | 228 | ||
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h index 57d6d82756dd..3567208191e3 100644 --- a/include/asm-parisc/page.h +++ b/include/asm-parisc/page.h | |||
@@ -26,24 +26,10 @@ | |||
26 | 26 | ||
27 | struct page; | 27 | struct page; |
28 | 28 | ||
29 | extern void purge_kernel_dcache_page(unsigned long); | 29 | void copy_user_page_asm(void *to, void *from); |
30 | extern void copy_user_page_asm(void *to, void *from); | 30 | void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, |
31 | extern void clear_user_page_asm(void *page, unsigned long vaddr); | 31 | struct page *pg); |
32 | 32 | void clear_user_page(void *page, unsigned long vaddr, struct page *pg); | |
33 | static inline void | ||
34 | copy_user_page(void *vto, void *vfrom, unsigned long vaddr, struct page *pg) | ||
35 | { | ||
36 | copy_user_page_asm(vto, vfrom); | ||
37 | flush_kernel_dcache_page_asm(vto); | ||
38 | /* XXX: ppc flushes icache too, should we? */ | ||
39 | } | ||
40 | |||
41 | static inline void | ||
42 | clear_user_page(void *page, unsigned long vaddr, struct page *pg) | ||
43 | { | ||
44 | purge_kernel_dcache_page((unsigned long)page); | ||
45 | clear_user_page_asm(page, vaddr); | ||
46 | } | ||
47 | 33 | ||
48 | /* | 34 | /* |
49 | * These are used to make use of C type-checking.. | 35 | * These are used to make use of C type-checking.. |
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h index c72b8fa49686..4313618c98ee 100644 --- a/include/asm-parisc/processor.h +++ b/include/asm-parisc/processor.h | |||
@@ -332,6 +332,19 @@ extern unsigned long get_wchan(struct task_struct *p); | |||
332 | 332 | ||
333 | #define cpu_relax() barrier() | 333 | #define cpu_relax() barrier() |
334 | 334 | ||
335 | /* Used as a macro to identify the combined VIPT/PIPT cached | ||
336 | * CPUs which require a guarantee of coherency (no inequivalent | ||
337 | * aliases with different data, whether clean or not) to operate */ | ||
338 | static inline int parisc_requires_coherency(void) | ||
339 | { | ||
340 | #ifdef CONFIG_PA8X00 | ||
341 | /* FIXME: also pa8900 - when we see one */ | ||
342 | return boot_cpu_data.cpu_type == mako; | ||
343 | #else | ||
344 | return 0; | ||
345 | #endif | ||
346 | } | ||
347 | |||
335 | #endif /* __ASSEMBLY__ */ | 348 | #endif /* __ASSEMBLY__ */ |
336 | 349 | ||
337 | #endif /* __ASM_PARISC_PROCESSOR_H */ | 350 | #endif /* __ASM_PARISC_PROCESSOR_H */ |