Re: [PATCH RFC] ARM: early fixmap support for earlycon

2014-12-27 Thread Rob Herring
On Sat, Dec 27, 2014 at 3:08 PM, Stefan Agner  wrote:

Thanks for picking this up.

> Add early fixmap support, initially to support permanent, fixed
> mapping support for early console. A temporary, early pte is
> created which is migrated to a permanent mapping in paging_init.
> This is also needed since the attributs may change as the memory

s/attributs/attributes/

I would like to fix this problem. I think it can be if we setup
memtype table earlier. The complication is some of it is dependent on
cache_policy. The device memory types don't depend on cache_policy, so
they could be setup early and used. I think that can all be done after
this patch.

> types are initialized. The 3MiB range of fixmap spans two pte
> tables, but currently only one pte is created for early fixmap
> support.
>
> Readd FIX_KMAP_BEGIN to the index calculation in highmem.c since

s/Readd/Re-add/

> the index for kmap does not start at zero anymore. This reverts
> 4221e2e6b316 ("ARM: 8031/1: fixmap: remove FIX_KMAP_BEGIN and
> FIX_KMAP_END") to some extends.

s/extends/extent/

>
> Cc: Mark Salter 
> Cc: Russell King 
> Cc: Rob Herring 
> Cc: Kees Cook 
> Cc: Laura Abbott 
> Cc: Arnd Bergmann 
> Signed-off-by: Stefan Agner 
> ---
> While trying to implement earlycon support on Vybrid SoC, it
> turned out that set_fixmap does not support calls at that early
> stage. This patch picks up code/ideas from Rob's and Mark's
> patches supporting early_ioremap and fixmap support from Rob's
> git tree. This patch only adds the necessary bits to extend
> fixmap API for earlycon.
> https://git.kernel.org/cgit/linux/kernel/git/robh/linux.git/log/?h=arm-fixmap

Given, I wrote some of this, feel free to add my SOB. It all looks
good to me. One minor spelling error below though.

It would be nice if you could re-factor the early_ioremap support on
top of this, too.

> Also aligned the implementation somewhat how it is done for arm64
> in Laura's patch af86e5974d30 ("arm64: Factor out fixmap
> initialization from ioremap").
>
> Tested with CONFIG_DEBUG_SET_MODULE_RONX which makes use of fixmap
> support too.
>
>  arch/arm/Kconfig  |  3 ++
>  arch/arm/include/asm/fixmap.h | 13 +++-
>  arch/arm/kernel/setup.c   |  3 ++
>  arch/arm/mm/highmem.c |  6 ++--
>  arch/arm/mm/mmu.c | 76 
> +--
>  5 files changed, 94 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 97d07ed..3a73cca 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -183,6 +183,9 @@ config ARCH_HAS_ILOG2_U64
>  config ARCH_HAS_BANDGAP
> bool
>
> +config FIX_EARLYCON_MEM
> +   def_bool y
> +
>  config GENERIC_HWEIGHT
> bool
> default y
> diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
> index 0415eae..2d8b12b 100644
> --- a/arch/arm/include/asm/fixmap.h
> +++ b/arch/arm/include/asm/fixmap.h
> @@ -6,9 +6,13 @@
>  #define FIXADDR_TOP(FIXADDR_END - PAGE_SIZE)
>
>  #include 
> +#include 
>
>  enum fixed_addresses {
> -   FIX_KMAP_BEGIN,
> +   FIX_EARLYCON_MEM_BASE,
> +   __end_of_permanent_fixed_addresses,
> +
> +   FIX_KMAP_BEGIN = __end_of_permanent_fixed_addresses,
> FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
>
> /* Support writing RO kernel text via kprobes, jump labels, etc. */
> @@ -18,7 +22,14 @@ enum fixed_addresses {
> __end_of_fixed_addresses
>  };
>
> +#define FIXMAP_PAGE_COMMON (L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN | 
> L_PTE_DIRTY)
> +
> +#define FIXMAP_PAGE_NORMAL (FIXMAP_PAGE_COMMON | L_PTE_MT_WRITEBACK)
> +#define FIXMAP_PAGE_IO (FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_SHARED | 
> L_PTE_SHARED)
> +#define FIXMAP_PAGE_NOCACHEFIXMAP_PAGE_IO
> +
>  void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
> +void __init early_fixmap_init(void);
>
>  #include 
>
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index f9c8639..015eade 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -37,6 +37,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -916,6 +917,8 @@ void __init setup_arch(char **cmdline_p)
> strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
> *cmdline_p = cmd_line;
>
> +   early_fixmap_init();
> +
> parse_early_param();
>
> early_paging_init(mdesc, lookup_processor_type(read_cpuid_id()));
> diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
> index b98895d..c7097f9 100644
> --- a/arch/arm/mm/highmem.c
> +++ b/arch/arm/mm/highmem.c
> @@ -78,7 +78,7 @@ void *kmap_atomic(struct page *page)
>
> type = kmap_atomic_idx_push();
>
> -   idx = type + KM_TYPE_NR * smp_processor_id();
> +   idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
> vaddr = __fix_to_virt(idx);
>  #ifdef CONFIG_DEBUG_HIGHMEM
> /*
> @@ -

[PATCH RFC] ARM: early fixmap support for earlycon

2014-12-27 Thread Stefan Agner
Add early fixmap support, initially to support permanent, fixed
mapping support for early console. A temporary, early pte is
created which is migrated to a permanent mapping in paging_init.
This is also needed since the attributs may change as the memory
types are initialized. The 3MiB range of fixmap spans two pte
tables, but currently only one pte is created for early fixmap
support.

Readd FIX_KMAP_BEGIN to the index calculation in highmem.c since
the index for kmap does not start at zero anymore. This reverts
4221e2e6b316 ("ARM: 8031/1: fixmap: remove FIX_KMAP_BEGIN and
FIX_KMAP_END") to some extends.

Cc: Mark Salter 
Cc: Russell King 
Cc: Rob Herring 
Cc: Kees Cook 
Cc: Laura Abbott 
Cc: Arnd Bergmann 
Signed-off-by: Stefan Agner 
---
While trying to implement earlycon support on Vybrid SoC, it
turned out that set_fixmap does not support calls at that early
stage. This patch picks up code/ideas from Rob's and Mark's
patches supporting early_ioremap and fixmap support from Rob's
git tree. This patch only adds the necessary bits to extend
fixmap API for earlycon.
https://git.kernel.org/cgit/linux/kernel/git/robh/linux.git/log/?h=arm-fixmap

Also aligned the implementation somewhat how it is done for arm64
in Laura's patch af86e5974d30 ("arm64: Factor out fixmap
initialization from ioremap").

Tested with CONFIG_DEBUG_SET_MODULE_RONX which makes use of fixmap
support too.

 arch/arm/Kconfig  |  3 ++
 arch/arm/include/asm/fixmap.h | 13 +++-
 arch/arm/kernel/setup.c   |  3 ++
 arch/arm/mm/highmem.c |  6 ++--
 arch/arm/mm/mmu.c | 76 +--
 5 files changed, 94 insertions(+), 7 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed..3a73cca 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -183,6 +183,9 @@ config ARCH_HAS_ILOG2_U64
 config ARCH_HAS_BANDGAP
bool
 
+config FIX_EARLYCON_MEM
+   def_bool y
+
 config GENERIC_HWEIGHT
bool
default y
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index 0415eae..2d8b12b 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -6,9 +6,13 @@
 #define FIXADDR_TOP(FIXADDR_END - PAGE_SIZE)
 
 #include 
+#include 
 
 enum fixed_addresses {
-   FIX_KMAP_BEGIN,
+   FIX_EARLYCON_MEM_BASE,
+   __end_of_permanent_fixed_addresses,
+
+   FIX_KMAP_BEGIN = __end_of_permanent_fixed_addresses,
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
 
/* Support writing RO kernel text via kprobes, jump labels, etc. */
@@ -18,7 +22,14 @@ enum fixed_addresses {
__end_of_fixed_addresses
 };
 
+#define FIXMAP_PAGE_COMMON (L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN | 
L_PTE_DIRTY)
+
+#define FIXMAP_PAGE_NORMAL (FIXMAP_PAGE_COMMON | L_PTE_MT_WRITEBACK)
+#define FIXMAP_PAGE_IO (FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_SHARED | 
L_PTE_SHARED)
+#define FIXMAP_PAGE_NOCACHEFIXMAP_PAGE_IO
+
 void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
+void __init early_fixmap_init(void);
 
 #include 
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index f9c8639..015eade 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -916,6 +917,8 @@ void __init setup_arch(char **cmdline_p)
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
*cmdline_p = cmd_line;
 
+   early_fixmap_init();
+
parse_early_param();
 
early_paging_init(mdesc, lookup_processor_type(read_cpuid_id()));
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index b98895d..c7097f9 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -78,7 +78,7 @@ void *kmap_atomic(struct page *page)
 
type = kmap_atomic_idx_push();
 
-   idx = type + KM_TYPE_NR * smp_processor_id();
+   idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
/*
@@ -105,7 +105,7 @@ void __kunmap_atomic(void *kvaddr)
 
if (kvaddr >= (void *)FIXADDR_START) {
type = kmap_atomic_idx();
-   idx = type + KM_TYPE_NR * smp_processor_id();
+   idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
 
if (cache_is_vivt())
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
@@ -135,7 +135,7 @@ void *kmap_atomic_pfn(unsigned long pfn)
return page_address(page);
 
type = kmap_atomic_idx_push();
-   idx = type + KM_TYPE_NR * smp_processor_id();
+   idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(!pte_none(get_fixmap_pte(vaddr)));
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index cda7c40..d1f70dd 100644
--- a/arch