From: Peng Fan <[email protected]> Current driver always programs the reset vector as 0. This works when the Cortex‑M7 on i.MX95 executes from TCM, since the reset vector is naturally located at address 0. However, when the firmware is loaded into DDR, the reset vector must be set to the actual reset address instead of 0.
For the Cortex‑M33 Sync core on i.MX94, the CODE TCM base is also not 0, so the correct reset vector must be passed to the SM API; otherwise the M33 Sync core cannot boot successfully. rproc_elf_get_boot_addr() returns the ELF entry point, which is not the hardware reset vector address. To derive the proper reset vector, this patch introduces imx_rproc_get_boot_addr(), which masks the ELF entry point using the SoC‑specific 'reset_vector_mask'. The resulting reset vector address is then passed to the appropriate SM CPU/LMM reset vector API calls. Signed-off-by: Peng Fan <[email protected]> --- drivers/remoteproc/imx_rproc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 0dd80e688b0ea3df4c66e5726884dc86c8a5a881..9b07103857b13018bdf62431cbfeffa3e3c1a15c 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -124,6 +124,7 @@ struct imx_rproc { u32 rsrc_id; /* resource id */ u32 entry; /* cpu start address */ u32 core_index; + u32 reset_vector_mask; struct dev_pm_domain_list *pd_list; const struct imx_rproc_plat_ops *ops; /* @@ -345,7 +346,7 @@ static int imx_rproc_sm_cpu_start(struct rproc *rproc) const struct imx_rproc_dcfg *dcfg = priv->dcfg; int ret; - ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, 0, true, false, false); + ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, rproc->bootaddr, true, false, false); if (ret) { dev_err(priv->dev, "Failed to set reset vector cpuid(%u): %d\n", dcfg->cpuid, ret); return ret; @@ -365,7 +366,7 @@ static int imx_rproc_sm_lmm_start(struct rproc *rproc) * If the remoteproc core can't start the M7, it will already be * handled in imx_rproc_sm_lmm_prepare(). */ - ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid, 0, 0); + ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid, 0, rproc->bootaddr); if (ret) { dev_err(dev, "Failed to set reset vector lmid(%u), cpuid(%u): %d\n", dcfg->lmid, dcfg->cpuid, ret); @@ -739,6 +740,13 @@ imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware * return rproc_elf_find_loaded_rsc_table(rproc, fw); } +static u64 imx_rproc_get_boot_addr(struct rproc *rproc, const struct firmware *fw) +{ + struct imx_rproc *priv = rproc->priv; + + return rproc_elf_get_boot_addr(rproc, fw) & priv->reset_vector_mask; +} + static const struct rproc_ops imx_rproc_ops = { .prepare = imx_rproc_prepare, .attach = imx_rproc_attach, @@ -752,7 +760,7 @@ static const struct rproc_ops imx_rproc_ops = { .find_loaded_rsc_table = imx_rproc_elf_find_loaded_rsc_table, .get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table, .sanity_check = rproc_elf_sanity_check, - .get_boot_addr = rproc_elf_get_boot_addr, + .get_boot_addr = imx_rproc_get_boot_addr, }; static int imx_rproc_addr_init(struct imx_rproc *priv, @@ -1244,6 +1252,9 @@ static int imx_rproc_probe(struct platform_device *pdev) priv->rproc = rproc; priv->dcfg = dcfg; priv->dev = dev; + priv->reset_vector_mask = GENMASK(31, 0); + + of_property_read_u32(np, "fsl,reset-vector-mask", &priv->reset_vector_mask); if (dcfg->ops) priv->ops = dcfg->ops; -- 2.37.1

