diff options
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/common.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/include/mach/barebox-arm-head.h | 54 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/include/mach/common.h | 17 |
4 files changed, 75 insertions, 3 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e4663ea268..6d38218814 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -123,6 +123,7 @@ config ARCH_MVEBU select GPIOLIB select HAS_DEBUG_LL select HAVE_DEFAULT_ENVIRONMENT_NEW + select HAVE_MACH_ARM_HEAD select HAVE_PBL_MULTI_IMAGES select HW_HAS_PCI select MVEBU_MBUS diff --git a/arch/arm/mach-mvebu/common.c b/arch/arm/mach-mvebu/common.c index 7534d8dd01..06bfb72615 100644 --- a/arch/arm/mach-mvebu/common.c +++ b/arch/arm/mach-mvebu/common.c @@ -180,14 +180,14 @@ mem_initcall(mvebu_meminit); * safely later on, as the remap register itself is within the * internal registers. */ -#define MVEBU_BOOTUP_INT_REG_BASE 0xd0000000 #define MVEBU_BRIDGE_REG_BASE 0x20000 #define DEVICE_INTERNAL_BASE_ADDR (MVEBU_BRIDGE_REG_BASE + 0x80) static void mvebu_remap_registers(void) { - writel(MVEBU_REMAP_INT_REG_BASE, - IOMEM(MVEBU_BOOTUP_INT_REG_BASE) + DEVICE_INTERNAL_BASE_ADDR); + void __iomem *base = mvebu_get_initial_int_reg_base(); + + writel(MVEBU_REMAP_INT_REG_BASE, base + DEVICE_INTERNAL_BASE_ADDR); } void __naked __noreturn dove_barebox_entry(void *boarddata) diff --git a/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h b/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h new file mode 100644 index 0000000000..3035f40ddf --- /dev/null +++ b/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h @@ -0,0 +1,54 @@ +#include <linux/stringify.h> +#include <mach/common.h> + +static inline void __barebox_arm_head(void) +{ + __asm__ __volatile__ ( +#ifdef CONFIG_THUMB2_BAREBOX + ".arm\n" + "adr r9, 1f + 1\n" + "bx r9\n" + ".thumb\n" + "1:\n" + "bl 2f\n" + ".rept 10\n" + "1: b 1b\n" + ".endr\n" +#else + "b 2f\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" +#endif + ".asciz \"barebox\"\n" + ".word _text\n" /* text base. If copied there, + * barebox can skip relocation + */ + ".word _barebox_image_size\n" /* image size to copy */ + + /* + * The following entry (at offset 0x30) is the only intended + * difference to the original arm __barebox_arm_head. This value + * holds the address of the internal register window when the + * image is started. If the window is not at the reset default + * position any more the caller can pass the actual value here. + */ + ".word " __stringify(MVEBU_BOOTUP_INT_REG_BASE) "\n" + ".rept 7\n" + ".word 0x55555555\n" + ".endr\n" + "2:\n" + ); +} + +static inline void barebox_arm_head(void) +{ + __barebox_arm_head(); + __asm__ __volatile__ ( + "b barebox_arm_reset_vector\n" + ); +} diff --git a/arch/arm/mach-mvebu/include/mach/common.h b/arch/arm/mach-mvebu/include/mach/common.h index 3cc1bf71c0..529eb61cfd 100644 --- a/arch/arm/mach-mvebu/include/mach/common.h +++ b/arch/arm/mach-mvebu/include/mach/common.h @@ -18,6 +18,23 @@ #ifndef __MACH_COMMON_H__ #define __MACH_COMMON_H__ +#include <asm/sections.h> +#include <asm/unaligned.h> + +#define MVEBU_BOOTUP_INT_REG_BASE 0xd0000000 #define MVEBU_REMAP_INT_REG_BASE 0xf1000000 +/* #including <asm/barebox-arm.h> yields a circle, so we need a forward decl */ +uint32_t get_runtime_offset(void); + +static inline void __iomem *mvebu_get_initial_int_reg_base(void) +{ +#ifdef __PBL__ + u32 base = __get_unaligned_le32(_text - get_runtime_offset() + 0x30); + return (void __force __iomem *)base; +#else + return (void __force __iomem *)MVEBU_REMAP_INT_REG_BASE; +#endif +} + #endif |