From 4ace3543aea62d9356dec5f044111187a8691190 Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Mon, 12 Aug 2024 10:15:24 +0800 Subject: [PATCH] virtio: Add memory operation interface for virtio device Buffer management is different for different transport layer: For MMIO transport layer, the buffer can directly allocated from the geust OS heap beacase the hypervisor can access all the memory own by guest OS. For remoteproc transport layer, the buffer should be allocated from the share memory region to make sure the remote core can access this buffer too. So add memory ops in virtio device to make different transport/device can implement their own share memory management. Signed-off-by: Bowen Wang --- lib/include/openamp/virtio.h | 60 ++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/lib/include/openamp/virtio.h b/lib/include/openamp/virtio.h index 278d2da7..0e366314 100644 --- a/lib/include/openamp/virtio.h +++ b/lib/include/openamp/virtio.h @@ -152,6 +152,7 @@ struct virtio_device_id { typedef void (*virtio_dev_reset_cb)(struct virtio_device *vdev); struct virtio_dispatch; +struct virtio_memory_ops; /** @brief Device features. */ struct virtio_feature_desc { @@ -197,6 +198,9 @@ struct virtio_device { /** Virtio dispatch table */ const struct virtio_dispatch *func; + /**< Virtio device memory operations */ + const struct virtio_memory_ops *mmops; + /** Private data */ void *priv; @@ -282,6 +286,14 @@ struct virtio_dispatch { void (*notify)(struct virtqueue *vq); }; +struct virtio_memory_ops { + /** Allocate memory from the virtio device. */ + void *(*alloc)(struct virtio_device *dev, size_t size, size_t align); + + /** Free memory allocated from the virtio device. */ + void (*free)(struct virtio_device *dev, void *buf); +}; + /** * @brief Create the virtio device virtqueue. * @@ -499,6 +511,54 @@ static inline int virtio_reset_device(struct virtio_device *vdev) return 0; } +/** + * @brief Allocate buffer from the virtio device + * + * @param vdev Pointer to virtio device structure. + * @param buf Pointer to the allocated buffer (virtual address). + * @param size Allocated buffer size. + * @param align Allocated buffer alignment. + * + * @return 0 on success, otherwise error code. + */ +static inline int virtio_alloc_buf(struct virtio_device *vdev, void **buf, + size_t size, size_t align) +{ + if (!vdev || !buf) + return -EINVAL; + + if (!vdev->mmops || !vdev->mmops->alloc) + return -ENXIO; + + *buf = vdev->mmops->alloc(vdev, size, align); + if (!*buf) + return -ENOMEM; + + return 0; +} + +/** + * @brief Free the buffer allocated by \ref virtio_alloc_buf from the virtio + * device. + * + * @param vdev Pointer to virtio device structure. + * @param buf Buffer need to be freed. + * + * @return 0 on success, otherwise error code. + */ +static inline int virtio_free_buf(struct virtio_device *vdev, void *buf) +{ + if (!vdev) + return -EINVAL; + + if (!vdev->mmops || !vdev->mmops->free) + return -ENXIO; + + vdev->mmops->free(vdev, buf); + + return 0; +} + #if defined __cplusplus } #endif