-
Notifications
You must be signed in to change notification settings - Fork 20
legacy_apps: xlnx: add api to poll apps on vdev status #100
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,7 +72,7 @@ int rpmsg_echo_app(struct rpmsg_device *rdev, void *priv) | |
| rpmsg_service_unbind); | ||
| if (ret) { | ||
| LPERROR("Failed to create endpoint.\r\n"); | ||
| return -1; | ||
| return ret; | ||
| } | ||
|
|
||
| metal_log(METAL_LOG_NOTICE, | ||
|
|
@@ -82,16 +82,12 @@ int rpmsg_echo_app(struct rpmsg_device *rdev, void *priv) | |
| metal_dbg("RPMsg device TX buffer size: %#x\r\n", rpmsg_get_tx_buffer_size(&lept)); | ||
| metal_dbg("RPMsg device RX buffer size: %#x\r\n", rpmsg_get_rx_buffer_size(&lept)); | ||
|
|
||
| while(1) { | ||
| platform_poll(priv); | ||
| /* we got a shutdown request, exit */ | ||
| if (shutdown_req) { | ||
| break; | ||
| } | ||
| } | ||
| ret = platform_poll(priv); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This make break all machines implementation not only the AMD ones.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know how it can break. Remote firmware will still work as it is.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not tested but, , for instance, seems not compatible with following codes: |
||
| if (ret) | ||
| metal_err("platform poll failed err = %d\n", ret); | ||
| rpmsg_destroy_ept(&lept); | ||
|
|
||
| return 0; | ||
| return ret; | ||
| } | ||
|
|
||
| /*-----------------------------------------------------------------------------* | ||
|
|
@@ -122,17 +118,21 @@ int __attribute__((weak)) main(int argc, char *argv[]) | |
|
|
||
| LPRINTF("Starting application...\r\n"); | ||
|
|
||
| rpdev = platform_create_rpmsg_vdev(platform, 0, | ||
| VIRTIO_DEV_DEVICE, | ||
| NULL, NULL); | ||
| if (!rpdev) { | ||
| LPERROR("Failed to create rpmsg virtio device.\r\n"); | ||
| ret = -1; | ||
| } else { | ||
| rpmsg_echo_app(rpdev, platform); | ||
| platform_release_rpmsg_vdev(rpdev, platform); | ||
| /* keep repeating application until it fails */ | ||
| do { | ||
| ret = 0; | ||
| } | ||
| rpdev = platform_create_rpmsg_vdev(platform, 0, | ||
| VIRTIO_DEV_DEVICE, | ||
| NULL, NULL); | ||
| if (!rpdev) { | ||
| LPERROR("Failed to create rpmsg virtio device.\r\n"); | ||
| ret = -1; | ||
| } else { | ||
| ret = rpmsg_echo_app(rpdev, platform); | ||
| platform_release_rpmsg_vdev(rpdev, platform); | ||
| } | ||
| LPRINTF("Creating vdev devices again\r\n"); | ||
| } while (!ret); | ||
|
|
||
| LPRINTF("Stopping application...\r\n"); | ||
| platform_cleanup(platform); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,17 +36,19 @@ int main(int argc, char *argv[]) | |
| LPRINTF("libmetal lib version: %s\n", metal_ver()); | ||
| LPRINTF("Starting application...\r\n"); | ||
|
|
||
| rpdev = platform_create_rpmsg_vdev(platform, 0, | ||
| VIRTIO_DEV_DEVICE, | ||
| NULL, NULL); | ||
| if (!rpdev) { | ||
| LPERROR("Failed to create rpmsg virtio device.\r\n"); | ||
| ret = -1; | ||
| } else { | ||
| rpmsg_matrix_app(rpdev, platform); | ||
| platform_release_rpmsg_vdev(rpdev, platform); | ||
| ret = 0; | ||
| } | ||
| /* on vdev reset, recreate rpmsg devices */ | ||
| do { | ||
| rpdev = platform_create_rpmsg_vdev(platform, 0, | ||
| VIRTIO_DEV_DEVICE, | ||
| NULL, NULL); | ||
| if (!rpdev) { | ||
| LPERROR("Failed to create rpmsg virtio device.\r\n"); | ||
| ret = -EINVAL; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sometime |
||
| } else { | ||
| ret = rpmsg_matrix_app(rpdev, platform); | ||
| platform_release_rpmsg_vdev(rpdev, platform); | ||
| } | ||
| } while (!ret); | ||
|
|
||
| LPRINTF("Stopping application...\r\n"); | ||
| platform_cleanup(platform); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,7 @@ | |
| #include <metal/sys.h> | ||
| #include <metal/utilities.h> | ||
| #include <openamp/rpmsg_virtio.h> | ||
| #include <openamp/virtio.h> | ||
|
|
||
| #include "platform_info.h" | ||
| #include "rsc_table.h" | ||
|
|
@@ -414,20 +415,42 @@ platform_create_rpmsg_vdev(void *platform, unsigned int vdev_index, | |
|
|
||
| int platform_poll(void *priv) | ||
| { | ||
| struct rpmsg_virtio_device *rpmsg_vdev; | ||
| struct remoteproc_virtio *rproc_vdev; | ||
| struct remoteproc *rproc = priv; | ||
| struct remoteproc_priv *prproc; | ||
| struct metal_list *node; | ||
| uint8_t vdev_status = 0; | ||
| unsigned int flags; | ||
| int ret; | ||
|
|
||
| prproc = rproc->priv; | ||
| while(1) { | ||
| /* If vdev reset is issued, then stop polling */ | ||
| node = metal_list_first(&rproc->vdevs); | ||
| if (!node) { | ||
| metal_err("failed to get rproc_vdev node\n"); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| rproc_vdev = metal_container_of(node, | ||
| struct remoteproc_virtio, | ||
| node); | ||
| rpmsg_vdev = rproc_vdev->vdev.priv; | ||
| if (!rpmsg_vdev) { | ||
| metal_err("failed to get rpmsg_vdev\n"); | ||
| return -ENODEV; | ||
| } | ||
| if (!rpmsg_vdev->vdev) { | ||
| metal_err("failed to get virtio device\n"); | ||
| return -ENODEV; | ||
| } | ||
| do { | ||
| #ifdef RPMSG_NO_IPI | ||
| if (metal_io_read32(prproc->kick_io, 0)) { | ||
| ret = remoteproc_get_notification(rproc, | ||
| RSC_NOTIFY_ID_ANY); | ||
| if (ret) | ||
| return ret; | ||
| break; | ||
| } | ||
| (void)flags; | ||
| #else /* !RPMSG_NO_IPI */ | ||
|
|
@@ -438,12 +461,18 @@ int platform_poll(void *priv) | |
| RSC_NOTIFY_ID_ANY); | ||
| if (ret) | ||
| return ret; | ||
| break; | ||
| } | ||
| system_suspend(); | ||
| metal_irq_restore_enable(flags); | ||
| system_suspend(); | ||
| #endif /* RPMSG_NO_IPI */ | ||
| } | ||
|
|
||
| ret = virtio_get_status(rpmsg_vdev->vdev, &vdev_status); | ||
| if (ret) { | ||
| metal_err("failed to get vdev status %d\n", ret); | ||
| return ret; | ||
| } | ||
| } while (vdev_status); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Except if I miss something this breaks the virtio spec protocol. The virtio driver must not set the status to 0. here the sequence should be
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So as per this virtio standard, this behavior is already broken in the linux kernel side. Because today we see virtio status set to 0 on
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes you are right, the Linux should not clean the vdev, status
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about this. We keep polling up until DRIVER_OKAY bit is set by the linux. If it's not setup anymore, then we stop polling. I think that's not breaking the virtio standard.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Actually, that's not a good idea too. Because as per the spec, driver can't choose specific bits to reset. Instead to reset the device, driver will set the status 0. So, are we not resetting the device when we issue detach() command?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From my point of view, we should think with a system-level approach rather than going with a temporary solution. What about a solution based on a new status in the resource table, as discussed during the last OpenAMP RP call? We should probably discuss the solution on the Linux kernel side before moving forward with this PR. The fact that Linux does not respect the virtio specification should help us reach a solution.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @arnopo Yes that's what I was thinking too. The only problem is the backward compatibility from the linux standpoint. If we implement the new status based on the resource table, and the remote firmware is polling based on current vdev status, then we may break the existing firmwares. So, I was thinking in the linux side: if (new_vdev_status in rsc tbl) then: We can discuss this in the next system-reference or rp call. Which comes first. |
||
|
|
||
| return 0; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.