Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipm: imx: send firmware ready reply #61709

Merged
merged 1 commit into from
Sep 26, 2023

Conversation

iuliana-prodan
Copy link
Collaborator

@iuliana-prodan iuliana-prodan commented Aug 21, 2023

Send a fw ready reply message as soon as possible.
This is usually used on host side which is waiting for this message in order to establish the communication with the remote processor - see imx_dsp_rproc driver from Linux.

This can be enabled by IPM_IMX_FW_READY_REPLY config, which is by default N.

Set CONFIG_IPM_IMX_FW_READY_REPLY as Y for openamp_rsc_table sample, running on nxp_adsp_imx8m.

Copy link
Collaborator

@carlocaione carlocaione left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this PR is not problematic per se my impression is that we are kinda cheating here. Wouldn't much better just to introduce a new REMOTEPROC API class / subsystem in Zephyr and use that instead?

drivers/ipm/Kconfig.imx Outdated Show resolved Hide resolved
drivers/ipm/Kconfig.imx Outdated Show resolved Hide resolved
drivers/ipm/ipm_imx.c Outdated Show resolved Hide resolved
@iuliana-prodan
Copy link
Collaborator Author

iuliana-prodan commented Aug 22, 2023

While this PR is not problematic per se my impression is that we are kinda cheating here. Wouldn't much better just to introduce a new REMOTEPROC API class / subsystem in Zephyr and use that instead?

This is not a standard - to send a fw ready reply after the remote core is up. This is just for imx use-case.

Others remoteproc Linux drivers (e.g. omap_remoteproc) are sending an echo request and this message will wait in the mailbox fifo until the remote core is up.

Others are doing nothing.

Therefore, there is no "one way fits all" for host-remote handshake communication.
In remoteproc there's no confirmation for remote core booted.

@carlocaione
Copy link
Collaborator

This is not a standard - to send a fw ready reply after the remote core is up. This is just for imx use-case.

Others remoteproc Linux drivers (e.g. omap_remoteproc) are sending an echo request and this message will wait in the mailbox fifo until the remote core is up.

Others are doing nothing.

Therefore, there is no "one way fits all" for host-remote handshake communication. In remoteproc there's no confirmation for remote core booted.

What about the notify hook here https://github.com/OpenAMP/open-amp/blob/5891cb4b2e813d1c9d10def998952b062304e43f/lib/include/openamp/remoteproc.h#L413 ?

I'm not going to NACK this PR, this is fine to me. I'm just trying to understand if there is a generic way to do this.

@iuliana-prodan
Copy link
Collaborator Author

This is not a standard - to send a fw ready reply after the remote core is up. This is just for imx use-case.
Others remoteproc Linux drivers (e.g. omap_remoteproc) are sending an echo request and this message will wait in the mailbox fifo until the remote core is up.
Others are doing nothing.
Therefore, there is no "one way fits all" for host-remote handshake communication. In remoteproc there's no confirmation for remote core booted.

What about the notify hook here https://github.com/OpenAMP/open-amp/blob/5891cb4b2e813d1c9d10def998952b062304e43f/lib/include/openamp/remoteproc.h#L413 ?

This might work if I would have openAMP on host side.
In my case, I have just Linux's remoteproc - https://elixir.bootlin.com/linux/latest/source/include/linux/remoteproc.h#L385, and has no notify().
That's why I said that in Linux there is no confirmation of remote core state.

I'm not going to NACK this PR, this is fine to me. I'm just trying to understand if there is a generic way to do this.

In my opinion, the generic way is to remove the limitation, from imx_dsp_rproc, of waiting for a fw_ready reply - this is not standard and is used only for an internal use case. But, there are still open discussions in upstream on how to handle this in Linux - https://patchwork.kernel.org/project/linux-remoteproc/patch/20230712224251.26482-1-iuliana.prodan@oss.nxp.com/

@arnopo
Copy link
Collaborator

arnopo commented Aug 22, 2023

Agree with @carlocaione,

The handshake should be performed at the application level. It probably relies on a mailbox, but

Today, similar mechanism is done in Linux but from the main to the remote processor. When the virtio device status has been updated. A kick (notify) is sent by Linux rpmsg virtio driver to the coprocessor. The Linux remoteproc is in charge of sending this kick through the mailbox. Associated code is available here: https://elixir.bootlin.com/linux/latest/source/drivers/rpmsg/virtio_rpmsg_bus.c#L995

In this PR the inverse is requested.
So your Linux kernel driver should probably have to block on start waiting a mailbox kick from the coprocessor before initializing the rpmsg.
The coprocessor application (https://elixir.bootlin.com/zephyr/latest/C/ident/rpmsg_mng_task) would be in charge of sending a notification when it is ready to communicate. And then wait the resource table virtio device status update.

Using a config is nice for compatibility with other hardwares

@iuliana-prodan
Copy link
Collaborator Author

Agree with @carlocaione,

The handshake should be performed at the application level. It probably relies on a mailbox, but

Today, similar mechanism is done in Linux but from the main to the remote processor. When the virtio device status has been updated. A kick (notify) is sent by Linux rpmsg virtio driver to the coprocessor. The Linux remoteproc is in charge of sending this kick through the mailbox. Associated code is available here: https://elixir.bootlin.com/linux/latest/source/drivers/rpmsg/virtio_rpmsg_bus.c#L995

The i.MX DSP remoteproc (imx_dsp_rproc) driver is implementing the generic kick callback - https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c and is called after starting the remote core - see https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c#L316.
But, this will return error, because the FW_READY flag was not set (https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c#L291).
This is set on rxdb callback (https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c#L496) which uses general purpose interrupts.

In this PR the inverse is requested. So your Linux kernel driver should probably have to block on start waiting a mailbox kick from the coprocessor before initializing the rpmsg.

It does, as mentioned above (https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c#L344)

The coprocessor application (https://elixir.bootlin.com/zephyr/latest/C/ident/rpmsg_mng_task) would be in charge of sending a notification when it is ready to communicate. And then wait the resource table virtio device status update.

So, @arnopo you're saying I should update the openamp_rsc_table sample?
This already sends a notify (using ipm_send), but is using TX interrupts, while in Linux, I'm waiting for GP interrupts.
So I cannot use the IPM API.

Now, in ipm_imx, I'm calling directly from NXP_HAL the MU_TriggerInterrupts() used for GP interrupts.

Using a config is nice for compatibility with other hardwares

@iuliana-prodan
Copy link
Collaborator Author

Agree with @carlocaione,
The handshake should be performed at the application level. It probably relies on a mailbox, but
Today, similar mechanism is done in Linux but from the main to the remote processor. When the virtio device status has been updated. A kick (notify) is sent by Linux rpmsg virtio driver to the coprocessor. The Linux remoteproc is in charge of sending this kick through the mailbox. Associated code is available here: https://elixir.bootlin.com/linux/latest/source/drivers/rpmsg/virtio_rpmsg_bus.c#L995

The i.MX DSP remoteproc (imx_dsp_rproc) driver is implementing the generic kick callback - https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c and is called after starting the remote core - see https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c#L316. But, this will return error, because the FW_READY flag was not set (https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c#L291). This is set on rxdb callback (https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c#L496) which uses general purpose interrupts.

In this PR the inverse is requested. So your Linux kernel driver should probably have to block on start waiting a mailbox kick from the coprocessor before initializing the rpmsg.

It does, as mentioned above (https://elixir.bootlin.com/linux/latest/source/drivers/remoteproc/imx_dsp_rproc.c#L344)

The coprocessor application (https://elixir.bootlin.com/zephyr/latest/C/ident/rpmsg_mng_task) would be in charge of sending a notification when it is ready to communicate. And then wait the resource table virtio device status update.

So, @arnopo you're saying I should update the openamp_rsc_table sample? This already sends a notify (using ipm_send), but is using TX interrupts, while in Linux, I'm waiting for GP interrupts. So I cannot use the IPM API.

I thought a little bit more and I can expand the IPM API with an ipm_notify().
Give me a couple of days and I'll send a new version to this.

Thanks!

PS: If I won't be able to send it by Friday, I'll do it next week since I'll be OOO :)

@carlocaione
Copy link
Collaborator

I thought a little bit more and I can expand the IPM API with an ipm_notify().

Why? Please don't.

A notify hook has nothing to do with the IPM device class. The IPM API is supposed to support an Inter-Processor communication hardware, a notify hook is something related to your transport protocol, not the hardware.

@iuliana-prodan
Copy link
Collaborator Author

iuliana-prodan commented Aug 22, 2023

I thought a little bit more and I can expand the IPM API with an ipm_notify().

Why? Please don't.

A notify hook has nothing to do with the IPM device class. The IPM API is supposed to support an Inter-Processor communication hardware, a notify hook is something related to your transport protocol, not the hardware.

But then how can I send (actually just set the interrupts I need) the fw reply? This is platform specific.
I add the ipm_notify and this will be implemented where needed - like, for now, only in ipm_imx.

As mention, I cannot use the ipm_send since is using TX interrupts, rather than GP interrupts that are expected in Linux.

@carlocaione
Copy link
Collaborator

But then how can I send (actually just set the interrupts I need) the fw reply? This is platform specific. I add the ipm_notify and this will be implemented where needed - like, for now, only in ipm_imx.

You realize that we cannot arbitrary extend every API device class because some random platform needs something on top right? This being platform specific is exactly the reason this hook makes no sense in the general API class.

You extend an API when the new API is going to support a wide variety of hardware and platforms and, to me, it looks like this is not the case.

The IPM class is about hardware, how do you use this hardware is not the driver concern really. You want something on top of that, an application, a subsystem, a framework, etc... that is using that driver to do something with it (notify, build packets, etc...).

@arnopo
Copy link
Collaborator

arnopo commented Aug 22, 2023

I thought a little bit more and I can expand the IPM API with an ipm_notify().

Why? Please don't.
A notify hook has nothing to do with the IPM device class. The IPM API is supposed to support an Inter-Processor communication hardware, a notify hook is something related to your transport protocol, not the hardware.

But then how can I send (actually just set the interrupts I need) the fw reply? This is platform specific. I add the ipm_notify and this will be implemented where needed - like, for now, only in ipm_imx.

As mention, I cannot use the ipm_send since is using TX interrupts, rather than GP interrupts that are expected in Linux.

What about considering the GP interrupt as a specific channel of the ipm_imx (or a new instance of the ipm)?
you could implement specific action in your ipm_imx based on the channel ID.

Then in application you could define a config that is set to the channel ID value.
if the CONFIG is set the application calls ipm_send(ipm_handle, 0, CONFIG_OPENAMP_RSC_TABLE_KICK_ID, NULL, 0); that trigs the GP interrupt.

@iuliana-prodan iuliana-prodan force-pushed the fw_ready_reply branch 4 times, most recently from b22aa93 to d565a28 Compare August 24, 2023 14:13
Comment on lines 58 to 63
config IPM_SEND_FW_READY_REPLY
hex "Send a FW_READY reply message"
default 0xFFFF
help
Send FW_READY reply to check for FW boot completion

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, so let's say that tomorrow I have a different platform (something custom of course) that needs a new reply type, for example an error messaging kind of thing. Should I add a new Kconfig symbol for that?

This doesn't scale and it is plain wrong.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want you can move this into Kconfig.imx, that would be acceptable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this new version as @arnopo suggested - just for all of us to review it :)
But, I prefer the first version of this PR - adding a config just for IPM_IMX.
Since the fw_ready is waited only for IMX we should fix this limitation only for imx.

@arnopo what do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want you can move this into Kconfig.imx, that would be acceptable.

Yes, I can add it to imx and not modify the openamp_rsc_table sample (main_remote.c) at all.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iuliana-prodan
Regarding your patch seems that my suggestion is not my best one... :(

This solution is not cleaner that your solution.

More than that looking at Shengju comment on Linux remote proc mailing list:
"The reason why wait for a reply in IMX DSP driver is to make sure the DSP
boot successfully and the firmware is correct. ", it looks to me that you need to trig the signal whatever the sample you are running on the remote processor.For instance, the "hello word" sample should also work so trig the signal.

In this case the implementation in IPM or in the openamp_rsc_table application seems not the good solutions.

Is it a way to do it at SoC or board level?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted to my previous version (with small changes on commit message and CONFIG description).

I added the config only for i.MX family.
I enable it only for the board I need (right now this is only for the openamp_rsc_table sample compiled for nxp_adsp_imx8m)

carlocaione
carlocaione previously approved these changes Aug 31, 2023
arnopo
arnopo previously approved these changes Sep 1, 2023
Copy link
Collaborator

@arnopo arnopo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still not convinced that the solution is reliable in the long term (for instance, for a Zephyr project that does not use ipm driver). However, the patch should be able to respond in the short term.

@dbaluta
Copy link
Collaborator

dbaluta commented Sep 1, 2023

I am still not convinced that the solution is reliable in the long term (for instance, for a Zephyr project that does not use ipm driver). However, the patch should be able to respond in the short term.

I'm OK with this for now, as it seems there is no general agreement with Linux folks.

On the long run I think we can make use of struct resource_table https://github.com/OpenAMP/open-amp/blob/e63d07d10577b06c5b3fc8e1c20ede74779d3132/lib/include/openamp/remoteproc.h#L4

We could define a new fw_resource_type for example RSC_PLATFORM.

All application will need to fill this struct with information about expected behavior. Like, kernel should wait for firmware to boot (or not).

It looks like the Linux kernel infrastructure is already in place. What we need to figure out is how to define such structure with open-amp and zephyr.

@arnopo
Copy link
Collaborator

arnopo commented Sep 1, 2023

I am still not convinced that the solution is reliable in the long term (for instance, for a Zephyr project that does not use ipm driver). However, the patch should be able to respond in the short term.

I'm OK with this for now, as it seems there is no general agreement with Linux folks.

On the long run I think we can make use of struct resource_table https://github.com/OpenAMP/open-amp/blob/e63d07d10577b06c5b3fc8e1c20ede74779d3132/lib/include/openamp/remoteproc.h#L4

We could define a new fw_resource_type for example RSC_PLATFORM.

All application will need to fill this struct with information about expected behavior. Like, kernel should wait for firmware to boot (or not).

It looks like the Linux kernel infrastructure is already in place. What we need to figure out is how to define such structure with open-amp and zephyr.

Yes that a way to do it. I don't know if that would cover all use cases (XIP, start by U-boot or secure context, Zephyr <->Zephyr IPC, ...). This would also imply that the resource table is defined for all zephyr samples. But also, that we respect cache line to make the resource table R/W for both processors during the initialization phase.

For your information we started a work in openAMP community to integrate virtio drivers/devices for IPC and the virtio-mmio transport in place of the virtio remoteproc (so no resource table). We identify similar handshake need to ensure that the coprocessor is running before probing the Linux virtio-mmio driver.

That's why synchronization using signaling seems to me more generic. But perhaps we will need different solutions to address all hardwares and use cases.

@iuliana-prodan
Copy link
Collaborator Author

I am still not convinced that the solution is reliable in the long term (for instance, for a Zephyr project that does not use ipm driver). However, the patch should be able to respond in the short term.

I'm OK with this for now, as it seems there is no general agreement with Linux folks.

On the long run I think we can make use of struct resource_table https://github.com/OpenAMP/open-amp/blob/e63d07d10577b06c5b3fc8e1c20ede74779d3132/lib/include/openamp/remoteproc.h#L4

We could define a new fw_resource_type for example RSC_PLATFORM.

All application will need to fill this struct with information about expected behavior. Like, kernel should wait for firmware to boot (or not).

The resource table, both in Linux and Zephyr, uses fw_rsc_vdev struct (meaning RSC_VDEV).
I cannot just add a new one and use that instead or both - this imply a serious refactorization - in Linux and openAMP.
Maybe, you mean to extend the fw_rsc_vdev struct.

Probably, a solution will be to use the config space from fw_rsc_vdev struct,
But this is nowhere (Linux, Zephyr, OpenAMP) used - the config_len is declared 0 and that's all.

It looks like the Linux kernel infrastructure is already in place. What we need to figure out is how to define such structure with open-amp and zephyr.

Where is this? Can you please give me some links?

There is nothing in place, otherwise I would have used it.

dbaluta
dbaluta previously approved these changes Sep 7, 2023
* FW_READY reply.
*/
MU_Type *base = MU(config);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a false positive.

@dleach02
Copy link
Member

@nashif, We appear to have a false-positive on the compliance. What should we do here?

https://github.com/zephyrproject-rtos/zephyr/pull/61709/files#diff-7a9de38974d6ca2f0d251849b385035241af755de445ddee41ab93fb33cd5d25R332

Send a fw ready reply message as soon as possible.
This is usually used on host side which is waiting
for this message in order to establish the
communication with the remote processor - see
imx_dsp_rproc driver from Linux.

This can be enabled by IPM_IMX_FW_READY_REPLY config,
which is by default N.

Set CONFIG_IPM_IMX_FW_READY_REPLY as Y for
openamp_rsc_table sample, running on nxp_adsp_imx8m.

Signed-off-by: Iuliana Prodan <iuliana.prodan@nxp.com>
@iuliana-prodan
Copy link
Collaborator Author

@carlescufi carlescufi requested a review from arnopo September 26, 2023 13:06
@carlescufi
Copy link
Member

@arnopo could you please take another look?

Copy link
Collaborator

@arnopo arnopo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only one minor comment else LGTM

* after starting the remote processor, the host is waiting for a
* FW_READY reply.
*/
MU_Type * base = MU(config);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove space between * and base

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add an extra space to fix a compliance issue - a false positive one - see also this comment #61709 (comment)

I didn't know what else to do in order to have this merged :)

@carlescufi carlescufi merged commit 8148643 into zephyrproject-rtos:main Sep 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: IPC Inter-Process Communication area: IPM Inter-Processor Mailbox platform: NXP NXP
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants