1d73cd428SNicolas Pitre #ifndef _ASM_HIGHMEM_H 2d73cd428SNicolas Pitre #define _ASM_HIGHMEM_H 3d73cd428SNicolas Pitre 4d73cd428SNicolas Pitre #include <asm/kmap_types.h> 5d73cd428SNicolas Pitre 6d73cd428SNicolas Pitre #define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE) 7d73cd428SNicolas Pitre #define LAST_PKMAP PTRS_PER_PTE 8d73cd428SNicolas Pitre #define LAST_PKMAP_MASK (LAST_PKMAP - 1) 9d73cd428SNicolas Pitre #define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) 10d73cd428SNicolas Pitre #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) 11d73cd428SNicolas Pitre 12d73cd428SNicolas Pitre #define kmap_prot PAGE_KERNEL 13d73cd428SNicolas Pitre 147e5a69e8SNicolas Pitre #define flush_cache_kmaps() \ 157e5a69e8SNicolas Pitre do { \ 167e5a69e8SNicolas Pitre if (cache_is_vivt()) \ 177e5a69e8SNicolas Pitre flush_cache_all(); \ 187e5a69e8SNicolas Pitre } while (0) 19d73cd428SNicolas Pitre 20d73cd428SNicolas Pitre extern pte_t *pkmap_page_table; 21d73cd428SNicolas Pitre 22d73cd428SNicolas Pitre extern void *kmap_high(struct page *page); 23d73cd428SNicolas Pitre extern void kunmap_high(struct page *page); 24d73cd428SNicolas Pitre 257e5a69e8SNicolas Pitre /* 26aaa50048SNicolas Pitre * The reason for kmap_high_get() is to ensure that the currently kmap'd 27aaa50048SNicolas Pitre * page usage count does not decrease to zero while we're using its 28aaa50048SNicolas Pitre * existing virtual mapping in an atomic context. With a VIVT cache this 29aaa50048SNicolas Pitre * is essential to do, but with a VIPT cache this is only an optimization 30aaa50048SNicolas Pitre * so not to pay the price of establishing a second mapping if an existing 31aaa50048SNicolas Pitre * one can be used. However, on platforms without hardware TLB maintenance 32aaa50048SNicolas Pitre * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since 33aaa50048SNicolas Pitre * the locking involved must also disable IRQs which is incompatible with 34aaa50048SNicolas Pitre * the IPI mechanism used by global TLB operations. 35aaa50048SNicolas Pitre */ 36aaa50048SNicolas Pitre #define ARCH_NEEDS_KMAP_HIGH_GET 37aaa50048SNicolas Pitre #if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6) 38aaa50048SNicolas Pitre #undef ARCH_NEEDS_KMAP_HIGH_GET 39aaa50048SNicolas Pitre #if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT) 40aaa50048SNicolas Pitre #error "The sum of features in your kernel config cannot be supported together" 41aaa50048SNicolas Pitre #endif 42aaa50048SNicolas Pitre #endif 43aaa50048SNicolas Pitre 44aaa50048SNicolas Pitre #ifdef ARCH_NEEDS_KMAP_HIGH_GET 45aaa50048SNicolas Pitre extern void *kmap_high_get(struct page *page); 46aaa50048SNicolas Pitre #else 47aaa50048SNicolas Pitre static inline void *kmap_high_get(struct page *page) 48aaa50048SNicolas Pitre { 49aaa50048SNicolas Pitre return NULL; 50aaa50048SNicolas Pitre } 51aaa50048SNicolas Pitre #endif 52aaa50048SNicolas Pitre 53aaa50048SNicolas Pitre /* 547e5a69e8SNicolas Pitre * The following functions are already defined by <linux/highmem.h> 557e5a69e8SNicolas Pitre * when CONFIG_HIGHMEM is not set. 567e5a69e8SNicolas Pitre */ 577e5a69e8SNicolas Pitre #ifdef CONFIG_HIGHMEM 58d73cd428SNicolas Pitre extern void *kmap(struct page *page); 59d73cd428SNicolas Pitre extern void kunmap(struct page *page); 603e4d3af5SPeter Zijlstra extern void *__kmap_atomic(struct page *page); 613e4d3af5SPeter Zijlstra extern void __kunmap_atomic(void *kvaddr); 623e4d3af5SPeter Zijlstra extern void *kmap_atomic_pfn(unsigned long pfn); 63d73cd428SNicolas Pitre extern struct page *kmap_atomic_to_page(const void *ptr); 647e5a69e8SNicolas Pitre #endif 65d73cd428SNicolas Pitre 66d73cd428SNicolas Pitre #endif 67