mm: generic early_ioremap support
Subsystems (8)
cover mm: generic early_ioremap support
To: linux-kernel at vger.kernel.org
CC: x86 at kernel.org
CC: linux-arm-kernel at lists.infradead.org
CC: Andrew Morton <[email protected]>
CC: Arnd Bergmann <[email protected]>
CC: Ingo Molnar <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: "H. Peter Anvin" <[email protected]>
CC: Russell King <[email protected]>
CC: Catalin Marinas <[email protected]>
CC: Will Deacon <[email protected]>
CC: Dave Young <[email protected]>
CC: Rob Herring <[email protected]>
CC: Leif Lindholm <[email protected]>
CC: patches at linaro.org
This patch series takes the common bits from the x86 early ioremap implementation and creates a generic implementation which may be used by other architectures. The early ioremap interfaces are intended for situations where boot code needs to make temporary virtual mappings before the normal ioremap interfaces are available. Typically, this means before paging_init() has run.
These patches are layered on top of generic fixmap patches which were pulled into upstream 3.14-rc kernels.
This is version 5 of the patch series. These patches fixmap patches
may be found at:
git://github.com/mosalter/linux.git (early-ioremap-v5 branch)
Changes from version 4:
* Dropped arm bits from this series. There is work to be done to support permanent fixmap mappings on ARM and that will be part of a separate arm-only patch series.
* Added Acks for common, x86, and arm64 bits.
Changes from version 3:
* Removed dependency on MMU. In the case of no-MMU, the early remap functions return the address passed in. This helps simplify use of early_ioremap functions on architectures such as ARM which have optional MMU support.
* Added L_PTE_XN to arm page flags so mappings are non-executable.
* Include linux/io.h rather than asm/io.h in arm setup.c
* Moved early_ioremap_init() before setup_machine_fdt() in arm
setup_arch().
* Fixed mispelling in config EARLY_IOREMAP help text.
Changes from version 2:
* Added some Acks
* Incorporated a patch from Dave Young to change the signature of early_memremap() (dropping __iomem from returned pointer) which is the first patch in a larger series:
https://lkml.org/lkml/2013/12/22/69
This allows the change of just the x86 function signature to be bisected.
Changes from version 1:
* Moved the generic code into linux/mm instead of linux/lib
* Have early_memremap() return normal pointer instead of __iomem This is in response to sparse warning cleanups being made in an unrelated patch series:
https://lkml.org/lkml/2013/12/22/69
* Added arm64 patch to call init_mem_pgprot() earlier so that the pgprot macros are valid in time for early_ioremap use
* Added validity checking for early_ioremap pgd, pud, and pmd in arm64
Dave Young (1):
x86/mm: sparse warning fix for early_memremap
Mark Salter (4):
mm: create generic early_ioremap() support
x86: use generic early_ioremap
arm64: initialize pgprot info earlier in boot
arm64: add early_ioremap support
Documentation/arm64/memory.txt | 4 +- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/Kbuild | 1 + arch/arm64/include/asm/fixmap.h | 67 +++++++++ arch/arm64/include/asm/io.h | 1 + arch/arm64/include/asm/memory.h | 2 +- arch/arm64/include/asm/mmu.h | 1 + arch/arm64/kernel/early_printk.c | 8 +- arch/arm64/kernel/head.S | 9 +- arch/arm64/kernel/setup.c | 4 + arch/arm64/mm/ioremap.c | 85 +++++++++++ arch/arm64/mm/mmu.c | 44 +----- arch/x86/Kconfig | 1 + arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/fixmap.h | 6 + arch/x86/include/asm/io.h | 14 +- arch/x86/mm/ioremap.c | 224 +---------------------------- arch/x86/mm/pgtable_32.c | 2 +- include/asm-generic/early_ioremap.h | 42 ++++++ mm/Kconfig | 3 + mm/Makefile | 1 + mm/early_ioremap.c | 271 ++++++++++++++++++++++++++++++++++++ 22 files changed, 503 insertions(+), 289 deletions(-) create mode 100644 arch/arm64/include/asm/fixmap.h create mode 100644 include/asm-generic/early_ioremap.h create mode 100644 mm/early_ioremap.c
Signature · 1 line
1.8.5.3
PATCH 1/5 x86/mm: sparse warning fix for early_memremap
From: Dave Young <[email protected]>
There's a lot of sparse warnings for code like below:
void *a = early_memremap(phys_addr, size);
early_memremap intend to map kernel memory with ioremap facility, the return pointer should be a kernel ram pointer instead of iomem one.
For making the function clearer and supressing sparse warnings this patch do below two things:
1. cast to (__force void *) for the return value of early_memremap
2. add early_memunmap function and pass (__force void __iomem *) to iounmap
Quoted 4 lines
From Boris:
Ingo told me yesterday, it makes sense too. I'd guess we can try it. FWIW, all callers ofearly_memremapuse the memory they get remapped as normal memory so we should be safe.
--- arch/x86/include/asm/io.h | 3 ++- arch/x86/mm/ioremap.c | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-)
arch/x86/include/asm/io.h +2 -1
@@ -325,9 +325,10 @@ extern void early_ioremap_init(void);extern void early_ioremap_reset (void );extern void __iomem *early_ioremap (resource_size_t phys_addr,unsigned long size); -extern void __iomem *early_memremap (resource_size_t phys_addr, +extern void *early_memremap (resource_size_t phys_addr,unsigned long size);extern void early_iounmap (void __iomem *addr,unsigned long size); +extern void early_memunmap (void *addr,unsigned long size);extern void fixup_early_ioremap (void );extern bool is_early_ioremap_ptep (pte_t *ptep);
arch/x86/mm/ioremap.c +7 -3
@@ -562,10 +562,9 @@ early_ioremap(resource_size_t phys_addr, unsigned long size) }/* Remap memory */ -void __init __iomem * -early_memremap (resource_size_t phys_addr,unsigned long size) +void __init *early_memremap (resource_size_t phys_addr,unsigned long size) { -return __early_ioremap (phys_addr, size,PAGE_KERNEL ); +return (__force void *)__early_ioremap (phys_addr, size,PAGE_KERNEL ); }void __init early_iounmap (void __iomem *addr,unsigned long size)
@@ -620,3 +619,8 @@ void __init early_iounmap(void __iomem *addr, unsigned long size) } prev_map[slot] =NULL ; } + +void __init early_memunmap (void *addr,unsigned long size) +{ +early_iounmap ((__force void __iomem *)addr, size); +}
Signature · 1 line
1.8.5.3
PATCH 2/5 mm: create generic early_ioremap() support
In reply to Mark SalterThis patch creates a generic implementation of early_ioremap() support based on the existing x86 implementation. early_ioremp() is useful for early boot code which needs to temporarily map I/O or memory regions before normal mapping functions such as ioremap() are available.
Some architectures have optional MMU. In the no-MMU case, the remap functions simply return the passed in physical address and the unmap functions do nothing.
--- include/asm-generic/early_ioremap.h | 42 ++++++ mm/Kconfig | 3 + mm/Makefile | 1 + mm/early_ioremap.c | 271 ++++++++++++++++++++++++++++++++++++ 4 files changed, 317 insertions(+) create mode 100644 include/asm-generic/early_ioremap.h create mode 100644 mm/early_ioremap.c
include/asm-generic/early_ioremap.h new file +42 -0
@@ -0,0 +1,42 @@ +#ifndef _ASM_EARLY_IOREMAP_H_ +#define _ASM_EARLY_IOREMAP_H_ + +#include <linux/types.h> + +/* +* early_ioremap() and early_iounmap() are for temporary early boot-time +* mappings, before the real ioremap() is functional. +*/ +extern void __iomem *early_ioremap (resource_size_t phys_addr, +unsigned long size); +extern void *early_memremap (resource_size_t phys_addr, +unsigned long size); +extern void early_iounmap (void __iomem *addr,unsigned long size); +extern void early_memunmap (void *addr,unsigned long size); + +/* +* Weak function called by early_ioremap_reset(). It does nothing, but +* architectures may provide their own version to do any needed cleanups. +*/ +extern void early_ioremap_shutdown (void ); + +#if defined(CONFIG_GENERIC_EARLY_IOREMAP ) && defined(CONFIG_MMU ) +/* Arch-specific initialization */ +extern void early_ioremap_init (void ); + +/* Generic initialization called by architecture code */ +extern void early_ioremap_setup (void ); + +/* +* Called as last step in paging_init() so library can act +* accordingly for subsequent map/unmap requests. +*/ +extern void early_ioremap_reset (void ); + +#else +static inline void early_ioremap_init (void ) { } +static inline void early_ioremap_setup (void ) { } +static inline void early_ioremap_reset (void ) { } +#endif + +#endif /* _ASM_EARLY_IOREMAP_H_ */
mm/Kconfig +3 -0
@@ -577,3 +577,6 @@ config PGTABLE_MAPPING You can check speed with zsmalloc benchmark[1]. [1] https://github.com/spartacus06/zsmalloc + +config GENERIC_EARLY_IOREMAP + bool
mm/Makefile +1 -0
@@ -61,3 +61,4 @@ obj-$(CONFIG_CLEANCACHE) += cleancache.o obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o obj-$(CONFIG_ZBUD) += zbud.o obj-$(CONFIG_ZSMALLOC) += zsmalloc.o +obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o
mm/early_ioremap.c new file +271 -0
271 lines not on this page · raw message
Signature · 1 line
1.8.5.3
Andrew Morton
maintainerRe: [PATCH 2/5] mm: create generic early_ioremap() support
Quoted 15 lines · On Tue, 4 Mar 2014 15:08:55 -0500 Mark Salter <[email protected]> wrote:
This patch creates a generic implementation of
early_ioremap()support based on the existing x86 implementation.early_ioremp()is useful for early boot code which needs to temporarily map I/O or memory regions before normal mapping functions such asioremap()are available.Some architectures have optional MMU. In the no-MMU case, the remap functions simply return the passed in physical address and the unmap functions do nothing.
....
mm/early_ioremap.c line 9
Quoted 9 lines
mm/early_ioremap.c new file +9
-0@@ -0,0 +1,271 @@ +/* +* Provide common bits of early_ioremap() support for architectures needing +* temporary mappings during boot before ioremap() is available. +* +* This is mostly a direct copy of the x86 early_ioremap implementation. +* +* (C) Copyright 1995 1996, 2014 Linus Torvalds +* +*/
I suppose one should include linux/kernel.h.
Quoted 8 lines
mm/early_ioremap.c new file +8
-0+#include <linux/init.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <asm/fixmap.h> +
mm/early_ioremap.c line 27
Quoted 10 lines
mm/early_ioremap.c new file +10
-0+#ifdef CONFIG_MMU +static int early_ioremap_debug__initdata ; + +static int __init early_ioremap_debug_setup (char *str) +{ + early_ioremap_debug =1 ; + +return 0 ; +} +early_param ("early_ioremap_debug" , early_ioremap_debug_setup);
Should be documented somewhere. Documentation/kernel-parameters.txt?
mm/early_ioremap.c line 31
Quoted 3 lines
mm/early_ioremap.c new file +3
-0+static int after_paging_init__initdata ; + +void __init __attribute__((weak))early_ioremap_shutdown (void )
__weak
Do __init and __weak work together? They should, but I don't recall seeing it.
Quoted 34 lines
mm/early_ioremap.c new file +31
-0+{ +} + +static void __init __iomem * +__early_ioremap (resource_size_t phys_addr,unsigned long size,pgprot_t prot) +{ +unsigned long offset; +resource_size_t last_addr; +unsigned int nrpages; +enum fixed_addresses idx; +int i, slot; + +WARN_ON (system_state !=SYSTEM_BOOTING ); + + slot =-1 ; +for (i =0 ; i <FIX_BTMAPS_SLOTS ; i++) { +if (!prev_map[i]) { + slot = i; +break ; + } + } + +if (slot <0 ) { +pr_info ("%s(%08llx, %08lx) not found slot\n" , + __func__, (u64 )phys_addr, size); +WARN_ON (1 ); +return NULL ; + } + +if (early_ioremap_debug) { + pr_info("%s(%08llx, %08lx) [%d] => ",
mm/early_ioremap.c line 137
Quoted 10 lines
mm/early_ioremap.c new file +10
-0+ __func__, (u64)phys_addr, size, slot); +dump_stack (); + } + +/* Don't allow wraparound or zero size */ + last_addr = phys_addr + size -1 ; +if (!size || last_addr < phys_addr) { +WARN_ON (1 ); +return NULL ; + }
if (WARN_ON(!size || last_addr < phys_addr)) return NULL;
Quoted 6 lines
mm/early_ioremap.c new file +6
-0+ prev_size[slot] = size; +/* +* Mappings have to be page-aligned +*/ + offset = phys_addr & ~PAGE_MASK ; + phys_addr &=PAGE_MASK ;
mm/early_ioremap.c line 154
Quoted 10 lines
mm/early_ioremap.c new file +10
-0+ size =PAGE_ALIGN (last_addr +1 ) - phys_addr; + +/* +* Mappings have to fit in the FIX_BTMAP area. +*/ + nrpages = size >>PAGE_SHIFT ; +if (nrpages >NR_FIX_BTMAPS ) { +WARN_ON (1 ); +return NULL ; + }
Ditto.
Quoted 32 lines
mm/early_ioremap.c new file +32
-0+/* +* Ok, go for it.. +*/ + idx =FIX_BTMAP_BEGIN -NR_FIX_BTMAPS *slot; +while (nrpages >0 ) { +if (after_paging_init) +__late_set_fixmap (idx, phys_addr, prot); +else +__early_set_fixmap (idx, phys_addr, prot); + phys_addr +=PAGE_SIZE ; + --idx; + --nrpages; + } +if (early_ioremap_debug) +pr_cont ("%08lx + %08lx\n" , offset, slot_virt[slot]); + + prev_map[slot] = (void __iomem *)(offset + slot_virt[slot]); +return prev_map[slot]; +} + +void __init early_iounmap (void __iomem *addr,unsigned long size) +{ +unsigned long virt_addr; +unsigned long offset; +unsigned int nrpages; +enum fixed_addresses idx; +int i, slot; + + slot =-1 ; +for (i =0 ; i <FIX_BTMAPS_SLOTS ; i++) { +if (prev_map[i] == addr) { + slot = i;
mm/early_ioremap.c line 197
Quoted 10 lines
mm/early_ioremap.c new file +10
-0+break ; + } + } + +if (slot <0 ) { +pr_info ("early_iounmap(%p, %08lx) not found slot\n" , + addr, size); +WARN_ON (1 ); +return ; + }
Can we do
if (WARN(slot < 0, "...", addr, size)) return;
here?
And in lots of other places?
mm/early_ioremap.c line 210
Quoted 12 lines
mm/early_ioremap.c new file +12
-0+if (prev_size[slot] != size) { +pr_info ("early_iounmap(%p, %08lx) [%d] size not consistent %08lx\n" , + addr, size, slot, prev_size[slot]); +WARN_ON (1 ); +return ; + } + +if (early_ioremap_debug) { +pr_info ("early_iounmap(%p, %08lx) [%d]\n" , addr, + size, slot); +dump_stack (); + }
That could be a WARN as well.
Quoted 22 lines
mm/early_ioremap.c new file +20
-0+ virt_addr = (unsigned long )addr; +if (virt_addr <fix_to_virt (FIX_BTMAP_BEGIN )) { +WARN_ON (1 ); +return ; + } + offset = virt_addr & ~PAGE_MASK ; + nrpages =PAGE_ALIGN (offset + size) >>PAGE_SHIFT ; + + idx =FIX_BTMAP_BEGIN -NR_FIX_BTMAPS *slot; +while (nrpages >0 ) { +if (after_paging_init) +__late_clear_fixmap (idx); +else +__early_set_fixmap (idx,0 ,FIXMAP_PAGE_CLEAR ); + --idx; + --nrpages; + } + prev_map[slot] =NULL ; +} +
Re: [PATCH 2/5] mm: create generic early_ioremap() support
Quoted 14 lines · Andrew Morton
Quoted 12 lines · On Tue, 4 Mar 2014 15:08:55 -0500 Mark Salter <[email protected]> wrote:
This patch creates a generic implementation of
early_ioremap()support based on the existing x86 implementation.early_ioremp()is useful for early boot code which needs to temporarily map I/O or memory regions before normal mapping functions such asioremap()are available.Some architectures have optional MMU. In the no-MMU case, the remap functions simply return the passed in physical address and the unmap functions do nothing.
....
Quoted 14 lines
mm/early_ioremap.c line 9
Quoted 12 lines
mm/early_ioremap.c new file +9
-0@@ -0,0 +1,271 @@ +/* +* Provide common bits of early_ioremap() support for architectures needing +* temporary mappings during boot before ioremap() is available. +* +* This is mostly a direct copy of the x86 early_ioremap implementation. +* +* (C) Copyright 1995 1996, 2014 Linus Torvalds +* +*/ I suppose one should include
linux/kernel.h.
Okay.
Quoted 13 lines
Quoted 13 lines
mm/early_ioremap.c new file +12
-0+#include <linux/init.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <asm/fixmap.h> + +#ifdef CONFIG_MMU +static int early_ioremap_debug__initdata ; + +static int __init early_ioremap_debug_setup (char *str)
Quoted 8 lines
mm/early_ioremap.c line 27
Quoted 6 lines
mm/early_ioremap.c new file +6
-0+{ + early_ioremap_debug =1 ; + +return 0 ; +} +early_param ("early_ioremap_debug" , early_ioremap_debug_setup);Should be documented somewhere.
Documentation/kernel-parameters.txt?
Okay.
Quoted 9 lines
mm/early_ioremap.c line 31
Quoted 4 lines
mm/early_ioremap.c new file +3
-0+static int after_paging_init__initdata ; + +void __init __attribute__((weak))early_ioremap_shutdown (void )
__weakDo
__initand__weakwork together? They should, but I don't recall seeing it.
Yes. Will use __weak here and clean up the uses of WARN/WARN_ON as noted.
Thanks.
PATCH 3/5 x86: use generic early_ioremap
In reply to Mark SalterMove x86 over to the generic early ioremap implementation.
--- arch/x86/Kconfig | 1 + arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/fixmap.h | 6 ++ arch/x86/include/asm/io.h | 15 +-- arch/x86/mm/ioremap.c | 228 +----------------------------------------- arch/x86/mm/pgtable_32.c | 2 +- 6 files changed, 13 insertions(+), 240 deletions(-)
arch/x86/Kconfig +1 -0
@@ -127,6 +127,7 @@ config X86 select HAVE_DEBUG_STACKOVERFLOW select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 select HAVE_CC_STACKPROTECTOR + select GENERIC_EARLY_IOREMAP config INSTRUCTION_DECODER def_bool y
arch/x86/include/asm/Kbuild +1 -0
@@ -5,3 +5,4 @@ genhdr-y += unistd_64.h genhdr-y += unistd_x32.h generic-y += clkdev.h +generic-y += early_ioremap.h
arch/x86/include/asm/fixmap.h +6 -0
@@ -177,5 +177,11 @@ static inline void __set_fixmap(enum fixed_addresses idx,#include <asm-generic/fixmap.h> +#define __late_set_fixmap (idx, phys, flags) __set_fixmap(idx, phys, flags) +#define __late_clear_fixmap (idx) __set_fixmap(idx, 0, __pgprot(0)) + +void __early_set_fixmap (enum fixed_addresses idx, +phys_addr_t phys,pgprot_t flags); +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_X86_FIXMAP_H */
arch/x86/include/asm/io.h +1 -14
@@ -39,6 +39,7 @@#include <linux/string.h> #include <linux/compiler.h> #include <asm/page.h> +#include <asm/early_ioremap.h> #define build_mmio_read (name, size, type, reg, barrier) \ static inline type name(const volatile void __iomem *addr) \
@@ -316,20 +317,6 @@ extern int ioremap_change_attr(unsigned long vaddr, unsigned long size, unsigned long prot_val);extern void __iomem *ioremap_wc (resource_size_t offset,unsigned long size); -/* -* early_ioremap() and early_iounmap() are for temporary early boot-time -* mappings, before the real ioremap() is functional. -* A boot-time mapping is currently limited to at most 16 pages. -*/ -extern void early_ioremap_init (void ); -extern void early_ioremap_reset (void ); -extern void __iomem *early_ioremap (resource_size_t phys_addr, -unsigned long size); -extern void *early_memremap (resource_size_t phys_addr, -unsigned long size); -extern void early_iounmap (void __iomem *addr,unsigned long size); -extern void early_memunmap (void *addr,unsigned long size); -extern void fixup_early_ioremap (void );extern bool is_early_ioremap_ptep (pte_t *ptep);#ifdef CONFIG_XEN
arch/x86/mm/ioremap.c +3 -225
253 lines not on this page · raw message
arch/x86/mm/pgtable_32.c +1 -1
@@ -127,7 +127,7 @@ static int __init parse_reservetop(char *arg) address =memparse (arg, &arg);reserve_top_address (address); -fixup_early_ioremap (); +early_ioremap_init ();return 0 ; }early_param ("reservetop" , parse_reservetop);
Signature · 1 line
1.8.5.3
PATCH 4/5 arm64: initialize pgprot info earlier in boot
In reply to Mark SalterPresently, paging_init() calls init_mem_pgprot() to initialize pgprot values used by macros such as PAGE_KERNEL, PAGE_KERNEL_EXEC, etc. The new fixmap and early_ioremap support also needs to use these macros before paging_init() is called. This patch moves the init_mem_pgprot() call out of paging_init() and into setup_arch() so that pgprot_default gets initialized in time for fixmap and early_ioremap.
--- arch/arm64/include/asm/mmu.h | 1 + arch/arm64/kernel/setup.c | 2 ++ arch/arm64/mm/mmu.c | 3 +-- 3 files changed, 4 insertions(+), 2 deletions(-)
arch/arm64/include/asm/mmu.h +1 -0
@@ -27,5 +27,6 @@ typedef struct {extern void paging_init (void );extern void setup_mm_for_reboot (void );extern void __iomem *early_io_map (phys_addr_t phys,unsigned long virt); +extern void init_mem_pgprot (void );#endif
arch/arm64/kernel/setup.c +2 -0
@@ -327,6 +327,8 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = boot_command_line; +init_mem_pgprot (); +parse_early_param ();arm64_memblock_init ();
arch/arm64/mm/mmu.c +1 -2
@@ -125,7 +125,7 @@ early_param("cachepolicy", early_cachepolicy);/* * Adjust the PMD section entries according to the CPU in use. */ -static void __init init_mem_pgprot (void ) +void __init init_mem_pgprot (void ) {pteval_t default_pgprot;int i;
@@ -357,7 +357,6 @@ void __init paging_init(void) {void *zero_page; -init_mem_pgprot ();map_mem ();/*
Signature · 1 line
1.8.5.3
PATCH 5/5 arm64: add early_ioremap support
In reply to Mark SalterAdd support for early IO or memory mappings which are needed before the normal ioremap() is usable. This also adds fixmap support for permanent fixed mappings such as that used by the earlyprintk device register region.
--- Documentation/arm64/memory.txt | 4 +- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/Kbuild | 1 + arch/arm64/include/asm/fixmap.h | 67 +++++++++++++++++++++++++++++++ arch/arm64/include/asm/io.h | 1 + arch/arm64/include/asm/memory.h | 2 +- arch/arm64/kernel/early_printk.c | 8 +++- arch/arm64/kernel/head.S | 9 ++--- arch/arm64/kernel/setup.c | 2 + arch/arm64/mm/ioremap.c | 85 ++++++++++++++++++++++++++++++++++++++++ arch/arm64/mm/mmu.c | 41 ------------------- 11 files changed, 169 insertions(+), 52 deletions(-) create mode 100644 arch/arm64/include/asm/fixmap.h
Documentation/arm64/memory.txt +2 -2
@@ -35,7 +35,7 @@ ffffffbc00000000 ffffffbdffffffff 8GB vmemmap ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap] -ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device +ffffffbffbc00000 ffffffbffbdfffff 2MB fixed mappings ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space
@@ -60,7 +60,7 @@ fffffdfc00000000 fffffdfdffffffff 8GB vmemmap fffffdfe00000000 fffffdfffbbfffff ~8GB [guard, future vmmemap] -fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device +fffffdfffbc00000 fffffdfffbdfffff 2MB fixed mappings fffffdfffbe00000 fffffdfffbe0ffff 64KB PCI I/O space
arch/arm64/Kconfig +1 -0
@@ -16,6 +16,7 @@ config ARM64 select DCACHE_WORD_ACCESS select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS_BROADCAST if SMP + select GENERIC_EARLY_IOREMAP select GENERIC_IOMAP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW
arch/arm64/include/asm/Kbuild +1 -0
@@ -10,6 +10,7 @@ generic-y += delay.h generic-y += div64.h generic-y += dma.h generic-y += emergency-restart.h +generic-y += early_ioremap.h generic-y += errno.h generic-y += ftrace.h generic-y += hw_irq.h
arch/arm64/include/asm/fixmap.h new file +67 -0
67 lines not on this page · raw message
arch/arm64/include/asm/io.h +1 -0
@@ -27,6 +27,7 @@#include <asm/byteorder.h> #include <asm/barrier.h> #include <asm/pgtable.h> +#include <asm/early_ioremap.h> #include <xen/xen.h>
arch/arm64/include/asm/memory.h +1 -1
@@ -49,7 +49,7 @@#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1))#define MODULES_END (PAGE_OFFSET)#define MODULES_VADDR (MODULES_END - SZ_64M) -#define EARLYCON_IOBASE (MODULES_VADDR - SZ_4M) +#define FIXADDR_TOP (MODULES_VADDR - SZ_2M - PAGE_SIZE)#define TASK_SIZE_64 (UL(1) << VA_BITS)#ifdef CONFIG_COMPAT
arch/arm64/kernel/early_printk.c +6 -2
@@ -26,6 +26,8 @@#include <linux/amba/serial.h> #include <linux/serial_reg.h> +#include <asm/fixmap.h> +static void __iomem *early_base;static void (*printch)(char ch);
@@ -141,8 +143,10 @@ static int __init setup_early_printk(char *buf) }/* no options parsing yet */ -if (paddr) - early_base =early_io_map (paddr,EARLYCON_IOBASE ); +if (paddr) { +set_fixmap_io (FIX_EARLYCON , paddr); + early_base = (void __iomem *)fix_to_virt (FIX_EARLYCON ); + } printch = match->printch; early_console = &early_console_dev;
arch/arm64/kernel/head.S +3 -6
@@ -412,7 +412,7 @@ ENDPROC(__calc_phys_offset) * - identity mapping to enable the MMU (low address, TTBR0) * - first few MB of the kernel linear mapping to jump to once the MMU has * been enabled, including the FDT blob (TTBR1) - * - UART mapping if CONFIG_EARLY_PRINTK is enabled (TTBR1) + * - pgd entry for fixed mappings (TTBR1) */ __create_page_tables: pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses
@@ -465,15 +465,12 @@ __create_page_tables: sub x6, x6, #1 // inclusive range create_block_map x0, x7, x3, x5, x6 1: -#ifdef CONFIG_EARLY_PRINTK /* - * Create the pgd entry for the UART mapping. The full mapping is done - * later based earlyprintk kernel parameter. + * Create the pgd entry for the fixed mappings. */ - ldr x5, =EARLYCON_IOBASE // UART virtual address + ldr x5, =FIXADDR_TOP // Fixed mapping virtual address add x0, x26, #2 * PAGE_SIZE // section table address create_pgd_entry x26, x0, x5, x6, x7 -#endif ret ENDPROC(__create_page_tables) .ltorg
arch/arm64/kernel/setup.c +2 -0
@@ -42,6 +42,7 @@#include <linux/of_fdt.h> #include <linux/of_platform.h> +#include <asm/fixmap.h> #include <asm/cputype.h> #include <asm/elf.h> #include <asm/cputable.h>
@@ -328,6 +329,7 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = boot_command_line;init_mem_pgprot (); +early_ioremap_init ();parse_early_param ();
arch/arm64/mm/ioremap.c +85 -0
94 lines not on this page · raw message
arch/arm64/mm/mmu.c +0 -41
47 lines not on this page · raw message
Signature · 1 line
1.8.5.3
Re: [PATCH 5/5] arm64: add early_ioremap support
Quoted 4 lines · Mark Salter
Add support for early IO or memory mappings which are needed before the normal
ioremap()is usable. This also adds fixmap support for permanent fixed mappings such as that used by the earlyprintk device register region.
One minor comment:
arch/arm64/include/asm/fixmap.h line 34
Quoted 2 lines
arch/arm64/include/asm/fixmap.h new file +2
-0+enum fixed_addresses { +FIX_EARLYCON ,
Can you align this name with x86 and rename to FIX_EARLYCON_MEM_BASE. Doing that will help enable the earlycon driver in 8250_early.c.
Rob
Re: [PATCH 5/5] arm64: add early_ioremap support
Quoted 6 lines · Rob Herring
Quoted 4 lines · Mark Salter
Add support for early IO or memory mappings which are needed before the normal
ioremap()is usable. This also adds fixmap support for permanent fixed mappings such as that used by the earlyprintk device register region.
Quoted 7 lines
One minor comment:
arch/arm64/include/asm/fixmap.h line 34
Quoted 2 lines
arch/arm64/include/asm/fixmap.h new file +2
-0+enum fixed_addresses { +FIX_EARLYCON ,Can you align this name with x86 and rename to
FIX_EARLYCON_MEM_BASE. Doing that will help enable the earlycon driver in8250_early.c.
Is there any advantage to earlycon=uart8250 vs. earlyprintk=uart8250? I don't mind using FIX_EARLYCON_MEM_BASE, but CONFIG_FIX_EARLYCON_MEM is X86 only right now and I think changing that should be a separate patch.
Re: [PATCH 5/5] arm64: add early_ioremap support
Quoted 9 lines · Mark Salter
Quoted 8 lines · Rob Herring
Quoted 4 lines · Mark Salter
Add support for early IO or memory mappings which are needed before the normal
ioremap()is usable. This also adds fixmap support for permanent fixed mappings such as that used by the earlyprintk device register region.One minor comment:
Quoted 7 lines
Quoted 5 lines
arch/arm64/include/asm/fixmap.h line 34
Quoted 2 lines
arch/arm64/include/asm/fixmap.h new file +2
-0+enum fixed_addresses { +FIX_EARLYCON ,Can you align this name with x86 and rename to
FIX_EARLYCON_MEM_BASE. Doing that will help enable the earlycon driver in8250_early.c.Is there any advantage to earlycon=uart8250 vs. earlyprintk=uart8250?
Functionally, they are pretty much the same. I'm working on a series to generalize earlycon and then we will be able to delete early_printk.c from arm64 and ultimately share with arm. Doing this alignment just saves a patch to change it later.
Quoted 3 lines
I don't mind using
FIX_EARLYCON_MEM_BASE, butCONFIG_FIX_EARLYCON_MEMis X86 only right now and I think changing that should be a separate patch.
Yes, definitely.
Rob