aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa/mm/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/xtensa/mm/cache.c')
-rw-r--r--arch/xtensa/mm/cache.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c
index 63cbb867dadd..96aea6624318 100644
--- a/arch/xtensa/mm/cache.c
+++ b/arch/xtensa/mm/cache.c
@@ -63,6 +63,69 @@
63#error "HIGHMEM is not supported on cores with aliasing cache." 63#error "HIGHMEM is not supported on cores with aliasing cache."
64#endif 64#endif
65 65
66#if (DCACHE_WAY_SIZE > PAGE_SIZE)
67static inline void kmap_invalidate_coherent(struct page *page,
68 unsigned long vaddr)
69{
70 if (!DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) {
71 unsigned long kvaddr;
72
73 if (!PageHighMem(page)) {
74 kvaddr = (unsigned long)page_to_virt(page);
75
76 __invalidate_dcache_page(kvaddr);
77 } else {
78 kvaddr = TLBTEMP_BASE_1 +
79 (page_to_phys(page) & DCACHE_ALIAS_MASK);
80
81 __invalidate_dcache_page_alias(kvaddr,
82 page_to_phys(page));
83 }
84 }
85}
86
87static inline void *coherent_kvaddr(struct page *page, unsigned long base,
88 unsigned long vaddr, unsigned long *paddr)
89{
90 if (PageHighMem(page) || !DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) {
91 *paddr = page_to_phys(page);
92 return (void *)(base + (vaddr & DCACHE_ALIAS_MASK));
93 } else {
94 *paddr = 0;
95 return page_to_virt(page);
96 }
97}
98
99void clear_user_highpage(struct page *page, unsigned long vaddr)
100{
101 unsigned long paddr;
102 void *kvaddr = coherent_kvaddr(page, TLBTEMP_BASE_1, vaddr, &paddr);
103
104 pagefault_disable();
105 kmap_invalidate_coherent(page, vaddr);
106 set_bit(PG_arch_1, &page->flags);
107 clear_page_alias(kvaddr, paddr);
108 pagefault_enable();
109}
110
111void copy_user_highpage(struct page *dst, struct page *src,
112 unsigned long vaddr, struct vm_area_struct *vma)
113{
114 unsigned long dst_paddr, src_paddr;
115 void *dst_vaddr = coherent_kvaddr(dst, TLBTEMP_BASE_1, vaddr,
116 &dst_paddr);
117 void *src_vaddr = coherent_kvaddr(src, TLBTEMP_BASE_2, vaddr,
118 &src_paddr);
119
120 pagefault_disable();
121 kmap_invalidate_coherent(dst, vaddr);
122 set_bit(PG_arch_1, &dst->flags);
123 copy_page_alias(dst_vaddr, src_vaddr, dst_paddr, src_paddr);
124 pagefault_enable();
125}
126
127#endif /* DCACHE_WAY_SIZE > PAGE_SIZE */
128
66#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK 129#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
67 130
68/* 131/*