diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2015-05-29 14:09:37 +0200 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2015-05-29 14:09:37 +0200 |
commit | caacb7d519ddf0c697ae20a9c55c6c0aed4b4a61 (patch) | |
tree | 22bc35b84a1b20a1f8d240d7dc1a635bb0a6fd3d /arch/arm | |
parent | 271ce8a33c6368ca81d075f1fea7b1deadb69aaa (diff) |
imx-common: m4boot: allow to boot other OS'es using m4boot
Allow to boot eCos, MQX and bare-metal firmwares to boot on the
secondary Cortex-M4. The boot code is equal for all those firmware
types, the argument register will be set to 0 and the code will
jump to the specified entry point directly.
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/imx-common/cmd_m4boot.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/arch/arm/imx-common/cmd_m4boot.c b/arch/arm/imx-common/cmd_m4boot.c index 76be8a25e6f..e30a5686c24 100644 --- a/arch/arm/imx-common/cmd_m4boot.c +++ b/arch/arm/imx-common/cmd_m4boot.c @@ -25,10 +25,17 @@ DECLARE_GLOBAL_DATA_PTR; extern unsigned char _binary_arch_arm_imx_common_vf610m4bootldr_start; extern unsigned char _binary_arch_arm_imx_common_vf610m4bootldr_end; +static void boot_startm4(void) +{ + struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR; + + /* Gate Cortex-M4 clock... */ + writel(CCM_CCOWR_START, &ccm->ccowr); +} + static void boot_startm4_linux(bootm_headers_t *images) { struct src *src = (struct src *)SRC_BASE_ADDR; - struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR; int size = &_binary_arch_arm_imx_common_vf610m4bootldr_end - &_binary_arch_arm_imx_common_vf610m4bootldr_start; ulong ep_loader = images->ep - size; @@ -47,8 +54,24 @@ static void boot_startm4_linux(bootm_headers_t *images) flush_dcache_all(); - /* Gate Cortex-M4 clock... */ - writel(CCM_CCOWR_START, &ccm->ccowr); + boot_startm4(); +} + +static void boot_startm4_generic(bootm_headers_t *images) +{ + struct src *src = (struct src *)SRC_BASE_ADDR; + + printf("Booting Cortex-M4 @0x%08lx\n", images->ep); + + /* Write entry point to GPR2 (PERSISTENT_ENTRY1) */ + writel(images->ep, &src->gpr2); + + /* Write fdt offset to GPR3 (PERSISTENT_ARG1) */ + writel(0, &src->gpr3); + + flush_dcache_all(); + + boot_startm4(); } static int fdt_chosenm4(void *fdt) @@ -188,7 +211,10 @@ static int do_m4boot(cmd_tbl_t *cmdtp, int flag, int argc, return 1; } - boot_startm4_linux(&images); + if (images.os.os == IH_OS_LINUX) + boot_startm4_linux(&images); + else + boot_startm4_generic(&images); return 1; } |