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 | |
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.
-rw-r--r-- | arch/arm/imx-common/cmd_m4boot.c | 34 | ||||
-rw-r--r-- | common/image-fit.c | 8 |
2 files changed, 34 insertions, 8 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; } diff --git a/common/image-fit.c b/common/image-fit.c index 778d2a148be..368b730ded0 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1640,11 +1640,11 @@ int fit_image_load(bootm_headers_t *images, ulong addr, fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD)); - os_ok = image_type == IH_TYPE_FLATDT || - fit_image_check_os(fit, noffset, IH_OS_LINUX) || - fit_image_check_os(fit, noffset, IH_OS_OPENRTOS); + fit_image_get_os(fit, noffset, &os); + os_ok = image_type == IH_TYPE_FLATDT || os == IH_OS_LINUX || + os == IH_OS_OPENRTOS || os == IH_OS_ECOS || + os == IH_OS_MQX || os == IH_OS_BAREMETAL; if (!type_ok || !os_ok) { - fit_image_get_os(fit, noffset, &os); printf("No %s %s %s Image\n", genimg_get_os_name(os), genimg_get_arch_name(arch), |