Merge tag 'u-boot-imx-20200511' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
[oweals/u-boot.git] / arch / arm / mach-imx / imx_bootaux.c
index 69026df7630f92a8967ab1ebb888a33feff3b1f3..ec0da1164f3cb888f32a9c711683f4d8b6804a57 100644 (file)
@@ -1,31 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2016 Freescale Semiconductor, Inc.
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
+#include <asm/io.h>
+#include <asm/mach-imx/sys_proto.h>
 #include <command.h>
+#include <elf.h>
+#include <imx_sip.h>
+#include <linux/compiler.h>
+#include <cpu_func.h>
 
-/* Allow for arch specific config before we boot */
-static int __arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
+int arch_auxiliary_core_up(u32 core_id, ulong addr)
 {
-       /* please define platform specific arch_auxiliary_core_up() */
-       return CMD_RET_FAILURE;
-}
+       ulong stack, pc;
 
-int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
-       __attribute__((weak, alias("__arch_auxiliary_core_up")));
+       if (!addr)
+               return -EINVAL;
+
+#ifdef CONFIG_IMX8M
+       stack = *(u32 *)addr;
+       pc = *(u32 *)(addr + 4);
+#else
+       /*
+        * handling ELF64 binaries
+        * isn't supported yet.
+        */
+       if (valid_elf_image(addr)) {
+               stack = 0x0;
+               pc = load_elf_image_phdr(addr);
+               if (!pc)
+                       return CMD_RET_FAILURE;
+
+       } else {
+               /*
+                * Assume binary file with vector table at the beginning.
+                * Cortex-M4 vector tables start with the stack pointer (SP)
+                * and reset vector (initial PC).
+                */
+               stack = *(u32 *)addr;
+               pc = *(u32 *)(addr + 4);
+       }
+#endif
+       printf("## Starting auxiliary core stack = 0x%08lX, pc = 0x%08lX...\n",
+              stack, pc);
+
+       /* Set the stack and pc to M4 bootROM */
+       writel(stack, M4_BOOTROM_BASE_ADDR);
+       writel(pc, M4_BOOTROM_BASE_ADDR + 4);
+
+       flush_dcache_all();
+
+       /* Enable M4 */
+#ifdef CONFIG_IMX8M
+       call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0);
+#else
+       clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET,
+                       SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK);
+#endif
 
-/* Allow for arch specific config before we boot */
-static int __arch_auxiliary_core_check_up(u32 core_id)
-{
-       /* please define platform specific arch_auxiliary_core_check_up() */
        return 0;
 }
 
 int arch_auxiliary_core_check_up(u32 core_id)
-       __attribute__((weak, alias("__arch_auxiliary_core_check_up")));
+{
+#ifdef CONFIG_IMX8M
+       return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0);
+#else
+       unsigned int val;
+
+       val = readl(SRC_BASE_ADDR + SRC_M4_REG_OFFSET);
+
+       if (val & SRC_M4C_NON_SCLR_RST_MASK)
+               return 0;  /* assert in reset */
+
+       return 1;
+#endif
+}
 
 /*
  * To i.MX6SX and i.MX7D, the image supported by bootaux needs
@@ -40,7 +92,7 @@ int arch_auxiliary_core_check_up(u32 core_id)
  * The TCMUL is mapped to (M4_BOOTROM_BASE_ADDR) at A core side for
  * accessing the M4 TCMUL.
  */
-int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        ulong addr;
        int ret, up;
@@ -56,7 +108,8 @@ int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        addr = simple_strtoul(argv[1], NULL, 16);
 
-       printf("## Starting auxiliary core at 0x%08lX ...\n", addr);
+       if (!addr)
+               return CMD_RET_FAILURE;
 
        ret = arch_auxiliary_core_up(0, addr);
        if (ret)