summaryrefslogtreecommitdiffstats
path: root/arch/csky/abiv2/cacheflush.c
diff options
context:
space:
mode:
authorGuo Ren2018-09-05 08:25:10 +0200
committerGuo Ren2018-10-25 17:36:19 +0200
commit00a9730e1007c6cc87a7c78af2f24a4105d616ee (patch)
treec014e5a0606a7a88b6e3493f49862c040f9aeea8 /arch/csky/abiv2/cacheflush.c
parentcsky: System Call (diff)
downloadkernel-qcow2-linux-00a9730e1007c6cc87a7c78af2f24a4105d616ee.tar.gz
kernel-qcow2-linux-00a9730e1007c6cc87a7c78af2f24a4105d616ee.tar.xz
kernel-qcow2-linux-00a9730e1007c6cc87a7c78af2f24a4105d616ee.zip
csky: Cache and TLB routines
This patch adds cache and tlb sync codes for abiv1 & abiv2. Signed-off-by: Guo Ren <ren_guo@c-sky.com> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/csky/abiv2/cacheflush.c')
-rw-r--r--arch/csky/abiv2/cacheflush.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/arch/csky/abiv2/cacheflush.c b/arch/csky/abiv2/cacheflush.c
new file mode 100644
index 000000000000..d22c95ffc74d
--- /dev/null
+++ b/arch/csky/abiv2/cacheflush.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#include <linux/cache.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <asm/cache.h>
+
+void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+ unsigned long start;
+
+ start = (unsigned long) kmap_atomic(page);
+
+ cache_wbinv_range(start, start + PAGE_SIZE);
+
+ kunmap_atomic((void *)start);
+}
+
+void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+ unsigned long vaddr, int len)
+{
+ unsigned long kaddr;
+
+ kaddr = (unsigned long) kmap_atomic(page) + (vaddr & ~PAGE_MASK);
+
+ cache_wbinv_range(kaddr, kaddr + len);
+
+ kunmap_atomic((void *)kaddr);
+}
+
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
+ pte_t *pte)
+{
+ unsigned long addr, pfn;
+ struct page *page;
+ void *va;
+
+ if (!(vma->vm_flags & VM_EXEC))
+ return;
+
+ pfn = pte_pfn(*pte);
+ if (unlikely(!pfn_valid(pfn)))
+ return;
+
+ page = pfn_to_page(pfn);
+ if (page == ZERO_PAGE(0))
+ return;
+
+ va = page_address(page);
+ addr = (unsigned long) va;
+
+ if (va == NULL && PageHighMem(page))
+ addr = (unsigned long) kmap_atomic(page);
+
+ cache_wbinv_range(addr, addr + PAGE_SIZE);
+
+ if (va == NULL && PageHighMem(page))
+ kunmap_atomic((void *) addr);
+}