summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/arch-imx9/imx-regs.h18
-rw-r--r--arch/arm/mach-imx/imx9/imx_bootaux.c186
-rw-r--r--arch/arm/mach-imx/imx9/scmi/soc.c33
-rw-r--r--include/imx_sip.h2
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