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_folio(struct folio *folio) 19 { 20 struct address_space *mapping; 21 22 if (is_zero_pfn(folio_pfn(folio))) 23 return; 24 25 mapping = folio_flush_mapping(folio); 26 27 if (mapping && !folio_mapped(folio)) 28 clear_bit(PG_dcache_clean, &folio->flags); 29 else { 30 dcache_wbinv_all(); 31 if (mapping) 32 icache_inv_all(); 33 set_bit(PG_dcache_clean, &folio->flags); 34 } 35 } 36 EXPORT_SYMBOL(flush_dcache_folio); 37 38 void flush_dcache_page(struct page *page) 39 { 40 flush_dcache_folio(page_folio(page)); 41 } 42 EXPORT_SYMBOL(flush_dcache_page); 43 44 void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma, 45 unsigned long addr, pte_t *ptep, unsigned int nr) 46 { 47 unsigned long pfn = pte_pfn(*ptep); 48 struct folio *folio; 49 50 flush_tlb_page(vma, addr); 51 52 if (!pfn_valid(pfn)) 53 return; 54 55 if (is_zero_pfn(pfn)) 56 return; 57 58 folio = page_folio(pfn_to_page(pfn)); 59 if (!test_and_set_bit(PG_dcache_clean, &folio->flags)) 60 dcache_wbinv_all(); 61 62 if (folio_flush_mapping(folio)) { 63 if (vma->vm_flags & VM_EXEC) 64 icache_inv_all(); 65 } 66 } 67 68 void flush_cache_range(struct vm_area_struct *vma, unsigned long start, 69 unsigned long end) 70 { 71 dcache_wbinv_all(); 72 73 if (vma->vm_flags & VM_EXEC) 74 icache_inv_all(); 75 } 76