summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2015-05-29 14:09:37 +0200
committerStefan Agner <stefan.agner@toradex.com>2015-05-29 14:09:37 +0200
commitcaacb7d519ddf0c697ae20a9c55c6c0aed4b4a61 (patch)
tree22bc35b84a1b20a1f8d240d7dc1a635bb0a6fd3d /arch
parent271ce8a33c6368ca81d075f1fea7b1deadb69aaa (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')
-rw-r--r--arch/arm/imx-common/cmd_m4boot.c34
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 76be8a25e6..e30a5686c2 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;
}