1f15cbe6fSPaul Mundt /* 2f15cbe6fSPaul Mundt * fixmap.h: compile-time virtual memory allocation 3f15cbe6fSPaul Mundt * 4f15cbe6fSPaul Mundt * This file is subject to the terms and conditions of the GNU General Public 5f15cbe6fSPaul Mundt * License. See the file "COPYING" in the main directory of this archive 6f15cbe6fSPaul Mundt * for more details. 7f15cbe6fSPaul Mundt * 8f15cbe6fSPaul Mundt * Copyright (C) 1998 Ingo Molnar 9f15cbe6fSPaul Mundt * 10f15cbe6fSPaul Mundt * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 11f15cbe6fSPaul Mundt */ 12f15cbe6fSPaul Mundt 13f15cbe6fSPaul Mundt #ifndef _ASM_FIXMAP_H 14f15cbe6fSPaul Mundt #define _ASM_FIXMAP_H 15f15cbe6fSPaul Mundt 16f15cbe6fSPaul Mundt #include <linux/kernel.h> 17f15cbe6fSPaul Mundt #include <asm/page.h> 18f15cbe6fSPaul Mundt #ifdef CONFIG_HIGHMEM 19f15cbe6fSPaul Mundt #include <linux/threads.h> 20f15cbe6fSPaul Mundt #include <asm/kmap_types.h> 21f15cbe6fSPaul Mundt #endif 22f15cbe6fSPaul Mundt 23f15cbe6fSPaul Mundt /* 24f15cbe6fSPaul Mundt * Here we define all the compile-time 'special' virtual 25f15cbe6fSPaul Mundt * addresses. The point is to have a constant address at 26f15cbe6fSPaul Mundt * compile time, but to set the physical address only 27f15cbe6fSPaul Mundt * in the boot process. We allocate these special addresses 28f15cbe6fSPaul Mundt * from the end of P3 backwards. 29f15cbe6fSPaul Mundt * Also this lets us do fail-safe vmalloc(), we 30f15cbe6fSPaul Mundt * can guarantee that these special addresses and 31f15cbe6fSPaul Mundt * vmalloc()-ed addresses never overlap. 32f15cbe6fSPaul Mundt * 33f15cbe6fSPaul Mundt * these 'compile-time allocated' memory buffers are 34f15cbe6fSPaul Mundt * fixed-size 4k pages. (or larger if used with an increment 35f15cbe6fSPaul Mundt * highger than 1) use fixmap_set(idx,phys) to associate 36f15cbe6fSPaul Mundt * physical memory with fixmap indices. 37f15cbe6fSPaul Mundt * 38f15cbe6fSPaul Mundt * TLB entries of such buffers will not be flushed across 39f15cbe6fSPaul Mundt * task switches. 40f15cbe6fSPaul Mundt */ 41f15cbe6fSPaul Mundt 42f15cbe6fSPaul Mundt /* 43f15cbe6fSPaul Mundt * on UP currently we will have no trace of the fixmap mechanizm, 44f15cbe6fSPaul Mundt * no page table allocations, etc. This might change in the 45f15cbe6fSPaul Mundt * future, say framebuffers for the console driver(s) could be 46f15cbe6fSPaul Mundt * fix-mapped? 47f15cbe6fSPaul Mundt */ 48f15cbe6fSPaul Mundt enum fixed_addresses { 49f15cbe6fSPaul Mundt #define FIX_N_COLOURS 16 50f15cbe6fSPaul Mundt FIX_CMAP_BEGIN, 51f15cbe6fSPaul Mundt FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS, 52f15cbe6fSPaul Mundt FIX_UNCACHED, 53f15cbe6fSPaul Mundt #ifdef CONFIG_HIGHMEM 54f15cbe6fSPaul Mundt FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ 55f15cbe6fSPaul Mundt FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, 56f15cbe6fSPaul Mundt #endif 57f15cbe6fSPaul Mundt __end_of_fixed_addresses 58f15cbe6fSPaul Mundt }; 59f15cbe6fSPaul Mundt 60f15cbe6fSPaul Mundt extern void __set_fixmap(enum fixed_addresses idx, 61f15cbe6fSPaul Mundt unsigned long phys, pgprot_t flags); 62f15cbe6fSPaul Mundt 63f15cbe6fSPaul Mundt #define set_fixmap(idx, phys) \ 64f15cbe6fSPaul Mundt __set_fixmap(idx, phys, PAGE_KERNEL) 65f15cbe6fSPaul Mundt /* 66f15cbe6fSPaul Mundt * Some hardware wants to get fixmapped without caching. 67f15cbe6fSPaul Mundt */ 68f15cbe6fSPaul Mundt #define set_fixmap_nocache(idx, phys) \ 69f15cbe6fSPaul Mundt __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) 70f15cbe6fSPaul Mundt /* 71f15cbe6fSPaul Mundt * used by vmalloc.c. 72f15cbe6fSPaul Mundt * 73f15cbe6fSPaul Mundt * Leave one empty page between vmalloc'ed areas and 74f15cbe6fSPaul Mundt * the start of the fixmap, and leave one page empty 75f15cbe6fSPaul Mundt * at the top of mem.. 76f15cbe6fSPaul Mundt */ 77f15cbe6fSPaul Mundt #ifdef CONFIG_SUPERH32 78f15cbe6fSPaul Mundt #define FIXADDR_TOP (P4SEG - PAGE_SIZE) 79f15cbe6fSPaul Mundt #else 80f15cbe6fSPaul Mundt #define FIXADDR_TOP (0xff000000 - PAGE_SIZE) 81f15cbe6fSPaul Mundt #endif 82f15cbe6fSPaul Mundt #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) 83f15cbe6fSPaul Mundt #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) 84f15cbe6fSPaul Mundt 85f15cbe6fSPaul Mundt #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) 86f15cbe6fSPaul Mundt #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) 87f15cbe6fSPaul Mundt 88f15cbe6fSPaul Mundt extern void __this_fixmap_does_not_exist(void); 89f15cbe6fSPaul Mundt 90f15cbe6fSPaul Mundt /* 91f15cbe6fSPaul Mundt * 'index to address' translation. If anyone tries to use the idx 92f15cbe6fSPaul Mundt * directly without tranlation, we catch the bug with a NULL-deference 93f15cbe6fSPaul Mundt * kernel oops. Illegal ranges of incoming indices are caught too. 94f15cbe6fSPaul Mundt */ 95f15cbe6fSPaul Mundt static inline unsigned long fix_to_virt(const unsigned int idx) 96f15cbe6fSPaul Mundt { 97f15cbe6fSPaul Mundt /* 98f15cbe6fSPaul Mundt * this branch gets completely eliminated after inlining, 99f15cbe6fSPaul Mundt * except when someone tries to use fixaddr indices in an 100f15cbe6fSPaul Mundt * illegal way. (such as mixing up address types or using 101f15cbe6fSPaul Mundt * out-of-range indices). 102f15cbe6fSPaul Mundt * 103f15cbe6fSPaul Mundt * If it doesn't get removed, the linker will complain 104f15cbe6fSPaul Mundt * loudly with a reasonably clear error message.. 105f15cbe6fSPaul Mundt */ 106f15cbe6fSPaul Mundt if (idx >= __end_of_fixed_addresses) 107f15cbe6fSPaul Mundt __this_fixmap_does_not_exist(); 108f15cbe6fSPaul Mundt 109f15cbe6fSPaul Mundt return __fix_to_virt(idx); 110f15cbe6fSPaul Mundt } 111f15cbe6fSPaul Mundt 112f15cbe6fSPaul Mundt static inline unsigned long virt_to_fix(const unsigned long vaddr) 113f15cbe6fSPaul Mundt { 114f15cbe6fSPaul Mundt BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); 115f15cbe6fSPaul Mundt return __virt_to_fix(vaddr); 116f15cbe6fSPaul Mundt } 117f15cbe6fSPaul Mundt #endif 118