18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_HIGHMEM_H
38c2ecf20Sopenharmony_ci#define _ASM_HIGHMEM_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <asm/kmap_types.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#define PKMAP_BASE		(PAGE_OFFSET - PMD_SIZE)
88c2ecf20Sopenharmony_ci#define LAST_PKMAP		PTRS_PER_PTE
98c2ecf20Sopenharmony_ci#define LAST_PKMAP_MASK		(LAST_PKMAP - 1)
108c2ecf20Sopenharmony_ci#define PKMAP_NR(virt)		(((virt) - PKMAP_BASE) >> PAGE_SHIFT)
118c2ecf20Sopenharmony_ci#define PKMAP_ADDR(nr)		(PKMAP_BASE + ((nr) << PAGE_SHIFT))
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#define flush_cache_kmaps() \
148c2ecf20Sopenharmony_ci	do { \
158c2ecf20Sopenharmony_ci		if (cache_is_vivt()) \
168c2ecf20Sopenharmony_ci			flush_cache_all(); \
178c2ecf20Sopenharmony_ci	} while (0)
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ciextern pte_t *pkmap_page_table;
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/*
228c2ecf20Sopenharmony_ci * The reason for kmap_high_get() is to ensure that the currently kmap'd
238c2ecf20Sopenharmony_ci * page usage count does not decrease to zero while we're using its
248c2ecf20Sopenharmony_ci * existing virtual mapping in an atomic context.  With a VIVT cache this
258c2ecf20Sopenharmony_ci * is essential to do, but with a VIPT cache this is only an optimization
268c2ecf20Sopenharmony_ci * so not to pay the price of establishing a second mapping if an existing
278c2ecf20Sopenharmony_ci * one can be used.  However, on platforms without hardware TLB maintenance
288c2ecf20Sopenharmony_ci * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since
298c2ecf20Sopenharmony_ci * the locking involved must also disable IRQs which is incompatible with
308c2ecf20Sopenharmony_ci * the IPI mechanism used by global TLB operations.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci#define ARCH_NEEDS_KMAP_HIGH_GET
338c2ecf20Sopenharmony_ci#if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6)
348c2ecf20Sopenharmony_ci#undef ARCH_NEEDS_KMAP_HIGH_GET
358c2ecf20Sopenharmony_ci#if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT)
368c2ecf20Sopenharmony_ci#error "The sum of features in your kernel config cannot be supported together"
378c2ecf20Sopenharmony_ci#endif
388c2ecf20Sopenharmony_ci#endif
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/*
418c2ecf20Sopenharmony_ci * Needed to be able to broadcast the TLB invalidation for kmap.
428c2ecf20Sopenharmony_ci */
438c2ecf20Sopenharmony_ci#ifdef CONFIG_ARM_ERRATA_798181
448c2ecf20Sopenharmony_ci#undef ARCH_NEEDS_KMAP_HIGH_GET
458c2ecf20Sopenharmony_ci#endif
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#ifdef ARCH_NEEDS_KMAP_HIGH_GET
488c2ecf20Sopenharmony_ciextern void *kmap_high_get(struct page *page);
498c2ecf20Sopenharmony_ci#else
508c2ecf20Sopenharmony_cistatic inline void *kmap_high_get(struct page *page)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	return NULL;
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci#endif
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci/*
578c2ecf20Sopenharmony_ci * The following functions are already defined by <linux/highmem.h>
588c2ecf20Sopenharmony_ci * when CONFIG_HIGHMEM is not set.
598c2ecf20Sopenharmony_ci */
608c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM
618c2ecf20Sopenharmony_ciextern void *kmap_atomic_pfn(unsigned long pfn);
628c2ecf20Sopenharmony_ci#endif
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci#endif
65