1 #ifndef _PARISC_CACHEFLUSH_H 2 #define _PARISC_CACHEFLUSH_H 3 4 #include <linux/config.h> 5 #include <linux/mm.h> 6 7 /* The usual comment is "Caches aren't brain-dead on the <architecture>". 8 * Unfortunately, that doesn't apply to PA-RISC. */ 9 10 /* Cache flush operations */ 11 12 #ifdef CONFIG_SMP 13 #define flush_cache_mm(mm) flush_cache_all() 14 #else 15 #define flush_cache_mm(mm) flush_cache_all_local() 16 #endif 17 18 #define flush_kernel_dcache_range(start,size) \ 19 flush_kernel_dcache_range_asm((start), (start)+(size)); 20 21 extern void flush_cache_all_local(void); 22 23 static inline void cacheflush_h_tmp_function(void *dummy) 24 { 25 flush_cache_all_local(); 26 } 27 28 static inline void flush_cache_all(void) 29 { 30 on_each_cpu(cacheflush_h_tmp_function, NULL, 1, 1); 31 } 32 33 #define flush_cache_vmap(start, end) flush_cache_all() 34 #define flush_cache_vunmap(start, end) flush_cache_all() 35 36 /* The following value needs to be tuned and probably scaled with the 37 * cache size. 38 */ 39 40 #define FLUSH_THRESHOLD 0x80000 41 42 static inline void 43 flush_user_dcache_range(unsigned long start, unsigned long end) 44 { 45 #ifdef CONFIG_SMP 46 flush_user_dcache_range_asm(start,end); 47 #else 48 if ((end - start) < FLUSH_THRESHOLD) 49 flush_user_dcache_range_asm(start,end); 50 else 51 flush_data_cache(); 52 #endif 53 } 54 55 static inline void 56 flush_user_icache_range(unsigned long start, unsigned long end) 57 { 58 #ifdef CONFIG_SMP 59 flush_user_icache_range_asm(start,end); 60 #else 61 if ((end - start) < FLUSH_THRESHOLD) 62 flush_user_icache_range_asm(start,end); 63 else 64 flush_instruction_cache(); 65 #endif 66 } 67 68 extern void __flush_dcache_page(struct page *page); 69 70 static inline void flush_dcache_page(struct page *page) 71 { 72 if (page->mapping && list_empty(&page->mapping->i_mmap) && 73 list_empty(&page->mapping->i_mmap_shared)) { 74 set_bit(PG_dcache_dirty, &page->flags); 75 } else { 76 __flush_dcache_page(page); 77 } 78 } 79 80 #define flush_icache_page(vma,page) do { flush_kernel_dcache_page(page_address(page)); flush_kernel_icache_page(page_address(page)); } while (0) 81 82 #define flush_icache_range(s,e) do { flush_kernel_dcache_range_asm(s,e); flush_kernel_icache_range_asm(s,e); } while (0) 83 84 #define flush_icache_user_range(vma, page, addr, len) do { \ 85 flush_user_dcache_range(addr, addr + len); \ 86 flush_user_icache_range(addr, addr + len); } while (0) 87 88 #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ 89 do { memcpy(dst, src, len); \ 90 flush_icache_user_range(vma, page, vaddr, len); \ 91 } while (0) 92 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ 93 memcpy(dst, src, len) 94 95 static inline void flush_cache_range(struct vm_area_struct *vma, 96 unsigned long start, unsigned long end) 97 { 98 int sr3; 99 100 if (!vma->vm_mm->context) { 101 BUG(); 102 return; 103 } 104 105 sr3 = mfsp(3); 106 if (vma->vm_mm->context == sr3) { 107 flush_user_dcache_range(start,end); 108 flush_user_icache_range(start,end); 109 } else { 110 flush_cache_all(); 111 } 112 } 113 114 static inline void 115 flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr) 116 { 117 int sr3; 118 119 if (!vma->vm_mm->context) { 120 BUG(); 121 return; 122 } 123 124 sr3 = mfsp(3); 125 if (vma->vm_mm->context == sr3) { 126 flush_user_dcache_range(vmaddr,vmaddr + PAGE_SIZE); 127 if (vma->vm_flags & VM_EXEC) 128 flush_user_icache_range(vmaddr,vmaddr + PAGE_SIZE); 129 } else { 130 if (vma->vm_flags & VM_EXEC) 131 flush_cache_all(); 132 else 133 flush_data_cache(); 134 } 135 } 136 #endif 137 138
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.