Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

microblaze: Introduce fixmap

Fixmap will be used for highmem support.

Signed-off-by: Michal Simek <monstr@monstr.eu>

+123 -6
+101
arch/microblaze/include/asm/fixmap.h
··· 1 + /* 2 + * fixmap.h: compile-time virtual memory allocation 3 + * 4 + * This file is subject to the terms and conditions of the GNU General Public 5 + * License. See the file "COPYING" in the main directory of this archive 6 + * for more details. 7 + * 8 + * Copyright (C) 1998 Ingo Molnar 9 + * 10 + * Copyright 2008 Freescale Semiconductor Inc. 11 + * Port to powerpc added by Kumar Gala 12 + * 13 + * Copyright 2011 Michal Simek <monstr@monstr.eu> 14 + * Copyright 2011 PetaLogix Qld Pty Ltd 15 + * Port to Microblaze 16 + */ 17 + 18 + #ifndef _ASM_FIXMAP_H 19 + #define _ASM_FIXMAP_H 20 + 21 + #ifndef __ASSEMBLY__ 22 + #include <linux/kernel.h> 23 + #include <asm/page.h> 24 + 25 + #define FIXADDR_TOP ((unsigned long)(-PAGE_SIZE)) 26 + 27 + /* 28 + * Here we define all the compile-time 'special' virtual 29 + * addresses. The point is to have a constant address at 30 + * compile time, but to set the physical address only 31 + * in the boot process. We allocate these special addresses 32 + * from the end of virtual memory (0xfffff000) backwards. 33 + * Also this lets us do fail-safe vmalloc(), we 34 + * can guarantee that these special addresses and 35 + * vmalloc()-ed addresses never overlap. 36 + * 37 + * these 'compile-time allocated' memory buffers are 38 + * fixed-size 4k pages. (or larger if used with an increment 39 + * highger than 1) use fixmap_set(idx,phys) to associate 40 + * physical memory with fixmap indices. 41 + * 42 + * TLB entries of such buffers will not be flushed across 43 + * task switches. 44 + */ 45 + enum fixed_addresses { 46 + FIX_HOLE, 47 + __end_of_fixed_addresses 48 + }; 49 + 50 + extern void __set_fixmap(enum fixed_addresses idx, 51 + phys_addr_t phys, pgprot_t flags); 52 + 53 + #define set_fixmap(idx, phys) \ 54 + __set_fixmap(idx, phys, PAGE_KERNEL) 55 + /* 56 + * Some hardware wants to get fixmapped without caching. 57 + */ 58 + #define set_fixmap_nocache(idx, phys) \ 59 + __set_fixmap(idx, phys, PAGE_KERNEL_CI) 60 + 61 + #define clear_fixmap(idx) \ 62 + __set_fixmap(idx, 0, __pgprot(0)) 63 + 64 + #define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) 65 + #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE) 66 + 67 + #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) 68 + #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) 69 + 70 + extern void __this_fixmap_does_not_exist(void); 71 + 72 + /* 73 + * 'index to address' translation. If anyone tries to use the idx 74 + * directly without tranlation, we catch the bug with a NULL-deference 75 + * kernel oops. Illegal ranges of incoming indices are caught too. 76 + */ 77 + static __always_inline unsigned long fix_to_virt(const unsigned int idx) 78 + { 79 + /* 80 + * this branch gets completely eliminated after inlining, 81 + * except when someone tries to use fixaddr indices in an 82 + * illegal way. (such as mixing up address types or using 83 + * out-of-range indices). 84 + * 85 + * If it doesn't get removed, the linker will complain 86 + * loudly with a reasonably clear error message.. 87 + */ 88 + if (idx >= __end_of_fixed_addresses) 89 + __this_fixmap_does_not_exist(); 90 + 91 + return __fix_to_virt(idx); 92 + } 93 + 94 + static inline unsigned long virt_to_fix(const unsigned long vaddr) 95 + { 96 + BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); 97 + return __virt_to_fix(vaddr); 98 + } 99 + 100 + #endif /* !__ASSEMBLY__ */ 101 + #endif
+11 -6
arch/microblaze/mm/init.c
··· 24 24 #include <asm/pgalloc.h> 25 25 #include <asm/sections.h> 26 26 #include <asm/tlb.h> 27 + #include <asm/fixmap.h> 27 28 28 29 /* Use for MMU and noMMU because of PCI generic code */ 29 30 int mem_init_done; ··· 55 54 static void __init paging_init(void) 56 55 { 57 56 unsigned long zones_size[MAX_NR_ZONES]; 57 + #ifdef CONFIG_MMU 58 + int idx; 59 + 60 + /* Setup fixmaps */ 61 + for (idx = 0; idx < __end_of_fixed_addresses; idx++) 62 + clear_fixmap(idx); 63 + #endif 58 64 59 65 /* Clean every zones */ 60 66 memset(zones_size, 0, sizeof(zones_size)); ··· 324 316 /* Map in all of RAM starting at CONFIG_KERNEL_START */ 325 317 mapin_ram(); 326 318 327 - #ifdef CONFIG_HIGHMEM_START_BOOL 328 - ioremap_base = CONFIG_HIGHMEM_START; 329 - #else 330 - ioremap_base = 0xfe000000UL; /* for now, could be 0xfffff000 */ 331 - #endif /* CONFIG_HIGHMEM_START_BOOL */ 332 - ioremap_bot = ioremap_base; 319 + /* Extend vmalloc and ioremap area as big as possible */ 320 + ioremap_base = ioremap_bot = FIXADDR_START; 321 + 333 322 /* Initialize the context management stuff */ 334 323 mmu_context_init(); 335 324
+11
arch/microblaze/mm/pgtable.c
··· 37 37 #include <linux/io.h> 38 38 #include <asm/mmu.h> 39 39 #include <asm/sections.h> 40 + #include <asm/fixmap.h> 40 41 41 42 #define flush_HPTE(X, va, pg) _tlbie(va) 42 43 ··· 249 248 clear_page(pte); 250 249 } 251 250 return pte; 251 + } 252 + 253 + void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) 254 + { 255 + unsigned long address = __fix_to_virt(idx); 256 + 257 + if (idx >= __end_of_fixed_addresses) 258 + BUG(); 259 + 260 + map_page(address, phys, pgprot_val(flags)); 252 261 }