1 /* 2 * Copyright (C) 2016 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <command.h> 9 #include <linux/compiler.h> 10 11 /* Allow for arch specific config before we boot */ 12 int __weak arch_auxiliary_core_up(u32 core_id, u32 boot_private_data) 13 { 14 /* please define platform specific arch_auxiliary_core_up() */ 15 return CMD_RET_FAILURE; 16 } 17 18 /* Allow for arch specific config before we boot */ 19 int __weak arch_auxiliary_core_check_up(u32 core_id) 20 { 21 /* please define platform specific arch_auxiliary_core_check_up() */ 22 return 0; 23 } 24 25 /* 26 * To i.MX6SX and i.MX7D, the image supported by bootaux needs 27 * the reset vector at the head for the image, with SP and PC 28 * as the first two words. 29 * 30 * Per the cortex-M reference manual, the reset vector of M4 needs 31 * to exist at 0x0 (TCMUL). The PC and SP are the first two addresses 32 * of that vector. So to boot M4, the A core must build the M4's reset 33 * vector with getting the PC and SP from image and filling them to 34 * TCMUL. When M4 is kicked, it will load the PC and SP by itself. 35 * The TCMUL is mapped to (M4_BOOTROM_BASE_ADDR) at A core side for 36 * accessing the M4 TCMUL. 37 */ 38 static int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 39 { 40 ulong addr; 41 int ret, up; 42 43 if (argc < 2) 44 return CMD_RET_USAGE; 45 46 up = arch_auxiliary_core_check_up(0); 47 if (up) { 48 printf("## Auxiliary core is already up\n"); 49 return CMD_RET_SUCCESS; 50 } 51 52 addr = simple_strtoul(argv[1], NULL, 16); 53 54 printf("## Starting auxiliary core at 0x%08lX ...\n", addr); 55 56 ret = arch_auxiliary_core_up(0, addr); 57 if (ret) 58 return CMD_RET_FAILURE; 59 60 return CMD_RET_SUCCESS; 61 } 62 63 U_BOOT_CMD( 64 bootaux, CONFIG_SYS_MAXARGS, 1, do_bootaux, 65 "Start auxiliary core", 66 "" 67 ); 68