1/* 2 * Copyright (C) 1998 Ingo Molnar 3 * Copyright 2010 Tilera Corporation. All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation, version 2. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 12 * NON INFRINGEMENT. See the GNU General Public License for 13 * more details. 14 */ 15 16#ifndef _ASM_TILE_FIXMAP_H 17#define _ASM_TILE_FIXMAP_H 18 19#include <asm/page.h> 20 21#ifndef __ASSEMBLY__ 22#include <linux/kernel.h> 23#ifdef CONFIG_HIGHMEM 24#include <linux/threads.h> 25#include <asm/kmap_types.h> 26#endif 27 28#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) 29#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) 30 31/* 32 * Here we define all the compile-time 'special' virtual 33 * addresses. The point is to have a constant address at 34 * compile time, but to set the physical address only 35 * in the boot process. We allocate these special addresses 36 * from the end of supervisor virtual memory backwards. 37 * Also this lets us do fail-safe vmalloc(), we 38 * can guarantee that these special addresses and 39 * vmalloc()-ed addresses never overlap. 40 * 41 * these 'compile-time allocated' memory buffers are 42 * fixed-size 4k pages. (or larger if used with an increment 43 * higher than 1) use fixmap_set(idx,phys) to associate 44 * physical memory with fixmap indices. 45 * 46 * TLB entries of such buffers will not be flushed across 47 * task switches. 48 */ 49enum fixed_addresses { 50#ifdef __tilegx__ 51 /* 52 * TILEPro has unmapped memory above so the hole isn't needed, 53 * and in any case the hole pushes us over a single 16MB pmd. 54 */ 55 FIX_HOLE, 56#endif 57#ifdef CONFIG_HIGHMEM 58 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ 59 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, 60#endif 61#ifdef __tilegx__ /* see homecache.c */ 62 FIX_HOMECACHE_BEGIN, 63 FIX_HOMECACHE_END = FIX_HOMECACHE_BEGIN+(NR_CPUS)-1, 64#endif 65 __end_of_permanent_fixed_addresses, 66 67 /* 68 * Temporary boot-time mappings, used before ioremap() is functional. 69 * Not currently needed by the Tile architecture. 70 */ 71#define NR_FIX_BTMAPS 0 72#if NR_FIX_BTMAPS 73 FIX_BTMAP_END = __end_of_permanent_fixed_addresses, 74 FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1, 75 __end_of_fixed_addresses 76#else 77 __end_of_fixed_addresses = __end_of_permanent_fixed_addresses 78#endif 79}; 80 81extern void __set_fixmap(enum fixed_addresses idx, 82 unsigned long phys, pgprot_t flags); 83 84#define set_fixmap(idx, phys) \ 85 __set_fixmap(idx, phys, PAGE_KERNEL) 86#define clear_fixmap(idx) \ 87 __set_fixmap(idx, 0, __pgprot(0)) 88 89#define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) 90#define __FIXADDR_BOOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) 91#define FIXADDR_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_SIZE) 92#define FIXADDR_BOOT_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_BOOT_SIZE) 93 94extern void __this_fixmap_does_not_exist(void); 95 96/* 97 * 'index to address' translation. If anyone tries to use the idx 98 * directly without tranlation, we catch the bug with a NULL-deference 99 * kernel oops. Illegal ranges of incoming indices are caught too. 100 */ 101static __always_inline unsigned long fix_to_virt(const unsigned int idx) 102{ 103 /* 104 * this branch gets completely eliminated after inlining, 105 * except when someone tries to use fixaddr indices in an 106 * illegal way. (such as mixing up address types or using 107 * out-of-range indices). 108 * 109 * If it doesn't get removed, the linker will complain 110 * loudly with a reasonably clear error message.. 111 */ 112 if (idx >= __end_of_fixed_addresses) 113 __this_fixmap_does_not_exist(); 114 115 return __fix_to_virt(idx); 116} 117 118static inline unsigned long virt_to_fix(const unsigned long vaddr) 119{ 120 BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); 121 return __virt_to_fix(vaddr); 122} 123 124#endif /* !__ASSEMBLY__ */ 125 126#endif /* _ASM_TILE_FIXMAP_H */ 127