150acfb2bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 2fab957c1SPalmer Dabbelt /* 3fab957c1SPalmer Dabbelt * Copyright (C) 2015 Regents of the University of California 4fab957c1SPalmer Dabbelt */ 5fab957c1SPalmer Dabbelt 6fab957c1SPalmer Dabbelt #ifndef _ASM_RISCV_CACHEFLUSH_H 7fab957c1SPalmer Dabbelt #define _ASM_RISCV_CACHEFLUSH_H 8fab957c1SPalmer Dabbelt 92d69fbf3SPaul Walmsley #include <linux/mm.h> 10fab957c1SPalmer Dabbelt 11fab957c1SPalmer Dabbelt static inline void local_flush_icache_all(void) 12fab957c1SPalmer Dabbelt { 13fab957c1SPalmer Dabbelt asm volatile ("fence.i" ::: "memory"); 14fab957c1SPalmer Dabbelt } 15fab957c1SPalmer Dabbelt 166ca445d8SAlexandre Ghiti static inline void local_flush_icache_range(unsigned long start, 176ca445d8SAlexandre Ghiti unsigned long end) 186ca445d8SAlexandre Ghiti { 196ca445d8SAlexandre Ghiti local_flush_icache_all(); 206ca445d8SAlexandre Ghiti } 216ca445d8SAlexandre Ghiti 2208f051edSAndrew Waterman #define PG_dcache_clean PG_arch_1 2308f051edSAndrew Waterman 24864609c6SMatthew Wilcox (Oracle) static inline void flush_dcache_folio(struct folio *folio) 25864609c6SMatthew Wilcox (Oracle) { 26864609c6SMatthew Wilcox (Oracle) if (test_bit(PG_dcache_clean, &folio->flags)) 27864609c6SMatthew Wilcox (Oracle) clear_bit(PG_dcache_clean, &folio->flags); 28864609c6SMatthew Wilcox (Oracle) } 29864609c6SMatthew Wilcox (Oracle) #define flush_dcache_folio flush_dcache_folio 30864609c6SMatthew Wilcox (Oracle) #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 31864609c6SMatthew Wilcox (Oracle) 3208f051edSAndrew Waterman static inline void flush_dcache_page(struct page *page) 3308f051edSAndrew Waterman { 34864609c6SMatthew Wilcox (Oracle) flush_dcache_folio(page_folio(page)); 3508f051edSAndrew Waterman } 3608f051edSAndrew Waterman 3708f051edSAndrew Waterman /* 3808f051edSAndrew Waterman * RISC-V doesn't have an instruction to flush parts of the instruction cache, 3908f051edSAndrew Waterman * so instead we just flush the whole thing. 4008f051edSAndrew Waterman */ 4108f051edSAndrew Waterman #define flush_icache_range(start, end) flush_icache_all() 42885f7f8eSChristoph Hellwig #define flush_icache_user_page(vma, pg, addr, len) \ 43542124fcSYangyu Chen do { \ 44542124fcSYangyu Chen if (vma->vm_flags & VM_EXEC) \ 45542124fcSYangyu Chen flush_icache_mm(vma->vm_mm, 0); \ 46542124fcSYangyu Chen } while (0) 4708f051edSAndrew Waterman 487e381152SAlexandre Ghiti #ifdef CONFIG_64BIT 49*503638e0SAlexandre Ghiti extern u64 new_vmalloc[NR_CPUS / sizeof(u64) + 1]; 50*503638e0SAlexandre Ghiti extern char _end[]; 51*503638e0SAlexandre Ghiti #define flush_cache_vmap flush_cache_vmap 52*503638e0SAlexandre Ghiti static inline void flush_cache_vmap(unsigned long start, unsigned long end) 53*503638e0SAlexandre Ghiti { 54*503638e0SAlexandre Ghiti if (is_vmalloc_or_module_addr((void *)start)) { 55*503638e0SAlexandre Ghiti int i; 56*503638e0SAlexandre Ghiti 57*503638e0SAlexandre Ghiti /* 58*503638e0SAlexandre Ghiti * We don't care if concurrently a cpu resets this value since 59*503638e0SAlexandre Ghiti * the only place this can happen is in handle_exception() where 60*503638e0SAlexandre Ghiti * an sfence.vma is emitted. 61*503638e0SAlexandre Ghiti */ 62*503638e0SAlexandre Ghiti for (i = 0; i < ARRAY_SIZE(new_vmalloc); ++i) 63*503638e0SAlexandre Ghiti new_vmalloc[i] = -1ULL; 64*503638e0SAlexandre Ghiti } 65*503638e0SAlexandre Ghiti } 667a92fc8bSAlexandre Ghiti #define flush_cache_vmap_early(start, end) local_flush_tlb_kernel_range(start, end) 677e381152SAlexandre Ghiti #endif 687e381152SAlexandre Ghiti 69fab957c1SPalmer Dabbelt #ifndef CONFIG_SMP 70fab957c1SPalmer Dabbelt 7108f051edSAndrew Waterman #define flush_icache_all() local_flush_icache_all() 7208f051edSAndrew Waterman #define flush_icache_mm(mm, local) flush_icache_all() 73fab957c1SPalmer Dabbelt 74fab957c1SPalmer Dabbelt #else /* CONFIG_SMP */ 75fab957c1SPalmer Dabbelt 7658de7754SGary Guo void flush_icache_all(void); 7708f051edSAndrew Waterman void flush_icache_mm(struct mm_struct *mm, bool local); 78fab957c1SPalmer Dabbelt 79fab957c1SPalmer Dabbelt #endif /* CONFIG_SMP */ 80fab957c1SPalmer Dabbelt 818f7e001eSPalmer Dabbelt extern unsigned int riscv_cbom_block_size; 827ea5a736SAndrew Jones extern unsigned int riscv_cboz_block_size; 837ea5a736SAndrew Jones void riscv_init_cbo_blocksizes(void); 841631ba12SHeiko Stuebner 851631ba12SHeiko Stuebner #ifdef CONFIG_RISCV_DMA_NONCOHERENT 861631ba12SHeiko Stuebner void riscv_noncoherent_supported(void); 8729267151SJisheng Zhang void __init riscv_set_dma_cache_alignment(void); 88f055268eSHeiko Stuebner #else 89f055268eSHeiko Stuebner static inline void riscv_noncoherent_supported(void) {} 9029267151SJisheng Zhang static inline void riscv_set_dma_cache_alignment(void) {} 911631ba12SHeiko Stuebner #endif 921631ba12SHeiko Stuebner 93921ebd8fSAndrew Waterman /* 94921ebd8fSAndrew Waterman * Bits in sys_riscv_flush_icache()'s flags argument. 95921ebd8fSAndrew Waterman */ 96921ebd8fSAndrew Waterman #define SYS_RISCV_FLUSH_ICACHE_LOCAL 1UL 97921ebd8fSAndrew Waterman #define SYS_RISCV_FLUSH_ICACHE_ALL (SYS_RISCV_FLUSH_ICACHE_LOCAL) 98921ebd8fSAndrew Waterman 99396eb69cSChristoph Hellwig #include <asm-generic/cacheflush.h> 100396eb69cSChristoph Hellwig 101fab957c1SPalmer Dabbelt #endif /* _ASM_RISCV_CACHEFLUSH_H */ 102