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 #include <asm/tlbflush.h> 15 16 #define PG_dcache_clean PG_arch_1 17 18 void flush_dcache_page(struct page *page) 19 { 20 struct address_space *mapping; 21 22 if (page == ZERO_PAGE(0)) 23 return; 24 25 mapping = page_mapping_file(page); 26 27 if (mapping && !page_mapcount(page)) 28 clear_bit(PG_dcache_clean, &page->flags); 29 else { 30 dcache_wbinv_all(); 31 if (mapping) 32 icache_inv_all(); 33 set_bit(PG_dcache_clean, &page->flags); 34 } 35 } 36 EXPORT_SYMBOL(flush_dcache_page); 37 38 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, 39 pte_t *ptep) 40 { 41 unsigned long pfn = pte_pfn(*ptep); 42 struct page *page; 43 44 flush_tlb_page(vma, addr); 45 46 if (!pfn_valid(pfn)) 47 return; 48 49 page = pfn_to_page(pfn); 50 if (page == ZERO_PAGE(0)) 51 return; 52 53 if (!test_and_set_bit(PG_dcache_clean, &page->flags)) 54 dcache_wbinv_all(); 55 56 if (page_mapping_file(page)) { 57 if (vma->vm_flags & VM_EXEC) 58 icache_inv_all(); 59 } 60 } 61 62 void flush_cache_range(struct vm_area_struct *vma, unsigned long start, 63 unsigned long end) 64 { 65 dcache_wbinv_all(); 66 67 if (vma->vm_flags & VM_EXEC) 68 icache_inv_all(); 69 } 70