From 7c0b658bd8a0abe0362bc8586af6b1bb1ead363b Mon Sep 17 00:00:00 2001 From: Tanmay Shah Date: Mon, 17 Nov 2025 10:54:10 -0800 Subject: [PATCH] rpmsg_virtio: add new virtio feature bit Introduce new feature bit that allows rpmsg buffer size via virtio device config space. If the feature is available then, driver will set single rpmsg buffer size from virtio device config space in the resource table. New virtio feature allows to configure rpmsg single buffer size via virtio device config space. Hence, rx buffer size can be provided by vdev device config space as well. If BUFSZ feature bit is set, then use rx buffer size from the virtio config space in the resource table. Signed-off-by: Tanmay Shah --- lib/include/openamp/rpmsg_virtio.h | 10 +++++++++- lib/rpmsg/rpmsg_virtio.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/lib/include/openamp/rpmsg_virtio.h b/lib/include/openamp/rpmsg_virtio.h index 1877d2976..2d8ed797d 100644 --- a/lib/include/openamp/rpmsg_virtio.h +++ b/lib/include/openamp/rpmsg_virtio.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ extern "C" { /* The feature bitmap for virtio rpmsg */ #define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */ +#define VIRTIO_RPMSG_F_BUFSZ 1 /* fw provides tx and rx single buf size */ #if defined(VIRTIO_USE_DCACHE) #define BUFFER_FLUSH(x, s) metal_cache_flush(x, s) @@ -59,7 +61,13 @@ struct rpmsg_virtio_shm_pool { * This structure is used by the RPMsg virtio host to configure the virtiio * layer. */ +METAL_PACKED_BEGIN struct rpmsg_virtio_config { + /** version of this struct */ + uint8_t version; + + /** size of the config space */ + uint16_t size; /** The size of the buffer used to send data from host to remote */ uint32_t h2r_buf_size; @@ -68,7 +76,7 @@ struct rpmsg_virtio_config { /** The flag for splitting shared memory pool to TX and RX */ bool split_shpool; -}; +} METAL_PACKED_END; /** @brief Representation of a RPMsg device based on virtio */ struct rpmsg_virtio_device { diff --git a/lib/rpmsg/rpmsg_virtio.c b/lib/rpmsg/rpmsg_virtio.c index ed3f4920c..84559d188 100644 --- a/lib/rpmsg/rpmsg_virtio.c +++ b/lib/rpmsg/rpmsg_virtio.c @@ -62,6 +62,8 @@ struct vbuff_reclaimer_t { #if VIRTIO_ENABLED(VIRTIO_DRIVER_SUPPORT) #define RPMSG_VIRTIO_DEFAULT_CONFIG \ (&(const struct rpmsg_virtio_config) { \ + .version = 1, \ + .size = sizeof(struct rpmsg_virtio_config), \ .h2r_buf_size = RPMSG_BUFFER_SIZE, \ .r2h_buf_size = RPMSG_BUFFER_SIZE, \ .split_shpool = false, \ @@ -742,7 +744,8 @@ int rpmsg_virtio_get_tx_buffer_size(struct rpmsg_device *rdev) int rpmsg_virtio_get_rx_buffer_size(struct rpmsg_device *rdev) { struct rpmsg_virtio_device *rvdev; - int size = 0; + int size = 0, ret; + uint32_t features = 0; if (!rdev) return RPMSG_ERR_PARAM; @@ -762,9 +765,22 @@ int rpmsg_virtio_get_rx_buffer_size(struct rpmsg_device *rdev) /* * If other core is host then buffers are provided by it, * so get the buffer size from the virtqueue. + * If virtio device has BUFSZ feature, then the rx buffer is + * provided by the vdev config space in the resource table. */ - size = (int)virtqueue_get_desc_size(rvdev->rvq) - - sizeof(struct rpmsg_hdr); + features = 0; + ret = virtio_get_features(rvdev->vdev, &features); + if (ret) { + metal_mutex_release(&rdev->lock); + return RPMSG_ERR_DEV_STATE; + } + + if (features & (1 << VIRTIO_RPMSG_F_BUFSZ)) { + size = rvdev->config.r2h_buf_size - sizeof(struct rpmsg_hdr); + } else { + size = (int)virtqueue_get_desc_size(rvdev->rvq) - + sizeof(struct rpmsg_hdr); + } } if (size <= 0) @@ -830,6 +846,13 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev, } if (VIRTIO_ROLE_IS_DEVICE(vdev)) { + status = virtio_get_features(vdev, &features); + if (status) + return status; + + if (features & (1 << VIRTIO_RPMSG_F_BUFSZ)) + rvdev->config = *config; + /* wait synchro with the host */ status = rpmsg_virtio_wait_remote_ready(rvdev); if (status)