[REGRESSION] Kernel reboots unexpectdely on i.MX8X when Cortex-M4 is running and it was started by U-Boot bootaux
Hiago De Franco
hiagofranco at gmail.com
Thu Apr 17 14:37:55 PDT 2025
Hi Peng,
On Thu, Apr 17, 2025 at 02:46:46AM +0000, Peng Fan wrote:
> > Subject: Re: [REGRESSION] Kernel reboots unexpectdely on i.MX8X
> > when Cortex-M4 is running and it was started by U-Boot bootaux
> >
> > Hi Peng,
> >
> > On Wed, Apr 16, 2025 at 08:19:27AM +0000, Peng Fan wrote:
> > > > Got it, I was able to make it work with the downstream pingpong
> > > > driver and the MCUXpresso demo. I can launch the firmware using
> > the
> > > > remoteproc and exchange data between the two cores.
> > > >
> > > > There is something I noticed, when I start the pingpong demo with
> > U-
> > > > Boot, it does not work. I run the pingpong modprobe on Linux but
> > the
> > > > name service is never annouced. It only works if I start with the
> > > > remoteproc on Linux, not U-Boot. Is this because of Linux not being
> > > > able to control the M4?
> > >
> > > No. In you case, you could start using remoteproc, that means Linux
> > > could control M4.
> > >
> > > >
> > > > If I start the binary using U-Boot, the "state" always report as
> > "offline"
> > > > by the remoteproc driver.
> > >
> > > In drivers/remoteproc/imx_rproc.c, imx_rproc_detect_mode case
> > > IMX_RPROC_SCU_API is used for detect mode of M4 for i.MX8Q/X
> > platform.
> > > Please give a look where it returns.
> > >
> > > For U-Boot start m4, linux should remote state: "attached"
> >
> > Ok, in this case looks its does not work. I start the firmware with U-
> > Boot and state is always "offline". Inside the IMX_RPROC_SCU_API case,
> > the function returns at this point:
> >
> > ...
> > /*
> > * If Mcore resource is not owned by Acore partition, It
> > is kicked by ROM,
> > * and Linux could only do IPC with Mcore and
> > nothing else.
> > */
> > if (imx_sc_rm_is_resource_owned(priv->ipc_handle,
> > priv->rsrc_id)) {
> > if (of_property_read_u32(dev->of_node,
> > "fsl,entry-address", &priv->entry))
> > return -EINVAL;
> >
> > return imx_rproc_attach_pd(priv); // <--
> > Returns here
> > ...
> >
> > And this function, imx_rproc_attach_pd, returns 0 at the end:
> >
> > ...
> > return 0; // <-- Returns here at the end
>
> ret = dev_pm_domain_attach_list(dev, &pd_data, &priv->pd_list);
> return ret < 0 ? ret : 0;
>
> It should return with ret as 0.
> Because you mentioned you added two entries.
> power-domains = <&pd IMX_SC_R_M4_0_PID0>,
> <&pd IMX_SC_R_M4_0_MU_1A>;
>
> https://lore.kernel.org/all/20250411162328.y2kchvdb4v4xi2lj@hiago-nb/
>
>
> >
> > detach_pd:
> > while (--i >= 0) {
> > ...
>
> It should not runs into detach_pd, where it fails?
>
> >
> > So looks like in this case the partition is *not* owned by the A core, it
> > is still being owned by the Mcore and I can not attach.
>
> No. It is owned, because imx_sc_rm_is_resource_owned returns
> true from what you said above.
>
> >
> > For debugging purposes, I did the following patch, inverting the logic:
> >
> > diff --git a/drivers/remoteproc/imx_rproc.c
> > b/drivers/remoteproc/imx_rproc.c index 592a34cfa75e..2fcc9086e916
> > 100644
> > --- a/drivers/remoteproc/imx_rproc.c
> > +++ b/drivers/remoteproc/imx_rproc.c
> > @@ -1072,7 +1072,7 @@ static int imx_rproc_detect_mode(struct
> > imx_rproc *priv)
> > * If Mcore resource is not owned by Acore partition, It is
> > kicked by ROM,
> > * and Linux could only do IPC with Mcore and nothing else.
> > */
> > - if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv-
> > >rsrc_id)) {
> > + if (!imx_sc_rm_is_resource_owned(priv->ipc_handle,
> > + priv->rsrc_id)) {
> > if (of_property_read_u32(dev->of_node, "fsl,entry-
> > address", &priv->entry))
> > return -EINVAL;
>
> Please no.
>
> >
> > And now the remoteproc driver attaches to the MCore succesfully,
> > which is exactly what I want. However less than one second later the
> > kernel reboot with the "SCFW fault reset" again.
>
> The resources used by M4 are unexpectedly shutdown by Linux,
> as I understand.
>
> Please check imx_rproc_attach_pd, it should return success
> with dev_pm_domain_attach_list return 0.
I was able to debug this issue further. The issue is not with the power
domains and the clock, these were solved by using the correct device
tree and by using the optional clk api:
@@ -1033,7 +1034,7 @@ static int imx_rproc_clk_enable(struct imx_rproc *priv)
if (dcfg->method == IMX_RPROC_NONE)
return 0;
- priv->clk = devm_clk_get(dev, NULL);
+ priv->clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(dev, "Failed to get clock\n");
return PTR_ERR(priv->clk);
And the device tree node:
imx8x-cm4 {
compatible = "fsl,imx8qxp-cm4";
mbox-names = "tx", "rx", "rxdb";
mboxes = <&lsio_mu5 0 1
&lsio_mu5 1 1
&lsio_mu5 3 1>;
memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>,
<&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
power-domains = <&pd IMX_SC_R_M4_0_PID0>,
<&pd IMX_SC_R_M4_0_MU_1A>;
fsl,entry-address = <0x34fe0000>;
fsl,resource-id = <IMX_SC_R_M4_0_PID0>;
};
The issue is: the .attach callback is never called when then code was
started by U-Boot bootaux. It should be called inside rproc_validate()
function from remoteproc_core.c. However, the rproc->state when we reach
this function is RPROC_OFFLINE, which causes the state to be always
(obviously) offline.
In imx_rproc.c driver, imx_rproc_detect_mode() returns at
/*
* If Mcore resource is not owned by Acore partition, It is kicked by ROM,
* and Linux could only do IPC with Mcore and nothing else.
*/
if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry))
return -EINVAL;
return imx_rproc_attach_pd(priv);
}
imx_sc_rm_is_resource_owned() returns 1, as M4 is owned by Linux, and
imx_rproc_attach_pd() returns 0, as both power domains are set. This
happens _before_ "priv->rproc->state = RPROC_DETACHED" is set one line
below, which causes the state to be always offline and the .attach
callback not called. For debugging, this patch solves this issue:
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 74299af1d7f1..b5af44a5d542 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -949,6 +949,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry))
return -EINVAL;
+ priv->rproc->state = RPROC_DETACHED;
return imx_rproc_attach_pd(priv);
}
With that, the running M4 is attached succesfully:
root at colibri-imx8x-07308754:~# dmesg | grep remote
[ 0.481561] remoteproc remoteproc0: imx-rproc is available
[ 0.481656] remoteproc remoteproc0: attaching to imx-rproc
[ 0.481743] remoteproc remoteproc0: remote processor imx-rproc is now attached
But as you know, this is not the correct solution, because this will
also attach when the M4 is _not_ running, since it will be owned by
Linux without any code running, which I think is wrong... I think this
"if" statement is not fully correct, there must be a way to attach to
the running M4. Any ideas or suggestions to fix this part?
>
> Regards,
> Peng
>
> >
> > Do you know what could be the issue in this case? Maybe the
> > partitions are not yet correct?
> >
> > >
> > > Regards,
> > > Peng.
> >
> > Cheers,
> > Hiago.
Cheers,
Hiago.
More information about the linux-arm-kernel
mailing list