Messages in this thread Patch in this message |  | | From | Peng Fan <> | | Subject | RE: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector | | Date | Wed, 1 Apr 2026 01:31:57 +0000 |
| |
Hi Mathieu,
> Subject: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM > CPU/LMM reset vector
I had an follow-up patch to update reset-vector-mask for i.MX95-CM7 to make it could boot from non-TCM area, not included in this pachset to avoid unnecessary churn for i.MX94 support, but I realize that that patch should be squashed into this patch 2/3 to avoid breaking i.MX95 M7 TCM booting. Although in my test, cm7 luckily boots up without crash[1], but in theory, below change should be included in patch 2/3. I will include below change in v3 after we clear the reset-vector-mask question.
Daniel, please see whether this is ok for you, since you reviewed this patch.
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 525a92e03e8ab..930dd9eca6fb5 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -1541,6 +1541,7 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = { /* Must align with System Manager Firmware */ .cpuid = 1, /* Use 1 as cpu id for M7 core */ .lmid = 1, /* Use 1 as Logical Machine ID where M7 resides */ + .reset_vector_mask = GENMASK_U32(31, 16), }; static const struct of_device_id imx_rproc_of_match[] = {
[1] [ 135.738523] remoteproc remoteproc0: powering up imx-rproc [ 135.748464] remoteproc remoteproc0: Booting fw image imx95-19x19-evk_m7_TCM_rpmsg_lite_str_echo_rtos.elf, size 98996 [ 135.759229] imx-rproc imx95-cm7: lmm(1) powered on by Linux [ 135.764900] ============== entry 0x91d [ 135.772597] xxxxxxxxxxxx bootaddr 0x91d [ 135.775818] rproc-virtio rproc-virtio.2.auto: assigned reserved memory node vdevbuffer@88020000 [ 135.780278] /soc/bus@42000000/i2c@426d0000/tcpc@50/connector: Fixed dependency cycle(s) with /soc/usb@4c010010/usb@4c100000 [ 135.795970] /soc/usb@4c010010/usb@4c100000: Fixed dependency cycle(s) with /soc/bus@42000000/i2c@426d0000/tcpc@50/connector [ 135.807727] virtio_rpmsg_bus virtio0: rpmsg host is online [ 135.811546] virtio_rpmsg_bus virtio0: creating channel rpmsg-i2c-channel addr 0x1
Thanks, Peng.
> > From: Peng Fan <peng.fan@nxp.com> > > Cortex-M[7,33] processors use a fixed reset vector table format: > > 0x00 Initial SP value > 0x04 Reset vector > 0x08 NMI > 0x0C ... > ... > IRQ[n] > > In ELF images, the corresponding layout is: > > reset_vectors: --> hardware reset address > .word __stack_end__ > .word Reset_Handler > .word NMI_Handler > .word HardFault_Handler > ... > .word UART_IRQHandler > .word SPI_IRQHandler > ... > > Reset_Handler: --> ELF entry point address > ... > > The hardware fetches the first two words from reset_vectors and > populates SP with __stack_end__ and PC with Reset_Handler. > Execution proceeds from Reset_Handler. > > However, the ELF entry point does not always match the hardware > reset address. For example, on i.MX94 CM33S: > > ELF entry point: 0x0ffc211d > hardware reset base: 0x0ffc0000 (default reset value, sw > programmable) > > To derive the correct hardware reset address, the unused lower bits > must be masked off. The boot code should apply a SoC-specific mask > before programming the reset address registers, e.g.: > > reset_address = entry & reset_vector_mask > > Current driver always programs the reset vector as 0. But i.MX94 > CM33S's default reset base is 0x0ffc0000, 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 SM CPU/LMM reset vector > API calls. > > Signed-off-by: Peng Fan <peng.fan@nxp.com> > --- > drivers/remoteproc/imx_rproc.c | 17 ++++++++++++++--- > drivers/remoteproc/imx_rproc.h | 2 ++ > 2 files changed, 16 insertions(+), 3 deletions(-) > > diff --git a/drivers/remoteproc/imx_rproc.c > b/drivers/remoteproc/imx_rproc.c index > 0dd80e688b0ea3df4c66e5726884dc86c8a5a881..d8ead42640881bd5 > 23d605fa7002935ef6e98077 100644 > --- a/drivers/remoteproc/imx_rproc.c > +++ b/drivers/remoteproc/imx_rproc.c > @@ -345,7 +345,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 +365,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 +739,17 @@ 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; > + u32 reset_vector_mask = GENMASK_U32(31, 0); > + > + if (priv->dcfg->reset_vector_mask) > + reset_vector_mask = priv->dcfg->reset_vector_mask; > + > + return rproc_elf_get_boot_addr(rproc, fw) & > reset_vector_mask; } > + > static const struct rproc_ops imx_rproc_ops = { > .prepare = imx_rproc_prepare, > .attach = imx_rproc_attach, > @@ -752,7 +763,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, diff --git > a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h > index > d37e6f90548cec727b4aeb874680b42af85bdbb4..0d7d48352a1091ad > 24e8e083172ce6da6d26ae10 100644 > --- a/drivers/remoteproc/imx_rproc.h > +++ b/drivers/remoteproc/imx_rproc.h > @@ -41,6 +41,8 @@ struct imx_rproc_dcfg { > /* For System Manager(SM) based SoCs */ > u32 cpuid; /* ID of the remote > core */ > u32 lmid; /* ID of the Logcial > Machine */ > + /* reset_vector = elf_entry_addr & reset_vector_mask */ > + u32 reset_vector_mask; > }; > > #endif /* _IMX_RPROC_H */ > > -- > 2.37.1
|  |