public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Add i.MX94 remoteproc support and reset vector handling improvements
@ 2026-03-27  2:42 Peng Fan (OSS)
  2026-03-27  2:42 ` [PATCH v2 1/3] dt-bindings: remoteproc: imx-rproc: Support i.MX94 Peng Fan (OSS)
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Peng Fan (OSS) @ 2026-03-27  2:42 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan

This series adds remoteproc support for the i.MX94 family, including the
CM70, CM71, and CM33S cores, and derive the hardware reset vector for
Cortex‑M processors whose ELF entry point does not directly correspond to
the actual reset address.

Background:
Cortex‑M processors fetch their initial SP and PC from a fixed reset vector
table. While ELF images embed the entry point (e_entry), this value is
not always aligned to the hardware reset address. On platforms such as
i.MX94 CM33S, masking is required to compute the correct reset vector
address before programming the SoC reset registers.

Similarly, on i.MX95, the existing implementation always programs a reset
vector of 0x0, which only works when executing entirely from TCM. When
firmware is loaded into DDR, the driver must pass the correct reset vector
to the SM CPU/LMM interfaces.

Summary of patches:
[1]dt-bindings: remoteproc: imx-rproc: Introduce fsl,reset-vector-mask
Adds a new DT property allowing SoCs to specify a mask for deriving the
hardware reset vector from the ELF entry point.

[2]remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector
Ensures the correct reset vector is passed to SM APIs by introducing a
driver‑level helper (imx_rproc_get_boot_addr()) that applies the
reset‑vector mask.

[3]remoteproc: imx_rproc: Add support for i.MX94 remoteproc
Adds address translation tables and configuration data for CM70, CM71,
and CM33S, enabling full remoteproc operation on i.MX94.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Changes in v2:
- Drop fsl,reset-vector-mask by using fixed value in driver for per device
- Add R-b for i.MX94 dt-binding
- Update commit log to include dev addr and sys addr
- Link to v1: https://lore.kernel.org/r/20260312-imx943-rproc-v1-0-3e66596592a8@nxp.com

---
Peng Fan (3):
      dt-bindings: remoteproc: imx-rproc: Support i.MX94
      remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector
      remoteproc: imx_rproc: Add support for i.MX94

 .../bindings/remoteproc/fsl,imx-rproc.yaml         |  3 +
 drivers/remoteproc/imx_rproc.c                     | 88 +++++++++++++++++++++-
 drivers/remoteproc/imx_rproc.h                     |  2 +
 3 files changed, 90 insertions(+), 3 deletions(-)
---
base-commit: a2f31c83962f7f298b2975ab004810f3ac4875dc
change-id: 20260311-imx943-rproc-2050e00b65f7

Best regards,
-- 
Peng Fan <peng.fan@nxp.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/3] dt-bindings: remoteproc: imx-rproc: Support i.MX94
  2026-03-27  2:42 [PATCH v2 0/3] Add i.MX94 remoteproc support and reset vector handling improvements Peng Fan (OSS)
@ 2026-03-27  2:42 ` Peng Fan (OSS)
  2026-03-27  2:42 ` [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector Peng Fan (OSS)
  2026-03-27  2:42 ` [PATCH v2 3/3] remoteproc: imx_rproc: Add support for i.MX94 Peng Fan (OSS)
  2 siblings, 0 replies; 9+ messages in thread
From: Peng Fan (OSS) @ 2026-03-27  2:42 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan

From: Peng Fan <peng.fan@nxp.com>

Add compatible string for:
 Cortex-M7 core[0,1] in i.MX94
 Cortex-M33 Sync core in i.MX94

To i.MX94, Cortex-M7 core0 and core1 have different memory view from
Cortex-A55 core, so different compatible string is used.

Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
index ce8ec0119469c8fc0979a192b6e3d3a03108d7d2..c18f71b648890da9c25a2f3309d8dbec5bb8d226 100644
--- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
@@ -28,6 +28,9 @@ properties:
       - fsl,imx8qxp-cm4
       - fsl,imx8ulp-cm33
       - fsl,imx93-cm33
+      - fsl,imx94-cm33s
+      - fsl,imx94-cm70
+      - fsl,imx94-cm71
       - fsl,imx95-cm7
 
   clocks:

-- 
2.37.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector
  2026-03-27  2:42 [PATCH v2 0/3] Add i.MX94 remoteproc support and reset vector handling improvements Peng Fan (OSS)
  2026-03-27  2:42 ` [PATCH v2 1/3] dt-bindings: remoteproc: imx-rproc: Support i.MX94 Peng Fan (OSS)
@ 2026-03-27  2:42 ` Peng Fan (OSS)
  2026-03-27  9:45   ` Daniel Baluta
                     ` (2 more replies)
  2026-03-27  2:42 ` [PATCH v2 3/3] remoteproc: imx_rproc: Add support for i.MX94 Peng Fan (OSS)
  2 siblings, 3 replies; 9+ messages in thread
From: Peng Fan (OSS) @ 2026-03-27  2:42 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan

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..d8ead42640881bd523d605fa7002935ef6e98077 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..0d7d48352a1091ad24e8e083172ce6da6d26ae10 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


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/3] remoteproc: imx_rproc: Add support for i.MX94
  2026-03-27  2:42 [PATCH v2 0/3] Add i.MX94 remoteproc support and reset vector handling improvements Peng Fan (OSS)
  2026-03-27  2:42 ` [PATCH v2 1/3] dt-bindings: remoteproc: imx-rproc: Support i.MX94 Peng Fan (OSS)
  2026-03-27  2:42 ` [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector Peng Fan (OSS)
@ 2026-03-27  2:42 ` Peng Fan (OSS)
  2026-03-27  9:46   ` Daniel Baluta
  2 siblings, 1 reply; 9+ messages in thread
From: Peng Fan (OSS) @ 2026-03-27  2:42 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan

From: Peng Fan <peng.fan@nxp.com>

Add basic remoteproc support for the i.MX94 M-core processors, including
address translation tables(dev addr is from view of remote processor,
sys addr is from view of main processor) and device configuration data for
the CM70, CM71, and CM33S cores.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 71 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index d8ead42640881bd523d605fa7002935ef6e98077..525a92e03e8ab540697a3ef1f593b079f55e10ee 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -145,6 +145,47 @@ static const struct imx_rproc_att imx_rproc_att_imx95_m7[] = {
 	{ 0x80000000, 0x80000000, 0x50000000, 0 },
 };
 
+static const struct imx_rproc_att imx_rproc_att_imx94_m70[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	/* TCM CODE NON-SECURE */
+	{ 0x00000000, 0x203C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
+	/* TCM SYS NON-SECURE*/
+	{ 0x20000000, 0x20400000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+	/* DDR */
+	{ 0x80000000, 0x80000000, 0x50000000, 0 },
+};
+
+static const struct imx_rproc_att imx_rproc_att_imx94_m71[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	/* TCM CODE NON-SECURE */
+	{ 0x00000000, 0x202C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
+	/* TCM SYS NON-SECURE*/
+	{ 0x20000000, 0x20300000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+	/* DDR */
+	{ 0x80000000, 0x80000000, 0x50000000, 0 },
+};
+
+static const struct imx_rproc_att imx_rproc_att_imx94_m33s[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	/* TCM CODE NON-SECURE */
+	{ 0x0FFC0000, 0x209C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
+	/* TCM CODE SECURE */
+	{ 0x1FFC0000, 0x209C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+	/* TCM SYS NON-SECURE */
+	{ 0x20000000, 0x20A00000, 0x00040000, ATT_OWN | ATT_IOMEM },
+	/* TCM SYS SECURE */
+	{ 0x30000000, 0x20A00000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+	/* M33S OCRAM */
+	{ 0x20800000, 0x20800000, 0x180000, ATT_OWN | ATT_IOMEM },
+
+	/* DDR */
+	{ 0x80000000, 0x80000000, 0x50000000, 0 },
+};
+
 static const struct imx_rproc_att imx_rproc_att_imx93[] = {
 	/* dev addr , sys addr  , size	    , flags */
 	/* TCM CODE NON-SECURE */
@@ -1466,6 +1507,33 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = {
 	.flags		= IMX_RPROC_NEED_CLKS,
 };
 
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx94_m70 = {
+	.att		= imx_rproc_att_imx94_m70,
+	.att_size	= ARRAY_SIZE(imx_rproc_att_imx94_m70),
+	.ops		= &imx_rproc_ops_sm_lmm,
+	.cpuid		= 1,
+	.lmid		= 2,
+	.reset_vector_mask = GENMASK_U32(31, 16),
+};
+
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx94_m71 = {
+	.att		= imx_rproc_att_imx94_m71,
+	.att_size	= ARRAY_SIZE(imx_rproc_att_imx94_m71),
+	.ops		= &imx_rproc_ops_sm_lmm,
+	.cpuid		= 7,
+	.lmid		= 3,
+	.reset_vector_mask = GENMASK_U32(31, 16),
+};
+
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx94_m33s = {
+	.att		= imx_rproc_att_imx94_m33s,
+	.att_size	= ARRAY_SIZE(imx_rproc_att_imx94_m33s),
+	.ops		= &imx_rproc_ops_sm_lmm,
+	.cpuid		= 8,
+	.lmid		= 1,
+	.reset_vector_mask = GENMASK_U32(31, 16),
+};
+
 static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = {
 	.att		= imx_rproc_att_imx95_m7,
 	.att_size	= ARRAY_SIZE(imx_rproc_att_imx95_m7),
@@ -1489,6 +1557,9 @@ static const struct of_device_id imx_rproc_of_match[] = {
 	{ .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
 	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
 	{ .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
+	{ .compatible = "fsl,imx94-cm70", .data = &imx_rproc_cfg_imx94_m70 },
+	{ .compatible = "fsl,imx94-cm71", .data = &imx_rproc_cfg_imx94_m71 },
+	{ .compatible = "fsl,imx94-cm33s", .data = &imx_rproc_cfg_imx94_m33s },
 	{ .compatible = "fsl,imx95-cm7", .data = &imx_rproc_cfg_imx95_m7 },
 	{},
 };

-- 
2.37.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector
  2026-03-27  2:42 ` [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector Peng Fan (OSS)
@ 2026-03-27  9:45   ` Daniel Baluta
  2026-03-30 16:22   ` Mathieu Poirier
  2026-04-01  1:31   ` Peng Fan
  2 siblings, 0 replies; 9+ messages in thread
From: Daniel Baluta @ 2026-03-27  9:45 UTC (permalink / raw)
  To: Peng Fan (OSS), Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan

On 3/27/26 04:42, Peng Fan (OSS) wrote:
> 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>


Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/3] remoteproc: imx_rproc: Add support for i.MX94
  2026-03-27  2:42 ` [PATCH v2 3/3] remoteproc: imx_rproc: Add support for i.MX94 Peng Fan (OSS)
@ 2026-03-27  9:46   ` Daniel Baluta
  0 siblings, 0 replies; 9+ messages in thread
From: Daniel Baluta @ 2026-03-27  9:46 UTC (permalink / raw)
  To: Peng Fan (OSS), Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan

On 3/27/26 04:42, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> Add basic remoteproc support for the i.MX94 M-core processors, including
> address translation tables(dev addr is from view of remote processor,
> sys addr is from view of main processor) and device configuration data for
> the CM70, CM71, and CM33S cores.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>

Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector
  2026-03-27  2:42 ` [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector Peng Fan (OSS)
  2026-03-27  9:45   ` Daniel Baluta
@ 2026-03-30 16:22   ` Mathieu Poirier
  2026-03-31  2:49     ` Peng Fan
  2026-04-01  1:31   ` Peng Fan
  2 siblings, 1 reply; 9+ messages in thread
From: Mathieu Poirier @ 2026-03-30 16:22 UTC (permalink / raw)
  To: Peng Fan (OSS)
  Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Daniel Baluta, linux-remoteproc, devicetree, imx,
	linux-arm-kernel, linux-kernel, Peng Fan

On Fri, Mar 27, 2026 at 10:42:03AM +0800, Peng Fan (OSS) wrote:
> 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)
>

But why?  Why can't the ELF image be set to the right reset base?
 
> 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..d8ead42640881bd523d605fa7002935ef6e98077 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..0d7d48352a1091ad24e8e083172ce6da6d26ae10 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
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector
  2026-03-30 16:22   ` Mathieu Poirier
@ 2026-03-31  2:49     ` Peng Fan
  0 siblings, 0 replies; 9+ messages in thread
From: Peng Fan @ 2026-03-31  2:49 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Daniel Baluta, linux-remoteproc, devicetree, imx,
	linux-arm-kernel, linux-kernel, Peng Fan

On Mon, Mar 30, 2026 at 10:22:35AM -0600, Mathieu Poirier wrote:
>On Fri, Mar 27, 2026 at 10:42:03AM +0800, Peng Fan (OSS) wrote:
>> 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)
>>
>
>But why?  Why can't the ELF image be set to the right reset base?

Per zephyr general link script[1]:
ENTRY(CONFIG_KERNEL_ENTRY)

CONFIG_KERNEL_ENTRY(_start) is the first instruction that Cortex-M starts to
execute.

config KERNEL_ENTRY
        string "Kernel entry symbol"
        default "__start"
        help
          Code entry symbol, to be set at linking phase.

The hardware reset base is different: it is the address where the hardware
fetches the initial MSP and PC values from the vector table. Hardware uses
this base to initialize the stack pointer and program counter, and only then
does the Cortex‑M begin execution at the reset handler.

Aligning the ELF entry point with the hardware reset base on Cortex‑M systems
is possible, but it comes with several risks.
1, Semantic mismatch (ELF vs. hardware behavior)
2, Debuggers may attempt to set breakpoints or start execution at the entry symbol

[1] https://elixir.bootlin.com/zephyr/v4.4.0-rc1/source/include/zephyr/arch/arm/cortex_m/scripts/linker.ld#L103

Regards
Peng.
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector
  2026-03-27  2:42 ` [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector Peng Fan (OSS)
  2026-03-27  9:45   ` Daniel Baluta
  2026-03-30 16:22   ` Mathieu Poirier
@ 2026-04-01  1:31   ` Peng Fan
  2 siblings, 0 replies; 9+ messages in thread
From: Peng Fan @ 2026-04-01  1:31 UTC (permalink / raw)
  To: Peng Fan (OSS), Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta
  Cc: linux-remoteproc@vger.kernel.org, devicetree@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org

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


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-04-01  1:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-27  2:42 [PATCH v2 0/3] Add i.MX94 remoteproc support and reset vector handling improvements Peng Fan (OSS)
2026-03-27  2:42 ` [PATCH v2 1/3] dt-bindings: remoteproc: imx-rproc: Support i.MX94 Peng Fan (OSS)
2026-03-27  2:42 ` [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector Peng Fan (OSS)
2026-03-27  9:45   ` Daniel Baluta
2026-03-30 16:22   ` Mathieu Poirier
2026-03-31  2:49     ` Peng Fan
2026-04-01  1:31   ` Peng Fan
2026-03-27  2:42 ` [PATCH v2 3/3] remoteproc: imx_rproc: Add support for i.MX94 Peng Fan (OSS)
2026-03-27  9:46   ` Daniel Baluta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox