Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

virtio: add create_virtqueues and delete_virtqueues in virtio_dispatch #495

Merged
merged 1 commit into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 207 additions & 0 deletions lib/include/openamp/virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define _VIRTIO_H_

#include <openamp/virtqueue.h>
#include <metal/errno.h>
#include <metal/spinlock.h>

#if defined __cplusplus
Expand Down Expand Up @@ -176,6 +177,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 @@ -196,10 +202,211 @@ struct virtio_dispatch {
void (*notify)(struct virtqueue *vq);
};

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

/**
* @brief Delete the virtio device virtqueue.
*
* @param vdev Pointer to virtio device structure.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_delete_virtqueues(struct virtio_device *vdev)
{
if (!vdev)
return -EINVAL;

if (!vdev->func || !vdev->func->delete_virtqueues)
return -ENXIO;

vdev->func->delete_virtqueues(vdev);
return 0;
}

/**
* @brief Retrieve device status.
*
* @param dev Pointer to device structure.
* @param status Pointer to the virtio device status.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_get_status(struct virtio_device *vdev, uint8_t *status)
{
if (!vdev || !status)
return -EINVAL;

if (!vdev->func || !vdev->func->get_status)
return -ENXIO;

*status = vdev->func->get_status(vdev);
return 0;
}

/**
* @brief Set device status.
*
* @param dev Pointer to device structure.
* @param status Value to be set as device status.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_set_status(struct virtio_device *vdev, uint8_t status)
{
if (!vdev)
return -EINVAL;

if (!vdev->func || !vdev->func->set_status)
arnopo marked this conversation as resolved.
Show resolved Hide resolved
return -ENXIO;

vdev->func->set_status(vdev, status);
return 0;
}

/**
* @brief Retrieve configuration data from the device.
*
* @param dev Pointer to device structure.
* @param offset Offset of the data within the configuration area.
* @param dst Address of the buffer that will hold the data.
* @param len Length of the data to be retrieved.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_read_config(struct virtio_device *vdev,
uint32_t offset, void *dst, int len)
{
arnopo marked this conversation as resolved.
Show resolved Hide resolved
if (!vdev || !dst)
return -EINVAL;

if (!vdev->func || !vdev->func->read_config)
return -ENXIO;

vdev->func->read_config(vdev, offset, dst, len);
return 0;
}

/**
* @brief Write configuration data to the device.
*
* @param dev Pointer to device structure.
* @param offset Offset of the data within the configuration area.
* @param src Address of the buffer that holds the data to write.
* @param len Length of the data to be written.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_write_config(struct virtio_device *vdev,
uint32_t offset, void *src, int len)
{
arnopo marked this conversation as resolved.
Show resolved Hide resolved
if (!vdev || !src)
return -EINVAL;

if (!vdev->func || !vdev->func->write_config)
return -ENXIO;

vdev->func->write_config(vdev, offset, src, len);
return 0;
}

/**
* @brief Get the virtio device features.
*
* @param dev Pointer to device structure.
* @param features Pointer to features supported by both the driver and
* the device as a bitfield.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_get_features(struct virtio_device *vdev,
uint32_t *features)
{
if (!vdev || !features)
return -EINVAL;

if (!vdev->func || !vdev->func->get_features)
return -ENXIO;

*features = vdev->func->get_features(vdev);
return 0;
}

/**
* @brief Set features supported by the VIRTIO driver.
*
* @param dev Pointer to device structure.
* @param features Features supported by the driver as a bitfield.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_set_features(struct virtio_device *vdev,
uint32_t features)
{
arnopo marked this conversation as resolved.
Show resolved Hide resolved
if (!vdev)
return -EINVAL;

if (!vdev->func || !vdev->func->set_features)
return -ENXIO;

vdev->func->set_features(vdev, features);
return 0;
}

/**
* @brief Negotiate features between virtio device and driver.
*
* @param dev Pointer to device structure.
* @param features Supported features.
* @param final_features Pointer to the final features after negotiate.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_negotiate_features(struct virtio_device *vdev,
uint32_t features,
uint32_t *final_features)
{
if (!vdev || !final_features)
return -EINVAL;

if (!vdev->func || !vdev->func->negotiate_features)
return -ENXIO;

*final_features = vdev->func->negotiate_features(vdev, features);
return 0;
}

/**
* @brief Reset virtio device.
*
* @param vdev Pointer to virtio_device structure.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_reset_device(struct virtio_device *vdev)
{
arnopo marked this conversation as resolved.
Show resolved Hide resolved
if (!vdev)
return -EINVAL;

if (!vdev->func || !vdev->func->reset_device)
return -ENXIO;

vdev->func->reset_device(vdev);
return 0;
}

#if defined __cplusplus
}
#endif
Expand Down
8 changes: 8 additions & 0 deletions lib/virtio/virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
int ret;
(void)flags;

if (!vdev)
return -EINVAL;

if (vdev->func && vdev->func->create_virtqueues) {
return vdev->func->create_virtqueues(vdev, flags, nvqs,
names, callbacks);
}

num_vrings = vdev->vrings_num;
if (nvqs > num_vrings)
return ERROR_VQUEUE_INVLD_PARAM;
Expand Down