summaryrefslogtreecommitdiffstats
path: root/arch/csky/abiv1/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/abiv1/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/abiv1/cacheflush.c')
-rw-r--r--arch/csky/abiv1/cacheflush.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/arch/csky/abiv1/cacheflush.c b/arch/csky/abiv1/cacheflush.c
new file mode 100644
index 000000000000..10af8b6fe322
--- /dev/null
+++ b/arch/csky/abiv1/cacheflush.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/syscalls.h>
+#include <linux/spinlock.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/cachectl.h>
+
+void flush_dcache_page(struct page *page)
+{
+ struct address_space *mapping = page_mapping(page);
+ unsigned long addr;
+
+ if (mapping && !mapping_mapped(mapping)) {
+ set_bit(PG_arch_1, &(page)->flags);
+ return;
+ }
+
+ /*
+ * We could delay the flush for the !page_mapping case too. But that
+ * case is for exec env/arg pages and those are %99 certainly going to
+ * get faulted into the tlb (and thus flushed) anyways.
+ */
+ addr = (unsigned long) page_address(page);
+ dcache_wb_range(addr, addr + PAGE_SIZE);
+}
+
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
+ pte_t *pte)
+{
+ unsigned long addr;
+ struct page *page;
+ unsigned long pfn;
+
+ pfn = pte_pfn(*pte);
+ if (unlikely(!pfn_valid(pfn)))
+ return;
+
+ page = pfn_to_page(pfn);
+ addr = (unsigned long) page_address(page);
+
+ if (vma->vm_flags & VM_EXEC ||
+ pages_do_alias(addr, address & PAGE_MASK))
+ cache_wbinv_all();
+
+ clear_bit(PG_arch_1, &(page)->flags);
+}