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