1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3 4 #include <linux/kernel.h> 5 #include <linux/mm.h> 6 #include <linux/fs.h> 7 #include <linux/pagemap.h> 8 #include <linux/syscalls.h> 9 #include <linux/spinlock.h> 10 #include <asm/page.h> 11 #include <asm/cache.h> 12 #include <asm/cacheflush.h> 13 #include <asm/cachectl.h> 14 15 #define PG_dcache_clean PG_arch_1 16 17 void flush_dcache_page(struct page *page) 18 { 19 struct address_space *mapping; 20 21 if (page == ZERO_PAGE(0)) 22 return; 23 24 mapping = page_mapping_file(page); 25 26 if (mapping && !page_mapcount(page)) 27 clear_bit(PG_dcache_clean, &page->flags); 28 else { 29 dcache_wbinv_all(); 30 if (mapping) 31 icache_inv_all(); 32 set_bit(PG_dcache_clean, &page->flags); 33 } 34 } 35 EXPORT_SYMBOL(flush_dcache_page); 36 37 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, 38 pte_t *ptep) 39 { 40 unsigned long pfn = pte_pfn(*ptep); 41 struct page *page; 42 43 if (!pfn_valid(pfn)) 44 return; 45 46 page = pfn_to_page(pfn); 47 if (page == ZERO_PAGE(0)) 48 return; 49 50 if (!test_and_set_bit(PG_dcache_clean, &page->flags)) 51 dcache_wbinv_all(); 52 53 if (page_mapping_file(page)) { 54 if (vma->vm_flags & VM_EXEC) 55 icache_inv_all(); 56 } 57 } 58 59 void flush_kernel_dcache_page(struct page *page) 60 { 61 struct address_space *mapping; 62 63 mapping = page_mapping_file(page); 64 65 if (!mapping || mapping_mapped(mapping)) 66 dcache_wbinv_all(); 67 } 68 EXPORT_SYMBOL(flush_kernel_dcache_page); 69 70 void flush_cache_range(struct vm_area_struct *vma, unsigned long start, 71 unsigned long end) 72 { 73 dcache_wbinv_all(); 74 75 if (vma->vm_flags & VM_EXEC) 76 icache_inv_all(); 77 } 78