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