2018-09-05 09:25:10 +03:00
// 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>
2021-04-30 08:55:35 +03:00
# include <linux/pagemap.h>
2018-09-05 09:25:10 +03:00
# include <linux/syscalls.h>
# include <linux/spinlock.h>
# include <asm/page.h>
# include <asm/cache.h>
# include <asm/cacheflush.h>
# include <asm/cachectl.h>
2023-04-06 11:46:49 +03:00
# include <asm/tlbflush.h>
2018-09-05 09:25:10 +03:00
2019-08-20 07:47:24 +03:00
# define PG_dcache_clean PG_arch_1
2023-08-02 18:13:39 +03:00
void flush_dcache_folio ( struct folio * folio )
2018-09-05 09:25:10 +03:00
{
2019-08-20 07:47:24 +03:00
struct address_space * mapping ;
2018-09-05 09:25:10 +03:00
2023-08-02 18:13:39 +03:00
if ( is_zero_pfn ( folio_pfn ( folio ) ) )
2018-09-05 09:25:10 +03:00
return ;
2023-08-02 18:13:39 +03:00
mapping = folio_flush_mapping ( folio ) ;
2019-08-20 07:47:24 +03:00
2023-08-02 18:13:39 +03:00
if ( mapping & & ! folio_mapped ( folio ) )
clear_bit ( PG_dcache_clean , & folio - > flags ) ;
2019-08-20 07:47:24 +03:00
else {
dcache_wbinv_all ( ) ;
if ( mapping )
icache_inv_all ( ) ;
2023-08-02 18:13:39 +03:00
set_bit ( PG_dcache_clean , & folio - > flags ) ;
2019-08-20 07:47:24 +03:00
}
2018-09-05 09:25:10 +03:00
}
2023-08-02 18:13:39 +03:00
EXPORT_SYMBOL ( flush_dcache_folio ) ;
void flush_dcache_page ( struct page * page )
{
flush_dcache_folio ( page_folio ( page ) ) ;
}
2019-08-20 07:47:24 +03:00
EXPORT_SYMBOL ( flush_dcache_page ) ;
2018-09-05 09:25:10 +03:00
2023-08-02 18:13:39 +03:00
void update_mmu_cache_range ( struct vm_fault * vmf , struct vm_area_struct * vma ,
unsigned long addr , pte_t * ptep , unsigned int nr )
2018-09-05 09:25:10 +03:00
{
2019-08-20 07:47:24 +03:00
unsigned long pfn = pte_pfn ( * ptep ) ;
2023-08-02 18:13:39 +03:00
struct folio * folio ;
2018-09-05 09:25:10 +03:00
2023-04-06 11:46:49 +03:00
flush_tlb_page ( vma , addr ) ;
2019-08-20 07:47:24 +03:00
if ( ! pfn_valid ( pfn ) )
2018-09-05 09:25:10 +03:00
return ;
2023-08-02 18:13:39 +03:00
if ( is_zero_pfn ( pfn ) )
2019-08-20 07:47:24 +03:00
return ;
2018-09-05 09:25:10 +03:00
2023-08-02 18:13:39 +03:00
folio = page_folio ( pfn_to_page ( pfn ) ) ;
if ( ! test_and_set_bit ( PG_dcache_clean , & folio - > flags ) )
2019-08-20 07:47:24 +03:00
dcache_wbinv_all ( ) ;
2018-09-05 09:25:10 +03:00
2023-08-02 18:13:39 +03:00
if ( folio_flush_mapping ( folio ) ) {
2019-08-20 07:47:24 +03:00
if ( vma - > vm_flags & VM_EXEC )
icache_inv_all ( ) ;
}
2018-09-05 09:25:10 +03:00
}
2019-08-21 14:15:52 +03:00
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 ( ) ;
}