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

ARM: add support for generic early_ioremap/early_memremap

This enables the generic early_ioremap implementation for ARM.

It uses the fixmap region reserved for kmap. Since early_ioremap
is only supported before paging_init(), and kmap is only supported
afterwards, this is guaranteed not to cause any clashes.

Tested-by: Ryan Harkin <ryan.harkin@linaro.org>
Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

+45 -4
+1
arch/arm/Kconfig
··· 20 20 select GENERIC_ALLOCATOR 21 21 select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) 22 22 select GENERIC_CLOCKEVENTS_BROADCAST if SMP 23 + select GENERIC_EARLY_IOREMAP 23 24 select GENERIC_IDLE_POLL_SETUP 24 25 select GENERIC_IRQ_PROBE 25 26 select GENERIC_IRQ_SHOW
+1
arch/arm/include/asm/Kbuild
··· 3 3 generic-y += bitsperlong.h 4 4 generic-y += cputime.h 5 5 generic-y += current.h 6 + generic-y += early_ioremap.h 6 7 generic-y += emergency-restart.h 7 8 generic-y += errno.h 8 9 generic-y += exec.h
+28 -1
arch/arm/include/asm/fixmap.h
··· 19 19 FIX_TEXT_POKE0, 20 20 FIX_TEXT_POKE1, 21 21 22 - __end_of_fixed_addresses 22 + __end_of_fixmap_region, 23 + 24 + /* 25 + * Share the kmap() region with early_ioremap(): this is guaranteed 26 + * not to clash since early_ioremap() is only available before 27 + * paging_init(), and kmap() only after. 28 + */ 29 + #define NR_FIX_BTMAPS 32 30 + #define FIX_BTMAPS_SLOTS 7 31 + #define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS) 32 + 33 + FIX_BTMAP_END = __end_of_permanent_fixed_addresses, 34 + FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1, 35 + __end_of_early_ioremap_region 23 36 }; 37 + 38 + static const enum fixed_addresses __end_of_fixed_addresses = 39 + __end_of_fixmap_region > __end_of_early_ioremap_region ? 40 + __end_of_fixmap_region : __end_of_early_ioremap_region; 24 41 25 42 #define FIXMAP_PAGE_COMMON (L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN | L_PTE_DIRTY) 26 43 27 44 #define FIXMAP_PAGE_NORMAL (FIXMAP_PAGE_COMMON | L_PTE_MT_WRITEBACK) 45 + #define FIXMAP_PAGE_RO (FIXMAP_PAGE_NORMAL | L_PTE_RDONLY) 28 46 29 47 /* Used by set_fixmap_(io|nocache), both meant for mapping a device */ 30 48 #define FIXMAP_PAGE_IO (FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_SHARED | L_PTE_SHARED) 31 49 #define FIXMAP_PAGE_NOCACHE FIXMAP_PAGE_IO 50 + 51 + #define __early_set_fixmap __set_fixmap 52 + 53 + #ifdef CONFIG_MMU 32 54 33 55 void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot); 34 56 void __init early_fixmap_init(void); 35 57 36 58 #include <asm-generic/fixmap.h> 37 59 60 + #else 61 + 62 + static inline void early_fixmap_init(void) { } 63 + 64 + #endif 38 65 #endif
+5 -2
arch/arm/kernel/setup.c
··· 38 38 #include <asm/cpu.h> 39 39 #include <asm/cputype.h> 40 40 #include <asm/elf.h> 41 + #include <asm/early_ioremap.h> 41 42 #include <asm/fixmap.h> 42 43 #include <asm/procinfo.h> 43 44 #include <asm/psci.h> ··· 957 956 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); 958 957 *cmdline_p = cmd_line; 959 958 960 - if (IS_ENABLED(CONFIG_FIX_EARLYCON_MEM)) 961 - early_fixmap_init(); 959 + early_fixmap_init(); 960 + early_ioremap_init(); 962 961 963 962 parse_early_param(); 964 963 ··· 968 967 setup_dma_zone(mdesc); 969 968 sanity_check_meminfo(); 970 969 arm_memblock_init(mdesc); 970 + 971 + early_ioremap_reset(); 971 972 972 973 paging_init(mdesc); 973 974 request_standard_resources(mdesc);
+9
arch/arm/mm/ioremap.c
··· 30 30 #include <asm/cp15.h> 31 31 #include <asm/cputype.h> 32 32 #include <asm/cacheflush.h> 33 + #include <asm/early_ioremap.h> 33 34 #include <asm/mmu_context.h> 34 35 #include <asm/pgalloc.h> 35 36 #include <asm/tlbflush.h> ··· 470 469 } 471 470 EXPORT_SYMBOL_GPL(pci_ioremap_io); 472 471 #endif 472 + 473 + /* 474 + * Must be called after early_fixmap_init 475 + */ 476 + void __init early_ioremap_init(void) 477 + { 478 + early_ioremap_setup(); 479 + }
+1 -1
arch/arm/mm/mmu.c
··· 390 390 * The early fixmap range spans multiple pmds, for which 391 391 * we are not prepared: 392 392 */ 393 - BUILD_BUG_ON((__fix_to_virt(__end_of_permanent_fixed_addresses) >> PMD_SHIFT) 393 + BUILD_BUG_ON((__fix_to_virt(__end_of_early_ioremap_region) >> PMD_SHIFT) 394 394 != FIXADDR_TOP >> PMD_SHIFT); 395 395 396 396 pmd = fixmap_pmd(FIXADDR_TOP);