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

[ARM] fixmap support

This is the minimum fixmap interface expected to be implemented by
architectures supporting highmem.

We have a second level page table already allocated and covering
0xfff00000-0xffffffff because the exception vector page is located
at 0xffff0000, and various cache tricks already use some entries above
0xffff0000. Therefore the PTEs covering 0xfff00000-0xfffeffff are free
to be used.

However the XScale cache flushing code already uses virtual addresses
between 0xfffe0000 and 0xfffeffff.

So this reserves the 0xfff00000-0xfffdffff range for fixmap stuff.

The Documentation/arm/memory.txt information is updated accordingly,
including the information about the actual top of DMA memory mapping
region which didn't match the code.

Signed-off-by: Nicolas Pitre <nico@marvell.com>

+50 -3
+8 -1
Documentation/arm/memory.txt
··· 29 29 CPU supports vector relocation (control 30 30 register V bit.) 31 31 32 - ffc00000 fffeffff DMA memory mapping region. Memory returned 32 + fffe0000 fffeffff XScale cache flush area. This is used 33 + in proc-xscale.S to flush the whole data 34 + cache. Free for other usage on non-XScale. 35 + 36 + fff00000 fffdffff Fixmap mapping region. Addresses provided 37 + by fix_to_virt() will be located here. 38 + 39 + ffc00000 ffefffff DMA memory mapping region. Memory returned 33 40 by the dma_alloc_xxx functions will be 34 41 dynamically mapped here. 35 42
+41
arch/arm/include/asm/fixmap.h
··· 1 + #ifndef _ASM_FIXMAP_H 2 + #define _ASM_FIXMAP_H 3 + 4 + /* 5 + * Nothing too fancy for now. 6 + * 7 + * On ARM we already have well known fixed virtual addresses imposed by 8 + * the architecture such as the vector page which is located at 0xffff0000, 9 + * therefore a second level page table is already allocated covering 10 + * 0xfff00000 upwards. 11 + * 12 + * The cache flushing code in proc-xscale.S uses the virtual area between 13 + * 0xfffe0000 and 0xfffeffff. 14 + */ 15 + 16 + #define FIXADDR_START 0xfff00000UL 17 + #define FIXADDR_TOP 0xfffe0000UL 18 + #define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START) 19 + 20 + #define FIX_KMAP_BEGIN 0 21 + #define FIX_KMAP_END (FIXADDR_SIZE >> PAGE_SHIFT) 22 + 23 + #define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT)) 24 + #define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT) 25 + 26 + extern void __this_fixmap_does_not_exist(void); 27 + 28 + static inline unsigned long fix_to_virt(const unsigned int idx) 29 + { 30 + if (idx >= FIX_KMAP_END) 31 + __this_fixmap_does_not_exist(); 32 + return __fix_to_virt(idx); 33 + } 34 + 35 + static inline unsigned int virt_to_fix(const unsigned long vaddr) 36 + { 37 + BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); 38 + return __virt_to_fix(vaddr); 39 + } 40 + 41 + #endif
+1 -2
arch/arm/mm/mm.h
··· 1 - /* the upper-most page table pointer */ 2 - 3 1 #ifdef CONFIG_MMU 4 2 3 + /* the upper-most page table pointer */ 5 4 extern pmd_t *top_pmd; 6 5 7 6 #define TOP_PTE(x) pte_offset_kernel(top_pmd, x)