From 6812ef458d9987f250b36df43e9dd9c97171c682 Mon Sep 17 00:00:00 2001 From: Tanmay Shah Date: Fri, 13 Mar 2026 10:26:54 -0700 Subject: [PATCH 1/2] legacy_apps: xlnx: add api to poll apps on vdev status In case of the remoteproc repeat attach-detach, RPU firmware should be able to re-create the virtio devices. For this, the firmware should poll on the vdev status, and if the status is 0, then it should destroy the virtio and rpmsg devices. Then it should re-create them and wait for next driver ready status from the linux kernel. The vdev status 0 is usually done during remoteproc detach operation. Mailbox notification is expected from the Linux side on vdev status reset. Signed-off-by: Tanmay Shah --- .../legacy_apps/examples/echo/rpmsg-echo.c | 12 ++---- .../matrix_multiply/matrix_multiplyd.c | 12 ++---- .../machine/xlnx/zynqmp_r5/platform_info.c | 39 ++++++++++++++++--- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/examples/legacy_apps/examples/echo/rpmsg-echo.c b/examples/legacy_apps/examples/echo/rpmsg-echo.c index 2a6b232e..5e659b7b 100644 --- a/examples/legacy_apps/examples/echo/rpmsg-echo.c +++ b/examples/legacy_apps/examples/echo/rpmsg-echo.c @@ -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); + if (ret) + metal_err("platform poll failed err = %d\n", ret); rpmsg_destroy_ept(&lept); - return 0; + return ret; } /*-----------------------------------------------------------------------------* diff --git a/examples/legacy_apps/examples/matrix_multiply/matrix_multiplyd.c b/examples/legacy_apps/examples/matrix_multiply/matrix_multiplyd.c index 8a6fb6ab..4954d3a8 100644 --- a/examples/legacy_apps/examples/matrix_multiply/matrix_multiplyd.c +++ b/examples/legacy_apps/examples/matrix_multiply/matrix_multiplyd.c @@ -113,16 +113,12 @@ int rpmsg_matrix_app(struct rpmsg_device *rdev, void *priv) RPMSG_SERVICE_NAME, lept.addr, lept.dest_addr); LPRINTF("Waiting for events...\r\n"); - while(1) { - platform_poll(priv); - /* we got a shutdown request, exit */ - if (shutdown_req) { - break; - } - } + ret = platform_poll(priv); + if (ret) + metal_err("platform_poll failed with error %d\n", ret); rpmsg_destroy_ept(&lept); - return 0; + return ret; } /*-----------------------------------------------------------------------------* diff --git a/examples/legacy_apps/machine/xlnx/zynqmp_r5/platform_info.c b/examples/legacy_apps/machine/xlnx/zynqmp_r5/platform_info.c index 560e3451..0e21cecc 100644 --- a/examples/legacy_apps/machine/xlnx/zynqmp_r5/platform_info.c +++ b/examples/legacy_apps/machine/xlnx/zynqmp_r5/platform_info.c @@ -29,6 +29,7 @@ #include #include #include +#include #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); + return 0; } From 46088021696076ce78f9a6be83e70f1a5894b92c Mon Sep 17 00:00:00 2001 From: Tanmay Shah Date: Fri, 27 Mar 2026 11:41:50 -0700 Subject: [PATCH 2/2] legacy_apps: recreate rpmsg devices after vdev reset echo and matrix multiply apps were not able to run after attach()->detach()->attach() command sequence from linux side. Solve this problem, by not stopping app, and re-creating rpmsg devices after detection of vdev reset. This allows the app to run again on next callback when linux sets DRIVER_OK bit. Signed-off-by: Tanmay Shah --- .../legacy_apps/examples/echo/freertos/main.c | 11 +++++--- .../legacy_apps/examples/echo/generic/main.c | 25 +++++++++--------- .../legacy_apps/examples/echo/rpmsg-echo.c | 26 +++++++++++-------- .../examples/matrix_multiply/freertos/main.c | 12 ++++----- .../examples/matrix_multiply/generic/main.c | 24 +++++++++-------- .../matrix_multiply/matrix_multiplyd.c | 15 ++++++----- 6 files changed, 63 insertions(+), 50 deletions(-) diff --git a/examples/legacy_apps/examples/echo/freertos/main.c b/examples/legacy_apps/examples/echo/freertos/main.c index 04ba1efb..8f96be46 100644 --- a/examples/legacy_apps/examples/echo/freertos/main.c +++ b/examples/legacy_apps/examples/echo/freertos/main.c @@ -48,18 +48,21 @@ static void rpmsg_listen_task(void *arg) LPRINTF("libmetal lib version: %s\n", metal_ver()); LPRINTF("Starting application...\r\n"); - while (1) { + do { rpdev = platform_create_rpmsg_vdev(platform, 0, VIRTIO_DEV_DEVICE, NULL, NULL); if (!rpdev) { LPERROR("Failed to create rpmsg virtio device.\r\n"); - break; + ret = 0; } else { - rpmsg_echo_app(rpdev, platform); + ret = rpmsg_echo_app(rpdev, platform); + if (ret) + metal_err("rpmsg_echo_app failed with err, %d\n", + ret); platform_release_rpmsg_vdev(rpdev, platform); } - } + } while (!ret); LPRINTF("Stopping application...\r\n"); platform_cleanup(platform); diff --git a/examples/legacy_apps/examples/echo/generic/main.c b/examples/legacy_apps/examples/echo/generic/main.c index db2035f2..d9c21d92 100644 --- a/examples/legacy_apps/examples/echo/generic/main.c +++ b/examples/legacy_apps/examples/echo/generic/main.c @@ -32,22 +32,23 @@ int main(int argc, char *argv[]) return ret; } - LPRINTF("openamp lib version: %s\n", openamp_version()); 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_echo_app(rpdev, platform); - platform_release_rpmsg_vdev(rpdev, platform); - ret = 0; - } + /* support repeate attach-detach by recreating virtio devices on vdev reset */ + 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 = -1; + } else { + ret = rpmsg_echo_app(rpdev, platform); + platform_release_rpmsg_vdev(rpdev, platform); + } + } while (!ret); LPRINTF("Stopping application...\r\n"); platform_cleanup(platform); diff --git a/examples/legacy_apps/examples/echo/rpmsg-echo.c b/examples/legacy_apps/examples/echo/rpmsg-echo.c index 5e659b7b..ed5acd22 100644 --- a/examples/legacy_apps/examples/echo/rpmsg-echo.c +++ b/examples/legacy_apps/examples/echo/rpmsg-echo.c @@ -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, @@ -118,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); diff --git a/examples/legacy_apps/examples/matrix_multiply/freertos/main.c b/examples/legacy_apps/examples/matrix_multiply/freertos/main.c index c64bd02f..bdb1ebd7 100644 --- a/examples/legacy_apps/examples/matrix_multiply/freertos/main.c +++ b/examples/legacy_apps/examples/matrix_multiply/freertos/main.c @@ -46,18 +46,18 @@ static void rpmsg_listen_task(__attribute__((unused)) void *arg) LPRINTF("Starting application...\r\n"); - while (1) { + do { rpdev = platform_create_rpmsg_vdev(platform, 0, VIRTIO_DEV_DEVICE, NULL, NULL); if (!rpdev) { LPERROR("Failed to create rpmsg virtio device.\r\n"); - break; + ret = -EINVAL; + } else { + ret = rpmsg_matrix_app(rpdev, platform); + platform_release_rpmsg_vdev(rpdev, platform); } - - rpmsg_matrix_app(rpdev, platform); - platform_release_rpmsg_vdev(rpdev, platform); - } + } while (!ret); LPRINTF("Stopping application...\r\n"); platform_cleanup(platform); diff --git a/examples/legacy_apps/examples/matrix_multiply/generic/main.c b/examples/legacy_apps/examples/matrix_multiply/generic/main.c index f3a3ee8e..206af3be 100644 --- a/examples/legacy_apps/examples/matrix_multiply/generic/main.c +++ b/examples/legacy_apps/examples/matrix_multiply/generic/main.c @@ -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; + } else { + ret = rpmsg_matrix_app(rpdev, platform); + platform_release_rpmsg_vdev(rpdev, platform); + } + } while (!ret); LPRINTF("Stopping application...\r\n"); platform_cleanup(platform); diff --git a/examples/legacy_apps/examples/matrix_multiply/matrix_multiplyd.c b/examples/legacy_apps/examples/matrix_multiply/matrix_multiplyd.c index 4954d3a8..0abd6bf9 100644 --- a/examples/legacy_apps/examples/matrix_multiply/matrix_multiplyd.c +++ b/examples/legacy_apps/examples/matrix_multiply/matrix_multiplyd.c @@ -105,7 +105,7 @@ int rpmsg_matrix_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, @@ -136,20 +136,23 @@ int __attribute__((weak)) main(int argc, char *argv[]) ret = platform_init(argc, argv, &platform); if (ret) { LPERROR("Failed to initialize platform.\r\n"); - ret = -1; - } else { + return ret; + } + + 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 = -1; + ret = -EINVAL; } else { - rpmsg_matrix_app(rpdev, platform); + ret = rpmsg_matrix_app(rpdev, platform); platform_release_rpmsg_vdev(rpdev, platform); - ret = 0; } + LPRINTF("creating rpmsg vdev devices again\r\n"); } + while (!ret); LPRINTF("Stopping application...\r\n"); platform_cleanup(platform);