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 <[email protected]>
>
> 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 <[email protected]>
> ---
> 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