76 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
 | |
| 
 | |
| #include <linux/kernel.h>
 | |
| #include <linux/mm.h>
 | |
| #include <linux/fs.h>
 | |
| #include <linux/pagemap.h>
 | |
| #include <linux/syscalls.h>
 | |
| #include <linux/spinlock.h>
 | |
| #include <asm/page.h>
 | |
| #include <asm/cache.h>
 | |
| #include <asm/cacheflush.h>
 | |
| #include <asm/cachectl.h>
 | |
| #include <asm/tlbflush.h>
 | |
| 
 | |
| #define PG_dcache_clean		PG_arch_1
 | |
| 
 | |
| void flush_dcache_folio(struct folio *folio)
 | |
| {
 | |
| 	struct address_space *mapping;
 | |
| 
 | |
| 	if (is_zero_pfn(folio_pfn(folio)))
 | |
| 		return;
 | |
| 
 | |
| 	mapping = folio_flush_mapping(folio);
 | |
| 
 | |
| 	if (mapping && !folio_mapped(folio))
 | |
| 		clear_bit(PG_dcache_clean, &folio->flags);
 | |
| 	else {
 | |
| 		dcache_wbinv_all();
 | |
| 		if (mapping)
 | |
| 			icache_inv_all();
 | |
| 		set_bit(PG_dcache_clean, &folio->flags);
 | |
| 	}
 | |
| }
 | |
| EXPORT_SYMBOL(flush_dcache_folio);
 | |
| 
 | |
| void flush_dcache_page(struct page *page)
 | |
| {
 | |
| 	flush_dcache_folio(page_folio(page));
 | |
| }
 | |
| EXPORT_SYMBOL(flush_dcache_page);
 | |
| 
 | |
| void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma,
 | |
| 		unsigned long addr, pte_t *ptep, unsigned int nr)
 | |
| {
 | |
| 	unsigned long pfn = pte_pfn(*ptep);
 | |
| 	struct folio *folio;
 | |
| 
 | |
| 	flush_tlb_page(vma, addr);
 | |
| 
 | |
| 	if (!pfn_valid(pfn))
 | |
| 		return;
 | |
| 
 | |
| 	if (is_zero_pfn(pfn))
 | |
| 		return;
 | |
| 
 | |
| 	folio = page_folio(pfn_to_page(pfn));
 | |
| 	if (!test_and_set_bit(PG_dcache_clean, &folio->flags))
 | |
| 		dcache_wbinv_all();
 | |
| 
 | |
| 	if (folio_flush_mapping(folio)) {
 | |
| 		if (vma->vm_flags & VM_EXEC)
 | |
| 			icache_inv_all();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
 | |
| 	unsigned long end)
 | |
| {
 | |
| 	dcache_wbinv_all();
 | |
| 
 | |
| 	if (vma->vm_flags & VM_EXEC)
 | |
| 		icache_inv_all();
 | |
| }
 |