diff options
| -rw-r--r-- | arch/arm/include/asm/arch-imx9/imx-regs.h | 18 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx9/imx_bootaux.c | 186 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx9/scmi/soc.c | 33 | ||||
| -rw-r--r-- | include/imx_sip.h | 2 |
4 files changed, 205 insertions, 34 deletions
diff --git a/arch/arm/include/asm/arch-imx9/imx-regs.h b/arch/arm/include/asm/arch-imx9/imx-regs.h index 47d6ae9b559..55f4f34e1bc 100644 --- a/arch/arm/include/asm/arch-imx9/imx-regs.h +++ b/arch/arm/include/asm/arch-imx9/imx-regs.h @@ -47,6 +47,16 @@ #define SRC_MEDIA_RBASE (SRC_IPS_BASE_ADDR + 0x2400) #define SRC_M33P_RBASE (SRC_IPS_BASE_ADDR + 0x2800) +#ifdef CONFIG_IMX94 +#define TCML_BASE_ADDR (0x209C0000UL) +#define TCML_BASE_MCORE_SEC_ADDR (0x1FFC0000UL) +#define TCML_BASE_MCORE_NSEC_ADDR (0x0FFC0000UL) +#define TCML_SIZE (0x40000U) +#define TCMU_BASE_ADDR (0x20A00000UL) +#define TCMU_BASE_MCORE_SEC_ADDR (0x30000000UL) +#define TCMU_BASE_MCORE_NSEC_ADDR (0x20000000UL) +#define TCMU_SIZE (0x40000U) +#else #define TCML_BASE_ADDR (0x201E0000UL) #define TCML_BASE_MCORE_SEC_ADDR (0x1FFE0000UL) #define TCML_BASE_MCORE_NSEC_ADDR (0x0FFE0000UL) @@ -55,6 +65,14 @@ #define TCMU_BASE_MCORE_SEC_ADDR (0x30000000UL) #define TCMU_BASE_MCORE_NSEC_ADDR (0x20000000UL) #define TCMU_SIZE (0x20000U) +#endif + +#define M7_TCML_BASE_ADDR (0x20380000UL) +#define M7_TCML_BASE_MCORE_ADDR (0x0UL) +#define M7_TCML_MAX_SIZE (0x80000U) /* Could configure to 512KB TCML */ +#define M71_TCML_BASE_ADDR (0x20280000UL) +#define M71_TCML_BASE_MCORE_ADDR (0x0UL) +#define M71_TCML_MAX_SIZE (0x80000U) /* Could configure to 512KB TCML */ #define FLEXSPI_AHB_ADDR (0x28000000UL) #define FLEXSPI_AHB_SIZE (0x8000000UL) diff --git a/arch/arm/mach-imx/imx9/imx_bootaux.c b/arch/arm/mach-imx/imx9/imx_bootaux.c index c49f80e84dd..5b94d71fda5 100644 --- a/arch/arm/mach-imx/imx9/imx_bootaux.c +++ b/arch/arm/mach-imx/imx9/imx_bootaux.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2022 NXP + * Copyright 2022, 2026 NXP */ #include <command.h> @@ -16,11 +16,16 @@ DECLARE_GLOBAL_DATA_PTR; +#define CORE_CM33 0 +#define CORE_CM7 1 +#define CORE_CM71 7 +#define CORE_CM33S 8 + int arch_auxiliary_core_check_up(u32 core_id) { struct arm_smccc_res res; - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STARTED, 0, 0, + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STARTED, 0, core_id, 0, 0, 0, 0, &res); return res.a0; @@ -32,7 +37,7 @@ int arch_auxiliary_core_down(u32 core_id) printf("## Stopping auxiliary core\n"); - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STOP, 0, 0, + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STOP, 0, core_id, 0, 0, 0, 0, &res); return 0; @@ -42,17 +47,48 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr) { struct arm_smccc_res res; - if (!addr) - return -EINVAL; - printf("## Starting auxiliary core addr = 0x%08lX...\n", addr); - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_START, addr, 0, + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_START, addr, core_id, + 0, 0, 0, 0, &res); + + return 0; +} + +#if IS_ENABLED(CONFIG_SCMI_FIRMWARE) +int arch_auxiliary_core_prepare(u32 core_id) +{ + struct arm_smccc_res res; + + printf("## Preparing auxiliary core: %d\n", core_id); + + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_PREP, 0, core_id, + 0, 0, 0, 0, &res); + + return res.a0; +} + +int arch_auxiliary_core_prepared(u32 core_id) +{ + struct arm_smccc_res res; + + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_PREPED, 0, core_id, 0, 0, 0, 0, &res); + return res.a0; +} +#else +int arch_auxiliary_core_prepare(u32 core_id) +{ return 0; } +bool arch_auxiliary_core_prepared(u32 core_id) +{ + return true; +} +#endif + static inline bool check_in_ddr(ulong addr) { int i; @@ -68,26 +104,42 @@ static inline bool check_in_ddr(ulong addr) return false; } -static inline bool check_in_tcm(ulong addr, bool mcore_view) +static inline bool check_in_tcm(u32 core_id, ulong addr, bool mcore_view) { if (mcore_view) { - if ((addr >= TCML_BASE_MCORE_SEC_ADDR && - addr < TCML_BASE_MCORE_SEC_ADDR + TCML_SIZE) || - (addr >= TCMU_BASE_MCORE_SEC_ADDR && - addr < TCMU_BASE_MCORE_SEC_ADDR + TCMU_SIZE)) - return true; + if (core_id == CORE_CM33 || core_id == CORE_CM33S) { + if ((addr >= TCML_BASE_MCORE_SEC_ADDR && + addr < TCML_BASE_MCORE_SEC_ADDR + TCML_SIZE) || + (addr >= TCMU_BASE_MCORE_SEC_ADDR && + addr < TCMU_BASE_MCORE_SEC_ADDR + TCMU_SIZE)) + return true; - if ((addr >= TCML_BASE_MCORE_NSEC_ADDR && - addr < TCML_BASE_MCORE_NSEC_ADDR + TCML_SIZE) || - (addr >= TCMU_BASE_MCORE_NSEC_ADDR && - addr < TCMU_BASE_MCORE_NSEC_ADDR + TCMU_SIZE)) - return true; + if ((addr >= TCML_BASE_MCORE_NSEC_ADDR && + addr < TCML_BASE_MCORE_NSEC_ADDR + TCML_SIZE) || + (addr >= TCMU_BASE_MCORE_NSEC_ADDR && + addr < TCMU_BASE_MCORE_NSEC_ADDR + TCMU_SIZE)) + return true; + } else if (core_id == CORE_CM7 || core_id == CORE_CM71) { + if (addr >= M7_TCML_BASE_MCORE_ADDR && + addr < M7_TCML_BASE_MCORE_ADDR + M7_TCML_MAX_SIZE) + return true; + } } else { - if ((addr >= TCML_BASE_ADDR && - addr < TCML_BASE_ADDR + TCML_SIZE) || - (addr >= TCMU_BASE_ADDR && - addr < TCMU_BASE_ADDR + TCMU_SIZE)) - return true; + if (core_id == CORE_CM33 || core_id == CORE_CM33S) { + if ((addr >= TCML_BASE_ADDR && + addr < TCML_BASE_ADDR + TCML_SIZE) || + (addr >= TCMU_BASE_ADDR && + addr < TCMU_BASE_ADDR + TCMU_SIZE)) + return true; + } else if (core_id == CORE_CM7) { + if (addr >= M7_TCML_BASE_ADDR && + addr < M7_TCML_BASE_ADDR + M7_TCML_MAX_SIZE) + return true; + } else if (core_id == CORE_CM71) { + if (addr >= M71_TCML_BASE_ADDR && + addr < M71_TCML_BASE_ADDR + M7_TCML_MAX_SIZE) + return true; + } } return false; } @@ -101,7 +153,7 @@ static inline bool check_in_flexspi(ulong addr) } #if IS_ENABLED(CONFIG_AHAB_BOOT) -static int authenticate_auxcore_container(ulong addr, ulong *entry) +static int authenticate_auxcore_container(u32 core_id, ulong addr, ulong *entry) { struct container_hdr *phdr; int i, ret = 0; @@ -114,7 +166,8 @@ static int authenticate_auxcore_container(ulong addr, ulong *entry) return -EINVAL; } - if (!check_in_ddr(addr) && !check_in_tcm(addr, false) && !check_in_flexspi(addr)) { + if (!check_in_ddr(addr) && !check_in_tcm(core_id, addr, false) && + !check_in_flexspi(addr)) { printf("Error: Container's address is invalid\n"); return -EINVAL; } @@ -147,7 +200,7 @@ static int authenticate_auxcore_container(ulong addr, ulong *entry) i * sizeof(struct boot_img_t)); /* Check Core ID of M core */ - if ((img->meta & 0xff) != 0) { + if ((img->meta & 0xff) != core_id) { printf("Error: Wrong Image core ID, meta = 0x%x\n", img->meta); ret = -EFAULT; break; @@ -163,7 +216,8 @@ static int authenticate_auxcore_container(ulong addr, ulong *entry) break; } } else { - if (!check_in_ddr(img->dst) && !check_in_tcm(img->dst, false)) { + if (!check_in_ddr(img->dst) && + !check_in_tcm(core_id, img->dst, false)) { printf("Error: Invalid Image[%u] load address 0x%llx\n", i, img->dst); ret = -EFAULT; @@ -217,6 +271,12 @@ static int do_bootaux_cntr(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } + up = arch_auxiliary_core_prepared(core); + if (!up) { + printf("## Not prepared, run 'prepaux [coreid]' first\n"); + return CMD_RET_FAILURE; + } + addr = simple_strtoul(argv[1], NULL, 16); if (!addr) @@ -224,13 +284,13 @@ static int do_bootaux_cntr(struct cmd_tbl *cmdtp, int flag, int argc, printf("Authenticate auxcore container at 0x%lx\n", addr); - ret = authenticate_auxcore_container(addr, &entry); + ret = authenticate_auxcore_container(core, addr, &entry); if (ret) { printf("Authenticate container failed %d\n", ret); return CMD_RET_FAILURE; } - if (!check_in_ddr(entry) && !check_in_tcm(entry, true) && + if (!check_in_ddr(entry) && !check_in_tcm(core, entry, true) && !check_in_flexspi(entry)) { printf("Error: Image's entry 0x%lx is invalid\n", entry); return CMD_RET_FAILURE; @@ -280,12 +340,20 @@ static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } + up = arch_auxiliary_core_prepared(core); + if (!up) { + printf("## Not prepared, run 'prepaux [coreid]' first\n"); + return CMD_RET_FAILURE; + } + addr = simple_strtoul(argv[1], NULL, 16); - if (!addr) + if ((core != CORE_CM7 && core != CORE_CM71) && !addr) { + printf("Invalid address 0x%lx for core: %d\n", addr, core); return CMD_RET_FAILURE; + } - if (!check_in_ddr(addr) && !check_in_tcm(addr, true) && !check_in_flexspi(addr)) { + if (!check_in_ddr(addr) && !check_in_tcm(core, addr, true) && !check_in_flexspi(addr)) { printf("Error: Image's address 0x%lx is invalid\n", addr); printf(" Address should be memory from M core view,\n" " For example: 0x1ffe0000 for TCML in secure\n"); @@ -304,14 +372,21 @@ static int do_stopaux(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { int ret, up; + u32 core = 0; + + if (argc < 2) + return CMD_RET_USAGE; + + if (argc > 2) + core = simple_strtoul(argv[2], NULL, 10); - up = arch_auxiliary_core_check_up(0); + up = arch_auxiliary_core_check_up(core); if (!up) { printf("## Auxiliary core is already down\n"); return CMD_RET_SUCCESS; } - ret = arch_auxiliary_core_down(0); + ret = arch_auxiliary_core_down(core); if (ret) return CMD_RET_FAILURE; @@ -324,6 +399,41 @@ U_BOOT_CMD( "<address> [<core>]\n" " - start auxiliary core [<core>] (default 0),\n" " at address <address>\n" + " <core>:\n" + " 0 - CM33\n" + " 1 - CM70\n" + " 7 - CM71\n" + " 8 - CM33 Sync\n" +); + +static int do_prepaux(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + u32 core = 0; + + if (argc != 2) + return CMD_RET_USAGE; + + core = simple_strtoul(argv[1], NULL, 10); + + ret = arch_auxiliary_core_prepare(core); + if (ret) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + prepaux, CONFIG_SYS_MAXARGS, 1, do_prepaux, + "prepare auxiliary core", + "[<core>]\n" + " - prep auxiliary core [<core>] (default 0),\n" + " <core>:\n" + " 0 - CM33\n" + " 1 - CM70\n" + " 7 - CM71\n" + " 8 - CM33 Sync\n" ); #if IS_ENABLED(CONFIG_AHAB_BOOT) @@ -333,6 +443,11 @@ U_BOOT_CMD( "<container_address> [<core>]\n" " - start auxiliary core [<core>] (default 0),\n" " with signed container image at address <address> in A core view\n" + " <core>:\n" + " 0 - CM33\n" + " 1 - CM70\n" + " 7 - CM71\n" + " 8 - CM33 Sync\n" ); #else U_BOOT_CMD( @@ -341,5 +456,10 @@ U_BOOT_CMD( "<address> [<core>]\n" " - start auxiliary core [<core>] (default 0),\n" " at address <address> of auxiliary core view\n" + " <core>:\n" + " 0 - CM33\n" + " 1 - CM70\n" + " 7 - CM71\n" + " 8 - CM33 Sync\n" ); #endif diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c index 18d00355999..dc78d73251c 100644 --- a/arch/arm/mach-imx/imx9/scmi/soc.c +++ b/arch/arm/mach-imx/imx9/scmi/soc.c @@ -248,7 +248,38 @@ static struct mm_region imx9_mem_map[] = { .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { + }, +#if IS_ENABLED(CONFIG_IMX94) + { + /* M71 TCM */ + .virt = 0x202c0000UL, + .phys = 0x202c0000UL, + .size = 0x80000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, + { + /* M33S TCM */ + .virt = 0x209c0000UL, + .phys = 0x209c0000UL, + .size = 0x80000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, + /* 644K netc ocram for rpmsg buffer */ + { + /* M33S NETC OCRAM */ + .virt = 0x20800000UL, + .phys = 0x20800000UL, + .size = 0xa1000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, +#endif + { /* OCRAM */ .virt = 0x20480000UL, .phys = 0x20480000UL, diff --git a/include/imx_sip.h b/include/imx_sip.h index 8a5ca34f393..478cbd3fdaf 100644 --- a/include/imx_sip.h +++ b/include/imx_sip.h @@ -16,5 +16,7 @@ #define IMX_SIP_SRC_MCU_START 0x00 #define IMX_SIP_SRC_MCU_STARTED 0x01 #define IMX_SIP_SRC_MCU_STOP 0x02 +#define IMX_SIP_SRC_MCU_PREP 0x04 +#define IMX_SIP_SRC_MCU_PREPED 0x05 #endif |
