Skip to content

Commit

Permalink
virtio: decoupling the transport layer and virtio device layer
Browse files Browse the repository at this point in the history
Add virtio device apis to decouple the transport layer and virtio
device layer.

Signed-off-by: Bowen Wang <[email protected]>
  • Loading branch information
Bowen Wang authored and CV-Bowen committed May 15, 2023
1 parent 710de81 commit 8c60cb6
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 45 deletions.
4 changes: 2 additions & 2 deletions lib/include/openamp/rpmsg_virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ rpmsg_virtio_create_virtqueues(struct rpmsg_virtio_device *rvdev,
const char *names[],
vq_callback *callbacks)
{
return virtio_create_virtqueues(rvdev->vdev, flags, nvqs, names,
callbacks);
return rvdev->vdev->func->create_virtqueues(rvdev->vdev, flags, nvqs,
names, callbacks);
}

/**
Expand Down
146 changes: 143 additions & 3 deletions lib/include/openamp/virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ void virtio_describe(struct virtio_device *dev, const char *msg,
*/

struct virtio_dispatch {
int (*create_virtqueues)(struct virtio_device *vdev,
unsigned int flags,
unsigned int nvqs, const char *names[],
vq_callback callbacks[]);
void (*delete_virtqueues)(struct virtio_device *vdev);
uint8_t (*get_status)(struct virtio_device *dev);
void (*set_status)(struct virtio_device *dev, uint8_t status);
uint32_t (*get_features)(struct virtio_device *dev);
Expand All @@ -181,9 +186,144 @@ struct virtio_dispatch {
void (*notify)(struct virtqueue *vq);
};

int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
unsigned int nvqs, const char *names[],
vq_callback callbacks[]);
/**
* @brief Create the virtio device virtqueue.
*
* @param[in] vdev Pointer to virtio device structure.
* @param[in] flags Create flag.
* @param[in] nvqs The virtqueue number.
* @param[in] names Virtqueue names.
* @param[in] callbacks Virtqueue callback functions.
*
* @return pointer to virtio device structure.
*/

static inline int
virtio_device_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
unsigned int nvqs, const char *names[],
vq_callback callbacks[])
{
return vdev->func->create_virtqueues(vdev, flags, nvqs, names,
callbacks);
}

/**
* @brief Delete the virtio device virtqueue.
*
* @param[in] vdev Pointer to virtio device structure.
*
* @return pointer to virtio device structure.
*/

static inline void
virtio_device_delete_virtqueues(struct virtio_device *vdev)
{
return vdev->func->delete_virtqueues ?
vdev->func->delete_virtqueues(vdev) : -ENXIO;
}

/**
* @brief Retrieve device status.
*
* @param[in] dev Pointer to device structure.
*
* @return status of the device.
*/

static inline uint8_t virtio_device_get_status(struct virtio_device *vdev)
{
return vdev->func->get_status(vdev);
}

/**
* @brief Set device status.
*
* @param[in] dev Pointer to device structure.
* @param[in] status Value to be set as device status.
*
* @return N/A.
*/

static inline void virtio_device_set_status(struct virtio_device *vdev,
uint8_t status)
{
vdev->func->set_status(vdev, status);
}

/**
* @brief Retrieve configuration data from the device.
*
* @param[in] dev Pointer to device structure.
* @param[in] offset Offset of the data within the configuration area.
* @param[in] dst Address of the buffer that will hold the data.
* @param[in] len Length of the data to be retrieved.
*
* @return N/A.
*/

static inline void virtio_device_read_config(struct virtio_device *vdev,
uint32_t offset, void *dst,
int length)
{
vdev->func->read_config(vdev, offset, dst, length);
}

/**
* @brief Write configuration data to the device.
*
* @param[in] dev Pointer to device structure.
* @param[in] offset Offset of the data within the configuration area.
* @param[in] src Address of the buffer that holds the data to write.
* @param[in] len Length of the data to be written.
*
* @return N/A.
*/

static inline void virtio_device_write_config(struct virtio_device *vdev,
uint32_t offset, void *src,
int length)
{
vdev->func->write_config(vdev, offset, src, length);
}

/**
* @brief Retrieve features supported by both the VIRTIO driver and the VIRTIO device.
*
* @param[in] dev Pointer to device structure.
*
* @return Features supported by both the driver and the device as a bitfield.
*/

static inline uint32_t virtio_device_get_features(struct virtio_device *vdev)
{
return vdev->func->get_features(vdev);
}

/**
* @brief Set features supported by the VIRTIO driver.
*
* @param[in] dev Pointer to device structure.
* @param[in] features Features supported by the driver as a bitfield.
*
* @return N/A.
*/

static inline void virtio_device_set_features(struct virtio_device *vdev,
uint32_t features)
{
return vdev->func->set_features(vdev, features);
}

/**
* @brief Reset virtio device.
* @param[in] vdev Pointer to virtio_device structure.
* @return N/A.
*/

static inline void virtio_device_reset(struct virtio_device *vdev)
{
vdev->func->reset_device(vdev);
}

#if defined __cplusplus
}
Expand Down
42 changes: 42 additions & 0 deletions lib/remoteproc/remoteproc_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,47 @@
#include <metal/utilities.h>
#include <metal/alloc.h>

static int rproc_virtio_create_virtqueues(struct virtio_device *vdev,
unsigned int flags,
unsigned int nvqs,
const char *names[],
vq_callback callbacks[])
{
struct virtio_vring_info *vring_info;
struct vring_alloc_info *vring_alloc;
unsigned int num_vrings, i;
int ret;
(void)flags;

num_vrings = vdev->vrings_num;
if (nvqs > num_vrings)
return ERROR_VQUEUE_INVLD_PARAM;
/* Initialize virtqueue for each vring */
for (i = 0; i < nvqs; i++) {
vring_info = &vdev->vrings_info[i];

vring_alloc = &vring_info->info;
#ifndef VIRTIO_DEVICE_ONLY
if (vdev->role == VIRTIO_DEV_DRIVER) {
size_t offset;
struct metal_io_region *io = vring_info->io;

offset = metal_io_virt_to_offset(io,
vring_alloc->vaddr);
metal_io_block_set(io, offset, 0,
vring_size(vring_alloc->num_descs,
vring_alloc->align));
}
#endif
ret = virtqueue_create(vdev, i, names[i], vring_alloc,
callbacks[i], vdev->func->notify,
vring_info->vq);
if (ret)
return ret;
}
return 0;
}

static void rproc_virtio_virtqueue_notify(struct virtqueue *vq)
{
struct remoteproc_virtio *rpvdev;
Expand Down Expand Up @@ -175,6 +216,7 @@ static void rproc_virtio_reset_device(struct virtio_device *vdev)
#endif

static const struct virtio_dispatch remoteproc_virtio_dispatch_funcs = {
.create_virtqueues = rproc_virtio_create_virtqueues,
.get_status = rproc_virtio_get_status,
.get_features = rproc_virtio_get_features,
.read_config = rproc_virtio_read_config,
Expand Down
40 changes: 0 additions & 40 deletions lib/virtio/virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,43 +96,3 @@ void virtio_describe(struct virtio_device *dev, const char *msg,
/* TODO: Not used currently - keeping it for future use*/
virtio_feature_name(0, desc);
}

int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
unsigned int nvqs, const char *names[],
vq_callback callbacks[])
{
struct virtio_vring_info *vring_info;
struct vring_alloc_info *vring_alloc;
unsigned int num_vrings, i;
int ret;
(void)flags;

num_vrings = vdev->vrings_num;
if (nvqs > num_vrings)
return ERROR_VQUEUE_INVLD_PARAM;
/* Initialize virtqueue for each vring */
for (i = 0; i < nvqs; i++) {
vring_info = &vdev->vrings_info[i];

vring_alloc = &vring_info->info;
#ifndef VIRTIO_DEVICE_ONLY
if (vdev->role == VIRTIO_DEV_DRIVER) {
size_t offset;
struct metal_io_region *io = vring_info->io;

offset = metal_io_virt_to_offset(io,
vring_alloc->vaddr);
metal_io_block_set(io, offset, 0,
vring_size(vring_alloc->num_descs,
vring_alloc->align));
}
#endif
ret = virtqueue_create(vdev, i, names[i], vring_alloc,
callbacks[i], vdev->func->notify,
vring_info->vq);
if (ret)
return ret;
}
return 0;
}

0 comments on commit 8c60cb6

Please sign in to comment.