Skip to content

Commit

Permalink
virtio: add alloc_buf/free_buf in virtio ops
Browse files Browse the repository at this point in the history
Buffer management is different for different transport layer:

For MMIO transport layer, the buffer can direclty malloced from
the gust os heap beacase the hypervisor can access all the memmory own
by guest os.

For remoteproc transpor layer, the buffer should be malloced from
the share memory region to make sure the remote core can access this
buffer too.

So add alloc_buf/free_buf in virtio ops to make different transport can
implement their own share memory management:
1. add alloc_buf/free_buf api in virtio ops;
2. support the alloc_buf/free_buf for remoteproc transport layer;

Signed-off-by: Bowen Wang <[email protected]>
  • Loading branch information
CV-Bowen committed Sep 14, 2024
1 parent c468328 commit 58d5fac
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
26 changes: 26 additions & 0 deletions lib/include/openamp/remoteproc_virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ extern "C" {
/* define vdev notification function user should implement */
typedef int (*rpvdev_notify_func)(void *priv, uint32_t id);

/* Define remoteproc virtio memory management function */
struct remoteproc_virtio;
typedef void *(*rpvdev_alloc_buf)(struct remoteproc_virtio *rpvdev, size_t size, size_t align);
typedef void (*rpvdev_free_buf)(struct remoteproc_virtio *rpvdev, void *buf);

/** @brief Virtio structure for remoteproc instance */
struct remoteproc_virtio {
/** Pointer to private data */
Expand All @@ -56,6 +61,12 @@ struct remoteproc_virtio {
/** Virtio device */
struct virtio_device vdev;

/** Share memory alloc function */
rpvdev_alloc_buf alloc_buf;

/** Share memory free function */
rpvdev_free_buf free_buf;

/** List node */
struct metal_list node;
};
Expand Down Expand Up @@ -126,6 +137,21 @@ int rproc_virtio_notified(struct virtio_device *vdev, uint32_t notifyid);
*/
void rproc_virtio_wait_remote_ready(struct virtio_device *vdev);

/**
* rproc_virtio_set_mm_callback
*
* Set the share memory management callback function
*
* @param vdev Pointer to the virtio device
* @param alloc_buf Alloc buffer callback function
* @param free_buf Free buffer callback function
*
* return 0 for success, negative value for failure.
*/
int rproc_virtio_set_mm_callback(struct virtio_device *vdev,
rpvdev_alloc_buf alloc_buf,
rpvdev_free_buf free_buf);

#if defined __cplusplus
}
#endif
Expand Down
54 changes: 54 additions & 0 deletions lib/include/openamp/virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ __deprecated void virtio_describe(struct virtio_device *dev, const char *msg,
*/

struct virtio_dispatch {
/** Alloc buffer from transport layer heap */
void *(*alloc_buf)(struct virtio_device *vdev, size_t size, size_t align);

/** Free buffer to transport layer heap */
void (*free_buf)(struct virtio_device *vdev, void *buf);

/** Create virtio queue instances. */
int (*create_virtqueues)(struct virtio_device *vdev,
unsigned int flags,
Expand Down Expand Up @@ -282,6 +288,54 @@ struct virtio_dispatch {
void (*notify)(struct virtqueue *vq);
};

/**
* @brief Alloc a buffer from virtio transport layer.
*
* @param vdev Pointer to virtio device structure.
* @param size Alloc buffer size.
* @param align Buffer alignment.
*
* @return Pointer to the return buffer. NULL indicates no enough buffer
* or some errors happened.
*/
static inline void *virtio_alloc_buf(struct virtio_device *vdev,
size_t size, size_t align)
{
return vdev->func->alloc_buf(vdev, size, align);
}

/**
* @brief Alloc a buffer from virtio transport layer with zero value.
*
* @param vdev Pointer to virtio device structure.
* @param size Alloc buffer size.
* @param align Buffer alignment.
*
* @return Pointer to the return buffer. NULL indicates no enough buffer
* or some errors happened.
*/
static inline void *virtio_zalloc_buf(struct virtio_device *vdev,
size_t size, size_t align)
{
void *ptr = virtio_alloc_buf(vdev, size, align);

if (ptr)
memset(ptr, 0, size);

return ptr;
}

/**
* @brief Free a buffer alloced from transport layer.
*
* @param vdev Pointer to virtio device structure.
* @param buf Pointer to an allocated buffer from transport layer.
*/
static inline void virtio_free_buf(struct virtio_device *vdev, void *buf)
{
vdev->func->free_buf(vdev, buf);
}

/**
* @brief Create the virtio device virtqueue.
*
Expand Down
41 changes: 41 additions & 0 deletions lib/remoteproc/remoteproc_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,29 @@
#include <metal/utilities.h>
#include <metal/alloc.h>

static void *rproc_virtio_alloc_buf(struct virtio_device *vdev,
size_t size, size_t align)
{
struct remoteproc_virtio *rpvdev;

rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
if (!rpvdev->alloc_buf)
return NULL;

return rpvdev->alloc_buf(rpvdev, size, align);
}

static void rproc_virtio_free_buf(struct virtio_device *vdev, void *buf)
{
struct remoteproc_virtio *rpvdev;

rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
if (!rpvdev->free_buf)
return;

rpvdev->free_buf(rpvdev, buf);
}

static void rproc_virtio_delete_virtqueues(struct virtio_device *vdev)
{
struct virtio_vring_info *vring_info;
Expand Down Expand Up @@ -265,6 +288,8 @@ static void rproc_virtio_reset_device(struct virtio_device *vdev)
#endif

static const struct virtio_dispatch remoteproc_virtio_dispatch_funcs = {
.alloc_buf = rproc_virtio_alloc_buf,
.free_buf = rproc_virtio_free_buf,
.create_virtqueues = rproc_virtio_create_virtqueues,
.delete_virtqueues = rproc_virtio_delete_virtqueues,
.get_status = rproc_virtio_get_status,
Expand Down Expand Up @@ -415,3 +440,19 @@ void rproc_virtio_wait_remote_ready(struct virtio_device *vdev)
metal_cpu_yield();
}
}

int rproc_virtio_set_mm_callback(struct virtio_device *vdev,
rpvdev_alloc_buf alloc_buf,
rpvdev_free_buf free_buf)
{
struct remoteproc_virtio *rpvdev;

if (!vdev || !alloc_buf || !free_buf)
return -RPROC_EINVAL;

rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
rpvdev->alloc_buf = alloc_buf;
rpvdev->free_buf = free_buf;

return 0;
}

0 comments on commit 58d5fac

Please sign in to comment.