18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include <linux/kernel.h>
58c2ecf20Sopenharmony_ci#include <linux/mm.h>
68c2ecf20Sopenharmony_ci#include <linux/fs.h>
78c2ecf20Sopenharmony_ci#include <linux/syscalls.h>
88c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
98c2ecf20Sopenharmony_ci#include <asm/page.h>
108c2ecf20Sopenharmony_ci#include <asm/cache.h>
118c2ecf20Sopenharmony_ci#include <asm/cacheflush.h>
128c2ecf20Sopenharmony_ci#include <asm/cachectl.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#define PG_dcache_clean		PG_arch_1
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_civoid flush_dcache_page(struct page *page)
178c2ecf20Sopenharmony_ci{
188c2ecf20Sopenharmony_ci	struct address_space *mapping;
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci	if (page == ZERO_PAGE(0))
218c2ecf20Sopenharmony_ci		return;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	mapping = page_mapping_file(page);
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	if (mapping && !page_mapcount(page))
268c2ecf20Sopenharmony_ci		clear_bit(PG_dcache_clean, &page->flags);
278c2ecf20Sopenharmony_ci	else {
288c2ecf20Sopenharmony_ci		dcache_wbinv_all();
298c2ecf20Sopenharmony_ci		if (mapping)
308c2ecf20Sopenharmony_ci			icache_inv_all();
318c2ecf20Sopenharmony_ci		set_bit(PG_dcache_clean, &page->flags);
328c2ecf20Sopenharmony_ci	}
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ciEXPORT_SYMBOL(flush_dcache_page);
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_civoid update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
378c2ecf20Sopenharmony_ci	pte_t *ptep)
388c2ecf20Sopenharmony_ci{
398c2ecf20Sopenharmony_ci	unsigned long pfn = pte_pfn(*ptep);
408c2ecf20Sopenharmony_ci	struct page *page;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	if (!pfn_valid(pfn))
438c2ecf20Sopenharmony_ci		return;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	page = pfn_to_page(pfn);
468c2ecf20Sopenharmony_ci	if (page == ZERO_PAGE(0))
478c2ecf20Sopenharmony_ci		return;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	if (!test_and_set_bit(PG_dcache_clean, &page->flags))
508c2ecf20Sopenharmony_ci		dcache_wbinv_all();
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	if (page_mapping_file(page)) {
538c2ecf20Sopenharmony_ci		if (vma->vm_flags & VM_EXEC)
548c2ecf20Sopenharmony_ci			icache_inv_all();
558c2ecf20Sopenharmony_ci	}
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_civoid flush_kernel_dcache_page(struct page *page)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	struct address_space *mapping;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	mapping = page_mapping_file(page);
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	if (!mapping || mapping_mapped(mapping))
658c2ecf20Sopenharmony_ci		dcache_wbinv_all();
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_ciEXPORT_SYMBOL(flush_kernel_dcache_page);
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_civoid flush_cache_range(struct vm_area_struct *vma, unsigned long start,
708c2ecf20Sopenharmony_ci	unsigned long end)
718c2ecf20Sopenharmony_ci{
728c2ecf20Sopenharmony_ci	dcache_wbinv_all();
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	if (vma->vm_flags & VM_EXEC)
758c2ecf20Sopenharmony_ci		icache_inv_all();
768c2ecf20Sopenharmony_ci}
77