imx-common: include mini-loader vf610m4bootldr 2015.04-toradex-next-m4boot
authorStefan Agner <stefan@agner.ch>
Sun, 17 May 2015 19:53:16 +0000 (21:53 +0200)
committerStefan Agner <stefan@agner.ch>
Fri, 22 May 2015 22:49:29 +0000 (00:49 +0200)
Include vf610m4bootldr, a mini boot loader for the Cortex-M4 CPU
inside Freescale Vybrid SoC. The mini loader enables caches and
copies the pointer to the device tree from the platform specific
argument register (PERSISTENT_ARG1) to the Cortex-M4 r2 register,
where the Linux kernel expects the pointer. The mini loader hence
essentially takes over the parts of the m4boot command which can
not be done from the Cortex-A5 main CPU.

arch/arm/imx-common/Makefile
arch/arm/imx-common/cmd_m4boot.c
arch/arm/imx-common/vf610m4bootldr.S [new file with mode: 0644]

index 175a36339d065b8cf0c491e90aedcad114adf52a..64959fb4aed3be09b2be615f96bf5d2fac3cd34c 100644 (file)
@@ -24,6 +24,26 @@ obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o
 endif
 ifeq ($(SOC),$(filter $(SOC),vf610))
 obj-y += ddrmc-vf610.o
+
+# The mini boot loader for Linux on the Cortex-M4 runs on ARMv7-M
+# architecture, hence force ARMv7-M architecture. Use objcopy with
+# binary-architecture (-B) to include the mini loader as binary blob
+quiet_cmd_ccm4_s_S = M4CC    $@
+cmd_ccm4_s_S       = $(CC) -Wall -march=armv7-m -mthumb -c -o $@ $<
+arch/arm/imx-common/vf610m4bootldr.o: arch/arm/imx-common/vf610m4bootldr.S
+       $(call if_changed,ccm4_s_S)
+
+quiet_cmd_objcopym4 = OBJCOPY $@
+cmd_objcopym4 = $(OBJCOPY) -O binary $< $@
+arch/arm/imx-common/vf610m4bootldr: arch/arm/imx-common/vf610m4bootldr.o
+       $(call if_changed,objcopym4)
+
+quiet_cmd_objcopybinm4 = OBJCOPY $@
+cmd_objcopybinm4 = $(OBJCOPY) -I binary -O elf32-littlearm -B arm $< $@
+arch/arm/imx-common/vf610m4bootldrbin.o: arch/arm/imx-common/vf610m4bootldr
+       $(call if_changed,objcopybinm4)
+
+obj-$(CONFIG_CMD_M4BOOT) += vf610m4bootldrbin.o
 endif
 obj-$(CONFIG_CMD_BMODE) += cmd_bmode.o
 obj-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o
index 67c4c4fa07302d10d4041b2d53c11b74298ae8b3..1e0168c97d54f7d720ced6e4121048ee33f88a3d 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/arch/crm_regs.h>
 #include <asm/io.h>
 #include <image.h>
+#include <inttypes.h>
 
 #ifndef CONFIG_SYS_FDT_PAD
 #define CONFIG_SYS_FDT_PAD 0x3000
@@ -21,11 +22,20 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define CCM_CCOWR_START 0x00015a5a
 
+extern unsigned char _binary_arch_arm_imx_common_vf610m4bootldr_start;
+extern unsigned char _binary_arch_arm_imx_common_vf610m4bootldr_end;
+
 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;
-       ulong ep_loader = images->ep - 0x80;
+       int size = &_binary_arch_arm_imx_common_vf610m4bootldr_end -
+                  &_binary_arch_arm_imx_common_vf610m4bootldr_start;
+       ulong ep_loader = images->ep - size;
+
+       /* Copy the Linux mini boot loader just in front of the image... */
+       memcpy((void *)(images->os.image_start - size),
+               &_binary_arch_arm_imx_common_vf610m4bootldr_start, size);
 
        printf("Booting Cortex-M4 @0x%08lx\n", ep_loader);
 
diff --git a/arch/arm/imx-common/vf610m4bootldr.S b/arch/arm/imx-common/vf610m4bootldr.S
new file mode 100644 (file)
index 0000000..991d31f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Freescale Vybrid VF6xx M4 boot loader
+ *
+ * Enable PC/PS-Bus cache and get device tree pointer from Vybrid specific
+ * argument register (PERSISTENT_ARG1)
+ *
+ * Copyright (c) 2014-2015 Stefan Agner <stefan@agner.ch>
+ *
+ */
+
+#define        LMEM_PC_BASE    0xe0082000
+#define        LMEM_PS_BASE    0xe0082800
+#define LMEM_PXCCR     0x0
+#define        SRC_BASE        0x4006e000
+#define SRC_GPR2       0x28
+#define SRC_GPR3       0x2c
+       .thumb
+       .align
+main:
+       .macro invalidate_cache, base
+       .local invalidate_cache
+       /* GO, INVW1 & INVW0 */
+       mov     r3, #0x85
+       lsl     r3, r3, #24
+
+       /* ENCACHE */
+       mov     r1, #0x1
+       orr     r3, r1
+       str     r3, [ \base, #LMEM_PXCCR ]
+
+       ldr     r3, =0x1
+       lsl     r3, r3, #31
+1:
+       ldr     r2, [ \base, #LMEM_PXCCR ]
+       and     r2, r2, r3
+       bne     1b
+       .endm
+
+       ldr     r0, lmem_ps_base
+       invalidate_cache r0
+       ldr     r0, lmem_pc_base
+       invalidate_cache r0
+
+       ldr     r0, src_base
+       ldr     r1, machine_id          @ Machine ID
+       ldr     r2, [ r0, #SRC_GPR3 ]   @ DT pointer from argument register
+       mov     r0, #0x0
+       b       end
+
+       .align
+
+machine_id:
+       .long   0xffffffff
+src_base:
+       .long   SRC_BASE
+lmem_pc_base:
+       .long   LMEM_PC_BASE
+lmem_ps_base:
+       .long   LMEM_PS_BASE
+       .align 7
+end: