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)