"Mark A. Greer" <[email protected]> writes:

> From: Lennert Buytenhek <[email protected]>
>
> On the Cirrus Logic ep93xx, system RAM isn't one nice physically
> contiguous region as it is on most SoCs, but it is spread out over
> between one and four memory banks.
>
> What's worse, RAM doesn't necessarily start at any fixed physical
> memory location. The start of RAM (PHYS_OFFSET) is not only board-
> specific, but on some boards also depends on jumper settings (whether
> async or sync boot mode is selected.)
>
> The attached patch adds the RUNTIME_PHYS_OFFSET config option, which,
> if selected, turns PHYS_OFFSET into a variable which is determined and
> set by __create_page_tables by looking at the current pc. This allows
> booting a single kernel image on all the different flavors of ep93xx
> boards. If the option isn't selected, there's zero impact.
>
> Signed-off-by: Lennert Buytenhek <[email protected]>
> Signed-off-by: Steve Chen <[email protected]>
> Signed-off-by: Mark A. Greer <[email protected]>

I think this one should go to l-a-k again.  Maybe with a request from
yet another source, RMK will accept it.

Kevin

> ---
>  arch/arm/Kconfig                           |    4 +++
>  arch/arm/boot/compressed/Makefile          |    9 ++----
>  arch/arm/boot/compressed/head.S            |    6 ++++
>  arch/arm/include/asm/memory.h              |    8 ++++++
>  arch/arm/kernel/head.S                     |   38 +++++++++++++++++++--------
>  arch/arm/kernel/setup.c                    |   14 +++++++++-
>  arch/arm/mach-ep93xx/Makefile.boot         |    1 -
>  arch/arm/mach-ep93xx/include/mach/memory.h |    2 +
>  8 files changed, 63 insertions(+), 19 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 9bf3cb0..4043f02 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -188,6 +188,9 @@ config VECTORS_BASE
>       help
>         The base address of exception vectors.
>  
> +config RUNTIME_PHYS_OFFSET
> +     bool
> +
>  source "init/Kconfig"
>  
>  source "kernel/Kconfig.freezer"
> @@ -272,6 +275,7 @@ config ARCH_EP93XX
>       select HAVE_CLK
>       select COMMON_CLKDEV
>       select ARCH_REQUIRE_GPIOLIB
> +     select RUNTIME_PHYS_OFFSET
>       help
>         This enables support for the Cirrus EP93xx series of CPUs.
>  
> diff --git a/arch/arm/boot/compressed/Makefile 
> b/arch/arm/boot/compressed/Makefile
> index fbe5eef..b0d7771 100644
> --- a/arch/arm/boot/compressed/Makefile
> +++ b/arch/arm/boot/compressed/Makefile
> @@ -74,13 +74,10 @@ endif
>  EXTRA_CFLAGS  := -fpic -fno-builtin
>  EXTRA_AFLAGS  := -Wa,-march=all
>  
> -# Supply ZRELADDR, INITRD_PHYS and PARAMS_PHYS to the decompressor via
> -# linker symbols.  We only define initrd_phys and params_phys if the
> -# machine class defined the corresponding makefile variable.
> +# Supply ZRELADDR and PARAMS_PHYS to the decompressor via linker
> +# symbols.  We only define params_phys if the machine class defined
> +# the corresponding makefile variable.
>  LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR)
> -ifneq ($(INITRD_PHYS),)
> -LDFLAGS_vmlinux += --defsym initrd_phys=$(INITRD_PHYS)
> -endif
>  ifneq ($(PARAMS_PHYS),)
>  LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS)
>  endif
> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index 77d6142..e19623c 100644
> --- a/arch/arm/boot/compressed/head.S
> +++ b/arch/arm/boot/compressed/head.S
> @@ -156,6 +156,12 @@ not_angel:
>               .text
>               adr     r0, LC0
>               ldmia   r0, {r1, r2, r3, r4, r5, r6, ip, sp}
> +#ifdef CONFIG_RUNTIME_PHYS_OFFSET
> +             and     r10, pc, #0xf0000000    @ fix up zreladdr
> +             and     r4, r4, #0x0fffffff
> +             add     r4, r4, r10
> +#endif
> +
>               subs    r0, r0, r1              @ calculate the delta offset
>  
>                                               @ if delta is zero, we are
> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
> index 0202a7c..04be0b5 100644
> --- a/arch/arm/include/asm/memory.h
> +++ b/arch/arm/include/asm/memory.h
> @@ -63,6 +63,14 @@
>   */
>  #define IOREMAP_MAX_ORDER    24
>  
> +/*
> + * PHYS_OFFSET determined at run time?
> + */
> +#if defined(CONFIG_RUNTIME_PHYS_OFFSET) && !defined(__ASSEMBLY__)
> +extern unsigned long phys_offset;
> +#define PHYS_OFFSET          (phys_offset)
> +#endif
> +
>  #else /* CONFIG_MMU */
>  
>  /*
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index 21e17dc..9f70d0a 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -22,12 +22,13 @@
>  #include <asm/thread_info.h>
>  #include <asm/system.h>
>  
> +#ifndef CONFIG_RUNTIME_PHYS_OFFSET
>  #if (PHYS_OFFSET & 0x001fffff)
>  #error "PHYS_OFFSET must be at an even 2MiB boundary!"
>  #endif
> +#endif
>  
>  #define KERNEL_RAM_VADDR     (PAGE_OFFSET + TEXT_OFFSET)
> -#define KERNEL_RAM_PADDR     (PHYS_OFFSET + TEXT_OFFSET)
>  
>  
>  /*
> @@ -44,8 +45,8 @@
>       .globl  swapper_pg_dir
>       .equ    swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
>  
> -     .macro  pgtbl, rd
> -     ldr     \rd, =(KERNEL_RAM_PADDR - 0x4000)
> +     .macro  pgtbl, rd, phys_offset
> +     add     \rd, \phys_offset, #(TEXT_OFFSET - 0x4000)
>       .endm
>  
>  #ifdef CONFIG_XIP_KERNEL
> @@ -210,9 +211,26 @@ ENDPROC(__turn_mmu_on)
>   * Returns:
>   *  r0, r3, r6, r7 corrupted
>   *  r4 = physical page table address
> + *  r5 = PHYS_OFFSET
>   */
>  __create_page_tables:
> -     pgtbl   r4                              @ page table address
> +#ifdef CONFIG_RUNTIME_PHYS_OFFSET
> +     adr     r5, stext
> +     sub     r5, r5, #TEXT_OFFSET            @ r5 = phys_offset
> +     ldr     r4, =0xfff00000
> +     and     r5, r5, r4
> +
> +     ldr     r4, =(phys_offset - PAGE_OFFSET)
> +     add     r4, r4, r5
> +     str     r5, [r4]                        @ save phys_offset
> +#else
> +     mov     r5, #(PHYS_OFFSET & 0xff000000)
> +     .if     (PHYS_OFFSET & 0x00f00000)
> +     orr     r5, r5, #(PHYS_OFFSET & 0x00f00000)
> +     .endif
> +#endif
> +
> +     pgtbl   r4, r5                          @ r4 = page table address
>  
>       /*
>        * Clear the 16K level 1 swapper page table
> @@ -257,10 +275,11 @@ __create_page_tables:
>       /*
>        * Map some ram to cover our .data and .bss areas.
>        */
> -     orr     r3, r7, #(KERNEL_RAM_PADDR & 0xff000000)
> -     .if     (KERNEL_RAM_PADDR & 0x00f00000)
> -     orr     r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
> +     add     r3, r5, #(TEXT_OFFSET & 0xff000000)     @ r5 = PHYS_OFFSET
> +     .if     (TEXT_OFFSET & 0x00f00000)
> +     add     r3, r3, #(TEXT_OFFSET & 0x00f00000)
>       .endif
> +     orr     r3, r3, r7
>       add     r0, r4,  #(KERNEL_RAM_VADDR & 0xff000000) >> 18
>       str     r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
>       ldr     r6, =(_end - 1)
> @@ -276,10 +295,7 @@ __create_page_tables:
>        * Then map first 1MB of ram in case it contains our boot params.
>        */
>       add     r0, r4, #PAGE_OFFSET >> 18
> -     orr     r6, r7, #(PHYS_OFFSET & 0xff000000)
> -     .if     (PHYS_OFFSET & 0x00f00000)
> -     orr     r6, r6, #(PHYS_OFFSET & 0x00f00000)
> -     .endif
> +     orr     r6, r7, r5
>       str     r6, [r0]
>  
>  #ifdef CONFIG_DEBUG_LL
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index 7049815..99c2a53 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -63,6 +63,16 @@ __setup("fpe=", fpe_setup);
>  extern void paging_init(struct machine_desc *desc);
>  extern void reboot_setup(char *str);
>  
> +#ifdef CONFIG_RUNTIME_PHYS_OFFSET
> +/*
> + * The assignment is here solely to prevent this variable from ending
> + * up in bss.  As the early startup code writes to it, we don't want it
> + * to be zeroed again later.
> + */
> +unsigned long phys_offset = 0xdeadbeef;
> +EXPORT_SYMBOL(phys_offset);
> +#endif
> +
>  unsigned int processor_id;
>  EXPORT_SYMBOL(processor_id);
>  unsigned int __machine_arch_type;
> @@ -663,7 +673,7 @@ static struct init_tags {
>       { tag_size(tag_core), ATAG_CORE },
>       { 1, PAGE_SIZE, 0xff },
>       { tag_size(tag_mem32), ATAG_MEM },
> -     { MEM_SIZE, PHYS_OFFSET },
> +     { MEM_SIZE, 0 },
>       { 0, ATAG_NONE }
>  };
>  
> @@ -684,6 +694,8 @@ void __init setup_arch(char **cmdline_p)
>       struct machine_desc *mdesc;
>       char *from = default_command_line;
>  
> +     init_tags.mem.start = PHYS_OFFSET;
> +
>       setup_processor();
>       mdesc = setup_machine(machine_arch_type);
>       machine_name = mdesc->name;
> diff --git a/arch/arm/mach-ep93xx/Makefile.boot 
> b/arch/arm/mach-ep93xx/Makefile.boot
> index d5561ad..574a4aa 100644
> --- a/arch/arm/mach-ep93xx/Makefile.boot
> +++ b/arch/arm/mach-ep93xx/Makefile.boot
> @@ -1,2 +1 @@
>     zreladdr-y        := 0x00008000
> -params_phys-y        := 0x00000100
> diff --git a/arch/arm/mach-ep93xx/include/mach/memory.h 
> b/arch/arm/mach-ep93xx/include/mach/memory.h
> index 5c80c3c..66e3b68 100644
> --- a/arch/arm/mach-ep93xx/include/mach/memory.h
> +++ b/arch/arm/mach-ep93xx/include/mach/memory.h
> @@ -5,6 +5,8 @@
>  #ifndef __ASM_ARCH_MEMORY_H
>  #define __ASM_ARCH_MEMORY_H
>  
> +#ifndef CONFIG_RUNTIME_PHYS_OFFSET
>  #define PHYS_OFFSET          UL(0x00000000)
> +#endif
>  
>  #endif
> -- 
> 1.6.0.3
>
>
> _______________________________________________
> Davinci-linux-open-source mailing list
> [email protected]
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to