18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Based on arch/arm/include/asm/cacheflush.h
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 1999-2002 Russell King.
68c2ecf20Sopenharmony_ci * Copyright (C) 2012 ARM Ltd.
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci#ifndef __ASM_CACHEFLUSH_H
98c2ecf20Sopenharmony_ci#define __ASM_CACHEFLUSH_H
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/kgdb.h>
128c2ecf20Sopenharmony_ci#include <linux/mm.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci/*
158c2ecf20Sopenharmony_ci * This flag is used to indicate that the page pointed to by a pte is clean
168c2ecf20Sopenharmony_ci * and does not require cleaning before returning it to the user.
178c2ecf20Sopenharmony_ci */
188c2ecf20Sopenharmony_ci#define PG_dcache_clean PG_arch_1
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci/*
218c2ecf20Sopenharmony_ci *	MM Cache Management
228c2ecf20Sopenharmony_ci *	===================
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci *	The arch/arm64/mm/cache.S implements these methods.
258c2ecf20Sopenharmony_ci *
268c2ecf20Sopenharmony_ci *	Start addresses are inclusive and end addresses are exclusive; start
278c2ecf20Sopenharmony_ci *	addresses should be rounded down, end addresses up.
288c2ecf20Sopenharmony_ci *
298c2ecf20Sopenharmony_ci *	See Documentation/core-api/cachetlb.rst for more information. Please note that
308c2ecf20Sopenharmony_ci *	the implementation assumes non-aliasing VIPT D-cache and (aliasing)
318c2ecf20Sopenharmony_ci *	VIPT I-cache.
328c2ecf20Sopenharmony_ci *
338c2ecf20Sopenharmony_ci *	flush_cache_mm(mm)
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci *		Clean and invalidate all user space cache entries
368c2ecf20Sopenharmony_ci *		before a change of page tables.
378c2ecf20Sopenharmony_ci *
388c2ecf20Sopenharmony_ci *	flush_icache_range(start, end)
398c2ecf20Sopenharmony_ci *
408c2ecf20Sopenharmony_ci *		Ensure coherency between the I-cache and the D-cache in the
418c2ecf20Sopenharmony_ci *		region described by start, end.
428c2ecf20Sopenharmony_ci *		- start  - virtual start address
438c2ecf20Sopenharmony_ci *		- end    - virtual end address
448c2ecf20Sopenharmony_ci *
458c2ecf20Sopenharmony_ci *	invalidate_icache_range(start, end)
468c2ecf20Sopenharmony_ci *
478c2ecf20Sopenharmony_ci *		Invalidate the I-cache in the region described by start, end.
488c2ecf20Sopenharmony_ci *		- start  - virtual start address
498c2ecf20Sopenharmony_ci *		- end    - virtual end address
508c2ecf20Sopenharmony_ci *
518c2ecf20Sopenharmony_ci *	__flush_cache_user_range(start, end)
528c2ecf20Sopenharmony_ci *
538c2ecf20Sopenharmony_ci *		Ensure coherency between the I-cache and the D-cache in the
548c2ecf20Sopenharmony_ci *		region described by start, end.
558c2ecf20Sopenharmony_ci *		- start  - virtual start address
568c2ecf20Sopenharmony_ci *		- end    - virtual end address
578c2ecf20Sopenharmony_ci *
588c2ecf20Sopenharmony_ci *	__flush_dcache_area(kaddr, size)
598c2ecf20Sopenharmony_ci *
608c2ecf20Sopenharmony_ci *		Ensure that the data held in page is written back.
618c2ecf20Sopenharmony_ci *		- kaddr  - page address
628c2ecf20Sopenharmony_ci *		- size   - region size
638c2ecf20Sopenharmony_ci */
648c2ecf20Sopenharmony_ciextern void __flush_icache_range(unsigned long start, unsigned long end);
658c2ecf20Sopenharmony_ciextern int  invalidate_icache_range(unsigned long start, unsigned long end);
668c2ecf20Sopenharmony_ciextern void __flush_dcache_area(void *addr, size_t len);
678c2ecf20Sopenharmony_ciextern void __inval_dcache_area(void *addr, size_t len);
688c2ecf20Sopenharmony_ciextern void __clean_dcache_area_poc(void *addr, size_t len);
698c2ecf20Sopenharmony_ciextern void __clean_dcache_area_pop(void *addr, size_t len);
708c2ecf20Sopenharmony_ciextern void __clean_dcache_area_pou(void *addr, size_t len);
718c2ecf20Sopenharmony_ciextern long __flush_cache_user_range(unsigned long start, unsigned long end);
728c2ecf20Sopenharmony_ciextern void sync_icache_aliases(void *kaddr, unsigned long len);
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic inline void flush_icache_range(unsigned long start, unsigned long end)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	__flush_icache_range(start, end);
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	/*
798c2ecf20Sopenharmony_ci	 * IPI all online CPUs so that they undergo a context synchronization
808c2ecf20Sopenharmony_ci	 * event and are forced to refetch the new instructions.
818c2ecf20Sopenharmony_ci	 */
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	/*
848c2ecf20Sopenharmony_ci	 * KGDB performs cache maintenance with interrupts disabled, so we
858c2ecf20Sopenharmony_ci	 * will deadlock trying to IPI the secondary CPUs. In theory, we can
868c2ecf20Sopenharmony_ci	 * set CACHE_FLUSH_IS_SAFE to 0 to avoid this known issue, but that
878c2ecf20Sopenharmony_ci	 * just means that KGDB will elide the maintenance altogether! As it
888c2ecf20Sopenharmony_ci	 * turns out, KGDB uses IPIs to round-up the secondary CPUs during
898c2ecf20Sopenharmony_ci	 * the patching operation, so we don't need extra IPIs here anyway.
908c2ecf20Sopenharmony_ci	 * In which case, add a KGDB-specific bodge and return early.
918c2ecf20Sopenharmony_ci	 */
928c2ecf20Sopenharmony_ci	if (in_dbg_master())
938c2ecf20Sopenharmony_ci		return;
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	kick_all_cpus_sync();
968c2ecf20Sopenharmony_ci}
978c2ecf20Sopenharmony_ci#define flush_icache_range flush_icache_range
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci/*
1008c2ecf20Sopenharmony_ci * Cache maintenance functions used by the DMA API. No to be used directly.
1018c2ecf20Sopenharmony_ci */
1028c2ecf20Sopenharmony_ciextern void __dma_map_area(const void *, size_t, int);
1038c2ecf20Sopenharmony_ciextern void __dma_unmap_area(const void *, size_t, int);
1048c2ecf20Sopenharmony_ciextern void __dma_flush_area(const void *, size_t);
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci/*
1078c2ecf20Sopenharmony_ci * Copy user data from/to a page which is mapped into a different
1088c2ecf20Sopenharmony_ci * processes address space.  Really, we want to allow our "user
1098c2ecf20Sopenharmony_ci * space" model to handle this.
1108c2ecf20Sopenharmony_ci */
1118c2ecf20Sopenharmony_ciextern void copy_to_user_page(struct vm_area_struct *, struct page *,
1128c2ecf20Sopenharmony_ci	unsigned long, void *, const void *, unsigned long);
1138c2ecf20Sopenharmony_ci#define copy_to_user_page copy_to_user_page
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci/*
1168c2ecf20Sopenharmony_ci * flush_dcache_page is used when the kernel has written to the page
1178c2ecf20Sopenharmony_ci * cache page at virtual address page->virtual.
1188c2ecf20Sopenharmony_ci *
1198c2ecf20Sopenharmony_ci * If this page isn't mapped (ie, page_mapping == NULL), or it might
1208c2ecf20Sopenharmony_ci * have userspace mappings, then we _must_ always clean + invalidate
1218c2ecf20Sopenharmony_ci * the dcache entries associated with the kernel mapping.
1228c2ecf20Sopenharmony_ci *
1238c2ecf20Sopenharmony_ci * Otherwise we can defer the operation, and clean the cache when we are
1248c2ecf20Sopenharmony_ci * about to change to user space.  This is the same method as used on SPARC64.
1258c2ecf20Sopenharmony_ci * See update_mmu_cache for the user space part.
1268c2ecf20Sopenharmony_ci */
1278c2ecf20Sopenharmony_ci#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
1288c2ecf20Sopenharmony_ciextern void flush_dcache_page(struct page *);
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic __always_inline void __flush_icache_all(void)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC))
1338c2ecf20Sopenharmony_ci		return;
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	asm("ic	ialluis");
1368c2ecf20Sopenharmony_ci	dsb(ish);
1378c2ecf20Sopenharmony_ci}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ciint set_memory_valid(unsigned long addr, int numpages, int enable);
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ciint set_direct_map_invalid_noflush(struct page *page);
1428c2ecf20Sopenharmony_ciint set_direct_map_default_noflush(struct page *page);
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci#include <asm-generic/cacheflush.h>
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci#endif /* __ASM_CACHEFLUSH_H */
147