1*41938761SMichal Simek /* 2*41938761SMichal Simek * fixmap.h: compile-time virtual memory allocation 3*41938761SMichal Simek * 4*41938761SMichal Simek * This file is subject to the terms and conditions of the GNU General Public 5*41938761SMichal Simek * License. See the file "COPYING" in the main directory of this archive 6*41938761SMichal Simek * for more details. 7*41938761SMichal Simek * 8*41938761SMichal Simek * Copyright (C) 1998 Ingo Molnar 9*41938761SMichal Simek * 10*41938761SMichal Simek * Copyright 2008 Freescale Semiconductor Inc. 11*41938761SMichal Simek * Port to powerpc added by Kumar Gala 12*41938761SMichal Simek * 13*41938761SMichal Simek * Copyright 2011 Michal Simek <monstr@monstr.eu> 14*41938761SMichal Simek * Copyright 2011 PetaLogix Qld Pty Ltd 15*41938761SMichal Simek * Port to Microblaze 16*41938761SMichal Simek */ 17*41938761SMichal Simek 18*41938761SMichal Simek #ifndef _ASM_FIXMAP_H 19*41938761SMichal Simek #define _ASM_FIXMAP_H 20*41938761SMichal Simek 21*41938761SMichal Simek #ifndef __ASSEMBLY__ 22*41938761SMichal Simek #include <linux/kernel.h> 23*41938761SMichal Simek #include <asm/page.h> 24*41938761SMichal Simek 25*41938761SMichal Simek #define FIXADDR_TOP ((unsigned long)(-PAGE_SIZE)) 26*41938761SMichal Simek 27*41938761SMichal Simek /* 28*41938761SMichal Simek * Here we define all the compile-time 'special' virtual 29*41938761SMichal Simek * addresses. The point is to have a constant address at 30*41938761SMichal Simek * compile time, but to set the physical address only 31*41938761SMichal Simek * in the boot process. We allocate these special addresses 32*41938761SMichal Simek * from the end of virtual memory (0xfffff000) backwards. 33*41938761SMichal Simek * Also this lets us do fail-safe vmalloc(), we 34*41938761SMichal Simek * can guarantee that these special addresses and 35*41938761SMichal Simek * vmalloc()-ed addresses never overlap. 36*41938761SMichal Simek * 37*41938761SMichal Simek * these 'compile-time allocated' memory buffers are 38*41938761SMichal Simek * fixed-size 4k pages. (or larger if used with an increment 39*41938761SMichal Simek * highger than 1) use fixmap_set(idx,phys) to associate 40*41938761SMichal Simek * physical memory with fixmap indices. 41*41938761SMichal Simek * 42*41938761SMichal Simek * TLB entries of such buffers will not be flushed across 43*41938761SMichal Simek * task switches. 44*41938761SMichal Simek */ 45*41938761SMichal Simek enum fixed_addresses { 46*41938761SMichal Simek FIX_HOLE, 47*41938761SMichal Simek __end_of_fixed_addresses 48*41938761SMichal Simek }; 49*41938761SMichal Simek 50*41938761SMichal Simek extern void __set_fixmap(enum fixed_addresses idx, 51*41938761SMichal Simek phys_addr_t phys, pgprot_t flags); 52*41938761SMichal Simek 53*41938761SMichal Simek #define set_fixmap(idx, phys) \ 54*41938761SMichal Simek __set_fixmap(idx, phys, PAGE_KERNEL) 55*41938761SMichal Simek /* 56*41938761SMichal Simek * Some hardware wants to get fixmapped without caching. 57*41938761SMichal Simek */ 58*41938761SMichal Simek #define set_fixmap_nocache(idx, phys) \ 59*41938761SMichal Simek __set_fixmap(idx, phys, PAGE_KERNEL_CI) 60*41938761SMichal Simek 61*41938761SMichal Simek #define clear_fixmap(idx) \ 62*41938761SMichal Simek __set_fixmap(idx, 0, __pgprot(0)) 63*41938761SMichal Simek 64*41938761SMichal Simek #define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) 65*41938761SMichal Simek #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE) 66*41938761SMichal Simek 67*41938761SMichal Simek #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) 68*41938761SMichal Simek #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) 69*41938761SMichal Simek 70*41938761SMichal Simek extern void __this_fixmap_does_not_exist(void); 71*41938761SMichal Simek 72*41938761SMichal Simek /* 73*41938761SMichal Simek * 'index to address' translation. If anyone tries to use the idx 74*41938761SMichal Simek * directly without tranlation, we catch the bug with a NULL-deference 75*41938761SMichal Simek * kernel oops. Illegal ranges of incoming indices are caught too. 76*41938761SMichal Simek */ 77*41938761SMichal Simek static __always_inline unsigned long fix_to_virt(const unsigned int idx) 78*41938761SMichal Simek { 79*41938761SMichal Simek /* 80*41938761SMichal Simek * this branch gets completely eliminated after inlining, 81*41938761SMichal Simek * except when someone tries to use fixaddr indices in an 82*41938761SMichal Simek * illegal way. (such as mixing up address types or using 83*41938761SMichal Simek * out-of-range indices). 84*41938761SMichal Simek * 85*41938761SMichal Simek * If it doesn't get removed, the linker will complain 86*41938761SMichal Simek * loudly with a reasonably clear error message.. 87*41938761SMichal Simek */ 88*41938761SMichal Simek if (idx >= __end_of_fixed_addresses) 89*41938761SMichal Simek __this_fixmap_does_not_exist(); 90*41938761SMichal Simek 91*41938761SMichal Simek return __fix_to_virt(idx); 92*41938761SMichal Simek } 93*41938761SMichal Simek 94*41938761SMichal Simek static inline unsigned long virt_to_fix(const unsigned long vaddr) 95*41938761SMichal Simek { 96*41938761SMichal Simek BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); 97*41938761SMichal Simek return __virt_to_fix(vaddr); 98*41938761SMichal Simek } 99*41938761SMichal Simek 100*41938761SMichal Simek #endif /* !__ASSEMBLY__ */ 101*41938761SMichal Simek #endif 102