openamp: decoupling the transport layer and virtio device layer
Patch 17: virtio: follow virtio 1.2 spec, add more virtio status and device Patch 18: virtio: decoupling the transport layer and virtio device layer 1. Add virtio device api to decouple the transport layer and virtio device layer. 2. Move the vrings info and virtqueue allocation/free to the remoteproc transport layer; 3. Because 2, modify the rpmsg device also; Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
parent
b4a6c63d47
commit
1f4b71d576
@ -0,0 +1,93 @@
|
||||
From 61a7811f09b529341351c19ce1644b7e790daa5f Mon Sep 17 00:00:00 2001
|
||||
From: wangbowen6 <wangbowen6@xiaomi.com>
|
||||
Date: Tue, 9 May 2023 11:30:09 +0800
|
||||
Subject: [PATCH 1/2] virtio: follow virtio 1.2 spec, add more virtio status
|
||||
and device
|
||||
|
||||
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
|
||||
---
|
||||
lib/include/openamp/virtio.h | 37 ++++++++++++++++++++++++++----------
|
||||
lib/virtio/virtio.c | 14 ++++++++++++++
|
||||
2 files changed, 41 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/lib/include/openamp/virtio.h open-amp/lib/include/openamp/virtio.h
|
||||
index 0303a5b..3001a06 100644
|
||||
--- a/lib/include/openamp/virtio.h
|
||||
+++ open-amp/lib/include/openamp/virtio.h
|
||||
@@ -15,21 +15,38 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* VirtIO device IDs. */
|
||||
-#define VIRTIO_ID_NETWORK 0x01UL
|
||||
-#define VIRTIO_ID_BLOCK 0x02UL
|
||||
-#define VIRTIO_ID_CONSOLE 0x03UL
|
||||
-#define VIRTIO_ID_ENTROPY 0x04UL
|
||||
-#define VIRTIO_ID_BALLOON 0x05UL
|
||||
-#define VIRTIO_ID_IOMEMORY 0x06UL
|
||||
-#define VIRTIO_ID_RPMSG 0x07UL /* remote processor messaging */
|
||||
-#define VIRTIO_ID_SCSI 0x08UL
|
||||
-#define VIRTIO_ID_9P 0x09UL
|
||||
-#define VIRTIO_DEV_ANY_ID (-1)UL
|
||||
+#define VIRTIO_ID_NETWORK 1UL
|
||||
+#define VIRTIO_ID_BLOCK 2UL
|
||||
+#define VIRTIO_ID_CONSOLE 3UL
|
||||
+#define VIRTIO_ID_ENTROPY 4UL
|
||||
+#define VIRTIO_ID_BALLOON 5UL
|
||||
+#define VIRTIO_ID_IOMEMORY 6UL
|
||||
+#define VIRTIO_ID_RPMSG 7UL /* remote processor messaging */
|
||||
+#define VIRTIO_ID_SCSI 8UL
|
||||
+#define VIRTIO_ID_9P 9UL
|
||||
+#define VIRTIO_ID_RPROC_SERIAL 11UL
|
||||
+#define VIRTIO_ID_GPU 16UL
|
||||
+#define VIRTIO_ID_INPUT 18UL
|
||||
+#define VIRTIO_ID_VSOCK 19UL
|
||||
+#define VIRTIO_ID_CRYPTO 20UL
|
||||
+#define VIRTIO_ID_IOMMU 23UL
|
||||
+#define VIRTIO_ID_MEM 24UL
|
||||
+#define VIRTIO_ID_SOUND 25UL
|
||||
+#define VIRTIO_ID_FS 26UL
|
||||
+#define VIRTIO_ID_PMEM 27UL
|
||||
+#define VIRTIO_ID_RPMB 28UL
|
||||
+#define VIRTIO_ID_SCMI 32UL
|
||||
+#define VIRTIO_ID_I2C_ADAPTER 34UL
|
||||
+#define VIRTIO_ID_BT 40UL
|
||||
+#define VIRTIO_ID_GPIO 41UL
|
||||
+#define VIRTIO_DEV_ANY_ID -1UL
|
||||
|
||||
/* Status byte for guest to report progress. */
|
||||
+#define VIRTIO_CONFIG_STATUS_RESET 0x00
|
||||
#define VIRTIO_CONFIG_STATUS_ACK 0x01
|
||||
#define VIRTIO_CONFIG_STATUS_DRIVER 0x02
|
||||
#define VIRTIO_CONFIG_STATUS_DRIVER_OK 0x04
|
||||
+#define VIRTIO_CONFIG_FEATURES_OK 0x08
|
||||
#define VIRTIO_CONFIG_STATUS_NEEDS_RESET 0x40
|
||||
#define VIRTIO_CONFIG_STATUS_FAILED 0x80
|
||||
|
||||
diff --git a/lib/virtio/virtio.c open-amp/lib/virtio/virtio.c
|
||||
index d205784..d25aec3 100644
|
||||
--- a/lib/virtio/virtio.c
|
||||
+++ open-amp/lib/virtio/virtio.c
|
||||
@@ -26,6 +26,20 @@ static const struct virtio_ident {
|
||||
VIRTIO_ID_IOMEMORY, "IOMemory"}, {
|
||||
VIRTIO_ID_SCSI, "SCSI"}, {
|
||||
VIRTIO_ID_9P, "9P Transport"}, {
|
||||
+ VIRTIO_ID_GPU, "GPU"}, {
|
||||
+ VIRTIO_ID_INPUT, "Input"}, {
|
||||
+ VIRTIO_ID_VSOCK, "Vsock Transport"}, {
|
||||
+ VIRTIO_ID_CRYPTO, "Crypto"}, {
|
||||
+ VIRTIO_ID_IOMMU, "IOMMU"}, {
|
||||
+ VIRTIO_ID_MEM, "Memory"}, {
|
||||
+ VIRTIO_ID_SOUND, "Sound"}, {
|
||||
+ VIRTIO_ID_FS, "File System"}, {
|
||||
+ VIRTIO_ID_PMEM, "Pmem"}, {
|
||||
+ VIRTIO_ID_RPMB, "RPMB"}, {
|
||||
+ VIRTIO_ID_SCMI, "SCMI"}, {
|
||||
+ VIRTIO_ID_I2C_ADAPTER, "I2C Adapter"}, {
|
||||
+ VIRTIO_ID_BT, "Bluetooth"}, {
|
||||
+ VIRTIO_ID_GPIO, "GPIO" }, {
|
||||
0, NULL}
|
||||
};
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
@ -0,0 +1,635 @@
|
||||
From 3ed768a2ce3b35e64c56cd69eb48e4436bdc4c12 Mon Sep 17 00:00:00 2001
|
||||
From: wangbowen6 <wangbowen6@xiaomi.com>
|
||||
Date: Tue, 9 May 2023 12:53:21 +0800
|
||||
Subject: [PATCH 2/2] virtio: decoupling the transport layer and virtio device
|
||||
layer
|
||||
|
||||
1. Add virtio device api to decouple the transport layer and virtio
|
||||
device layer.
|
||||
2. Move the vrings info and virtqueue allocation/free to the
|
||||
remoteproc transport layer;
|
||||
3. Because 2, modify the rpmsg device also;
|
||||
|
||||
Change-Id: Ideb5fc388dd1626ce4ac1efd4c5120863918057b
|
||||
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
|
||||
---
|
||||
lib/include/openamp/rpmsg_virtio.h | 10 +-
|
||||
lib/include/openamp/virtio.h | 128 +++++++++++++++++++-
|
||||
lib/remoteproc/remoteproc.c | 32 -----
|
||||
lib/remoteproc/remoteproc_virtio.c | 188 +++++++++++++++++++++--------
|
||||
lib/rpmsg/rpmsg_virtio.c | 29 ++++-
|
||||
lib/virtio/virtio.c | 40 ------
|
||||
6 files changed, 293 insertions(+), 134 deletions(-)
|
||||
|
||||
diff --git a/lib/include/openamp/rpmsg_virtio.h open-amp/lib/include/openamp/rpmsg_virtio.h
|
||||
index bdc6cc6..e2d166f 100644
|
||||
--- a/lib/include/openamp/rpmsg_virtio.h
|
||||
+++ open-amp/lib/include/openamp/rpmsg_virtio.h
|
||||
@@ -144,8 +144,14 @@ 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);
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+rpmsg_virtio_delete_virtqueues(struct rpmsg_virtio_device *rvdev)
|
||||
+{
|
||||
+ rvdev->vdev->func->delete_virtqueues(rvdev->vdev);
|
||||
}
|
||||
|
||||
static inline int
|
||||
diff --git a/lib/include/openamp/virtio.h open-amp/lib/include/openamp/virtio.h
|
||||
index 3001a06..fb68c19 100644
|
||||
--- a/lib/include/openamp/virtio.h
|
||||
+++ open-amp/lib/include/openamp/virtio.h
|
||||
@@ -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);
|
||||
@@ -182,9 +187,126 @@ struct virtio_dispatch {
|
||||
int (*notify_wait)(struct virtio_device *dev, 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 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 Pointer to virtio device structure.
|
||||
+ */
|
||||
+static inline int virtio_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 vdev Pointer to virtio device structure.
|
||||
+ *
|
||||
+ * @return pointer to virtio device structure.
|
||||
+ */
|
||||
+static inline void virtio_delete_virtqueues(struct virtio_device *vdev)
|
||||
+{
|
||||
+ return vdev->func->delete_virtqueues(vdev);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Retrieve device status.
|
||||
+ *
|
||||
+ * @param dev Pointer to device structure.
|
||||
+ *
|
||||
+ * @return status of the device.
|
||||
+ */
|
||||
+static inline uint8_t virtio_get_status(struct virtio_device *vdev)
|
||||
+{
|
||||
+ return vdev->func->get_status(vdev);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Set device status.
|
||||
+ *
|
||||
+ * @param dev Pointer to device structure.
|
||||
+ * @param status Value to be set as device status.
|
||||
+ */
|
||||
+static inline void virtio_set_status(struct virtio_device *vdev,
|
||||
+ uint8_t status)
|
||||
+{
|
||||
+ vdev->func->set_status(vdev, status);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @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.
|
||||
+ */
|
||||
+static inline void virtio_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 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.
|
||||
+ */
|
||||
+static inline void virtio_write_config(struct virtio_device *vdev,
|
||||
+ uint32_t offset, void *src,
|
||||
+ int length)
|
||||
+{
|
||||
+ vdev->func->write_config(vdev, offset, src, length);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Get the virtio device features.
|
||||
+ *
|
||||
+ * @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_get_features(struct virtio_device *vdev)
|
||||
+{
|
||||
+ return vdev->func->get_features(vdev);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Set features supported by the VIRTIO driver.
|
||||
+ *
|
||||
+ * @param dev Pointer to device structure.
|
||||
+ * @param features Features supported by the driver as a bitfield.
|
||||
+ */
|
||||
+static inline void virtio_set_features(struct virtio_device *vdev,
|
||||
+ uint32_t features)
|
||||
+{
|
||||
+ return vdev->func->set_features(vdev, features);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Reset virtio device.
|
||||
+ *
|
||||
+ * @param vdev Pointer to virtio_device structure.
|
||||
+ */
|
||||
+static inline void virtio_reset_device(struct virtio_device *vdev)
|
||||
+{
|
||||
+ vdev->func->reset_device(vdev);
|
||||
+}
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
diff --git a/lib/remoteproc/remoteproc.c open-amp/lib/remoteproc/remoteproc.c
|
||||
index 001b11b..5a38fe1 100644
|
||||
--- a/lib/remoteproc/remoteproc.c
|
||||
+++ open-amp/lib/remoteproc/remoteproc.c
|
||||
@@ -921,7 +921,6 @@ remoteproc_create_virtio(struct remoteproc *rproc,
|
||||
struct remoteproc_virtio *rpvdev;
|
||||
size_t vdev_rsc_offset;
|
||||
unsigned int notifyid;
|
||||
- unsigned int num_vrings, i;
|
||||
struct metal_list *node;
|
||||
|
||||
#ifdef VIRTIO_DRIVER_ONLY
|
||||
@@ -969,39 +968,8 @@ remoteproc_create_virtio(struct remoteproc *rproc,
|
||||
rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
|
||||
rpvdev->notify_wait = remoteproc_virtio_notify_wait;
|
||||
metal_list_add_tail(&rproc->vdevs, &rpvdev->node);
|
||||
- num_vrings = vdev_rsc->num_of_vrings;
|
||||
-
|
||||
- /* set the notification id for vrings */
|
||||
- for (i = 0; i < num_vrings; i++) {
|
||||
- struct fw_rsc_vdev_vring *vring_rsc;
|
||||
- metal_phys_addr_t da;
|
||||
- unsigned int num_descs, align;
|
||||
- struct metal_io_region *io;
|
||||
- void *va;
|
||||
- size_t size;
|
||||
- int ret;
|
||||
-
|
||||
- vring_rsc = &vdev_rsc->vring[i];
|
||||
- notifyid = vring_rsc->notifyid;
|
||||
- da = vring_rsc->da;
|
||||
- num_descs = vring_rsc->num;
|
||||
- align = vring_rsc->align;
|
||||
- size = vring_size(num_descs, align);
|
||||
- va = remoteproc_mmap(rproc, NULL, &da, size, 0, &io);
|
||||
- if (!va)
|
||||
- goto err1;
|
||||
- ret = rproc_virtio_init_vring(vdev, i, notifyid,
|
||||
- va, io, num_descs, align);
|
||||
- if (ret)
|
||||
- goto err1;
|
||||
- }
|
||||
metal_mutex_release(&rproc->lock);
|
||||
return vdev;
|
||||
-
|
||||
-err1:
|
||||
- remoteproc_remove_virtio(rproc, vdev);
|
||||
- metal_mutex_release(&rproc->lock);
|
||||
- return NULL;
|
||||
}
|
||||
|
||||
void remoteproc_remove_virtio(struct remoteproc *rproc,
|
||||
diff --git a/lib/remoteproc/remoteproc_virtio.c open-amp/lib/remoteproc/remoteproc_virtio.c
|
||||
index 4375c4c..96767c1 100644
|
||||
--- a/lib/remoteproc/remoteproc_virtio.c
|
||||
+++ open-amp/lib/remoteproc/remoteproc_virtio.c
|
||||
@@ -16,6 +16,139 @@
|
||||
#include <metal/utilities.h>
|
||||
#include <metal/alloc.h>
|
||||
|
||||
+static void rproc_virtio_delete_virtqueues(struct virtio_device *vdev)
|
||||
+{
|
||||
+ struct virtio_vring_info *vring_info;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (vdev->vrings_info != NULL) {
|
||||
+ for (i = 0; i < vdev->vrings_num; i++) {
|
||||
+ vring_info = &vdev->vrings_info[i];
|
||||
+ if (vring_info->vq != NULL) {
|
||||
+ virtqueue_free(vring_info->vq);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ metal_free_memory(vdev->vrings_info);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int rproc_virtio_create_virtqueue(struct virtio_device *vdev,
|
||||
+ unsigned int flags,
|
||||
+ unsigned int i,
|
||||
+ const char *name,
|
||||
+ vq_callback callback)
|
||||
+{
|
||||
+ struct remoteproc_virtio *rpvdev;
|
||||
+ struct fw_rsc_vdev_vring *vring_rsc;
|
||||
+ struct fw_rsc_vdev *vdev_rsc;
|
||||
+ struct remoteproc *rproc;
|
||||
+ struct virtio_vring_info *vring_info;
|
||||
+ struct vring_alloc_info *vring_alloc;
|
||||
+ struct metal_io_region *io;
|
||||
+ metal_phys_addr_t da;
|
||||
+ size_t vringsize;
|
||||
+ void *va;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Get remoteproc virtio device */
|
||||
+ rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
|
||||
+
|
||||
+ /* Get the remoteproc */
|
||||
+ rproc = rpvdev->priv;
|
||||
+
|
||||
+ /* Get the rsc table */
|
||||
+ vdev_rsc = rpvdev->vdev_rsc;
|
||||
+ vring_rsc = &vdev_rsc->vring[i];
|
||||
+
|
||||
+ /*
|
||||
+ * Initialize the vring information according to the vring resource
|
||||
+ * table.
|
||||
+ */
|
||||
+ da = vring_rsc->da;
|
||||
+ vringsize = vring_size(vring_rsc->num, vring_rsc->align);
|
||||
+ va = remoteproc_mmap(rproc, NULL, &da, vringsize, 0, &io);
|
||||
+ if (!va) {
|
||||
+ return ERROR_VQUEUE_INVLD_PARAM;
|
||||
+ }
|
||||
+
|
||||
+ ret = rproc_virtio_init_vring(vdev, i, vring_rsc->notifyid, va, io,
|
||||
+ vring_rsc->num, vring_rsc->align);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Get the vring information */
|
||||
+ vring_info = &vdev->vrings_info[i];
|
||||
+ vring_alloc = &vring_info->info;
|
||||
+
|
||||
+ /* Alloc the virtqueue and init it */
|
||||
+ vring_info->vq = virtqueue_allocate(vring_alloc->num_descs);
|
||||
+ if (!vring_info->vq) {
|
||||
+ return ERROR_NO_MEM;
|
||||
+ }
|
||||
+
|
||||
+#ifndef VIRTIO_DEVICE_ONLY
|
||||
+ if (vdev->role == VIRTIO_DEV_DRIVER) {
|
||||
+ size_t offset = metal_io_virt_to_offset(vring_info->io,
|
||||
+ vring_alloc->vaddr);
|
||||
+ metal_io_block_set(vring_info->io, offset, 0, vringsize);
|
||||
+ }
|
||||
+#endif
|
||||
+ ret = virtqueue_create(vdev, i, name, vring_alloc, callback,
|
||||
+ vdev->func->notify, vring_info->vq);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rproc_virtio_create_virtqueues(struct virtio_device *vdev,
|
||||
+ unsigned int flags,
|
||||
+ unsigned int nvqs,
|
||||
+ const char *names[],
|
||||
+ vq_callback callbacks[])
|
||||
+{
|
||||
+ struct remoteproc_virtio *rpvdev;
|
||||
+ struct virtio_vring_info *vrings_info;
|
||||
+ struct fw_rsc_vdev *vdev_rsc;
|
||||
+ unsigned int i;
|
||||
+ int ret;
|
||||
+ (void)flags;
|
||||
+
|
||||
+ /* Get remoteproc virtio device, rsc table, remoteproc */
|
||||
+ rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
|
||||
+ vdev_rsc = rpvdev->vdev_rsc;
|
||||
+
|
||||
+ /* Check vrings number */
|
||||
+ if (nvqs > vdev_rsc->num_of_vrings)
|
||||
+ return ERROR_VQUEUE_INVLD_PARAM;
|
||||
+
|
||||
+ /* Alloc vrings info for the virtio device */
|
||||
+ vrings_info = metal_allocate_memory(sizeof(*vrings_info) * nvqs);
|
||||
+ if (!vrings_info) {
|
||||
+ return ERROR_NO_MEM;
|
||||
+ }
|
||||
+
|
||||
+ memset(vrings_info, 0, sizeof(*vrings_info) * nvqs);
|
||||
+ vdev->vrings_info = vrings_info;
|
||||
+ vdev->vrings_num = nvqs;
|
||||
+
|
||||
+ /* set the notification id for vrings */
|
||||
+ for (i = 0; i < nvqs; i++) {
|
||||
+ ret = rproc_virtio_create_virtqueue(vdev, flags, i, names[i],
|
||||
+ callbacks[i]);
|
||||
+ if (ret) {
|
||||
+ goto err;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+
|
||||
+err:
|
||||
+ rproc_virtio_delete_virtqueues(vdev);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void rproc_virtio_virtqueue_notify(struct virtqueue *vq)
|
||||
{
|
||||
struct remoteproc_virtio *rpvdev;
|
||||
@@ -148,7 +281,7 @@ static void rproc_virtio_read_config(struct virtio_device *vdev,
|
||||
|
||||
rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
|
||||
vdev_rsc = rpvdev->vdev_rsc;
|
||||
- config = (char *)(&vdev_rsc->vring[vdev->vrings_num]);
|
||||
+ config = (char *)(&vdev_rsc->vring[vdev_rsc->num_of_vrings]);
|
||||
io = rpvdev->vdev_rsc_io;
|
||||
|
||||
if (offset + length <= vdev_rsc->config_len)
|
||||
@@ -168,7 +301,7 @@ static void rproc_virtio_write_config(struct virtio_device *vdev,
|
||||
|
||||
rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
|
||||
vdev_rsc = rpvdev->vdev_rsc;
|
||||
- config = (char *)(&vdev_rsc->vring[vdev->vrings_num]);
|
||||
+ config = (char *)(&vdev_rsc->vring[vdev_rsc->num_of_vrings]);
|
||||
io = rpvdev->vdev_rsc_io;
|
||||
|
||||
if (offset + length <= vdev_rsc->config_len) {
|
||||
@@ -188,6 +321,8 @@ 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,
|
||||
+ .delete_virtqueues = rproc_virtio_delete_virtqueues,
|
||||
.get_status = rproc_virtio_get_status,
|
||||
.get_features = rproc_virtio_get_features,
|
||||
.read_config = rproc_virtio_read_config,
|
||||
@@ -215,44 +350,16 @@ rproc_virtio_create_vdev(unsigned int role, unsigned int notifyid,
|
||||
virtio_dev_reset_cb rst_cb)
|
||||
{
|
||||
struct remoteproc_virtio *rpvdev;
|
||||
- struct virtio_vring_info *vrings_info;
|
||||
struct fw_rsc_vdev *vdev_rsc = rsc;
|
||||
struct virtio_device *vdev;
|
||||
- unsigned int num_vrings = vdev_rsc->num_of_vrings;
|
||||
- unsigned int i;
|
||||
|
||||
rpvdev = metal_allocate_memory(sizeof(*rpvdev));
|
||||
if (!rpvdev)
|
||||
return NULL;
|
||||
- vrings_info = metal_allocate_memory(sizeof(*vrings_info) * num_vrings);
|
||||
- if (!vrings_info)
|
||||
- goto err0;
|
||||
memset(rpvdev, 0, sizeof(*rpvdev));
|
||||
- memset(vrings_info, 0, sizeof(*vrings_info));
|
||||
vdev = &rpvdev->vdev;
|
||||
-
|
||||
- for (i = 0; i < num_vrings; i++) {
|
||||
- struct virtqueue *vq;
|
||||
-#ifndef VIRTIO_DEVICE_ONLY
|
||||
- struct fw_rsc_vdev_vring *vring_rsc;
|
||||
-#endif
|
||||
- unsigned int num_extra_desc = 0;
|
||||
-
|
||||
-#ifndef VIRTIO_DEVICE_ONLY
|
||||
- vring_rsc = &vdev_rsc->vring[i];
|
||||
- if (role == VIRTIO_DEV_DRIVER) {
|
||||
- num_extra_desc = vring_rsc->num;
|
||||
- }
|
||||
-#endif
|
||||
- vq = virtqueue_allocate(num_extra_desc);
|
||||
- if (!vq)
|
||||
- goto err1;
|
||||
- vrings_info[i].vq = vq;
|
||||
- }
|
||||
-
|
||||
rpvdev->notify = notify;
|
||||
rpvdev->priv = priv;
|
||||
- vdev->vrings_info = vrings_info;
|
||||
/* Assuming the shared memory has been mapped and registered if
|
||||
* necessary
|
||||
*/
|
||||
@@ -262,7 +369,6 @@ rproc_virtio_create_vdev(unsigned int role, unsigned int notifyid,
|
||||
vdev->notifyid = notifyid;
|
||||
vdev->role = role;
|
||||
vdev->reset_cb = rst_cb;
|
||||
- vdev->vrings_num = num_vrings;
|
||||
vdev->func = &remoteproc_virtio_dispatch_funcs;
|
||||
|
||||
#ifndef VIRTIO_DEVICE_ONLY
|
||||
@@ -274,35 +380,15 @@ rproc_virtio_create_vdev(unsigned int role, unsigned int notifyid,
|
||||
#endif
|
||||
|
||||
return &rpvdev->vdev;
|
||||
-
|
||||
-err1:
|
||||
- for (i = 0; i < num_vrings; i++) {
|
||||
- if (vrings_info[i].vq)
|
||||
- metal_free_memory(vrings_info[i].vq);
|
||||
- }
|
||||
- metal_free_memory(vrings_info);
|
||||
-err0:
|
||||
- metal_free_memory(rpvdev);
|
||||
- return NULL;
|
||||
}
|
||||
|
||||
void rproc_virtio_remove_vdev(struct virtio_device *vdev)
|
||||
{
|
||||
struct remoteproc_virtio *rpvdev;
|
||||
- unsigned int i;
|
||||
|
||||
if (!vdev)
|
||||
return;
|
||||
rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
|
||||
- for (i = 0; i < vdev->vrings_num; i++) {
|
||||
- struct virtqueue *vq;
|
||||
-
|
||||
- vq = vdev->vrings_info[i].vq;
|
||||
- if (vq)
|
||||
- metal_free_memory(vq);
|
||||
- }
|
||||
- if (vdev->vrings_info)
|
||||
- metal_free_memory(vdev->vrings_info);
|
||||
metal_free_memory(rpvdev);
|
||||
}
|
||||
|
||||
diff --git a/lib/rpmsg/rpmsg_virtio.c open-amp/lib/rpmsg/rpmsg_virtio.c
|
||||
index 2f38faa..b30eccc 100644
|
||||
--- a/lib/rpmsg/rpmsg_virtio.c
|
||||
+++ open-amp/lib/rpmsg/rpmsg_virtio.c
|
||||
@@ -821,8 +821,6 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
|
||||
vq_names[1] = "tx_vq";
|
||||
callback[0] = rpmsg_virtio_rx_callback;
|
||||
callback[1] = rpmsg_virtio_tx_callback;
|
||||
- rvdev->rvq = vdev->vrings_info[0].vq;
|
||||
- rvdev->svq = vdev->vrings_info[1].vq;
|
||||
}
|
||||
#endif /*!VIRTIO_DEVICE_ONLY*/
|
||||
|
||||
@@ -833,8 +831,6 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
|
||||
vq_names[1] = "rx_vq";
|
||||
callback[0] = rpmsg_virtio_tx_callback;
|
||||
callback[1] = rpmsg_virtio_rx_callback;
|
||||
- rvdev->rvq = vdev->vrings_info[1].vq;
|
||||
- rvdev->svq = vdev->vrings_info[0].vq;
|
||||
}
|
||||
#endif /*!VIRTIO_DRIVER_ONLY*/
|
||||
rvdev->shbuf_io = shm_io;
|
||||
@@ -846,6 +842,21 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
|
||||
if (status != RPMSG_SUCCESS)
|
||||
return status;
|
||||
|
||||
+ /* Create virtqueue success, assign back the virtqueue */
|
||||
+#ifndef VIRTIO_DEVICE_ONLY
|
||||
+ if (role == RPMSG_HOST) {
|
||||
+ rvdev->rvq = vdev->vrings_info[0].vq;
|
||||
+ rvdev->svq = vdev->vrings_info[1].vq;
|
||||
+ }
|
||||
+#endif /*!VIRTIO_DEVICE_ONLY*/
|
||||
+
|
||||
+#ifndef VIRTIO_DRIVER_ONLY
|
||||
+ if (role == RPMSG_REMOTE) {
|
||||
+ rvdev->rvq = vdev->vrings_info[1].vq;
|
||||
+ rvdev->svq = vdev->vrings_info[0].vq;
|
||||
+ }
|
||||
+#endif /*!VIRTIO_DRIVER_ONLY*/
|
||||
+
|
||||
/*
|
||||
* Suppress "tx-complete" interrupts
|
||||
* since send method use busy loop when buffer pool exhaust
|
||||
@@ -873,7 +884,8 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
|
||||
rvdev->config.r2h_buf_size);
|
||||
|
||||
if (!buffer) {
|
||||
- return RPMSG_ERR_NO_BUFF;
|
||||
+ status = RPMSG_ERR_NO_BUFF;
|
||||
+ goto err;
|
||||
}
|
||||
|
||||
vqbuf.buf = buffer;
|
||||
@@ -887,7 +899,7 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
|
||||
buffer);
|
||||
|
||||
if (status != RPMSG_SUCCESS) {
|
||||
- return status;
|
||||
+ goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -912,6 +924,10 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
|
||||
#endif /*!VIRTIO_DEVICE_ONLY*/
|
||||
|
||||
return status;
|
||||
+
|
||||
+err:
|
||||
+ rpmsg_virtio_delete_virtqueues(rvdev);
|
||||
+ return status;
|
||||
}
|
||||
|
||||
void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev)
|
||||
@@ -931,6 +947,7 @@ void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev)
|
||||
rvdev->rvq = 0;
|
||||
rvdev->svq = 0;
|
||||
|
||||
+ rpmsg_virtio_delete_virtqueues(rvdev);
|
||||
metal_mutex_deinit(&rdev->lock);
|
||||
}
|
||||
}
|
||||
diff --git a/lib/virtio/virtio.c open-amp/lib/virtio/virtio.c
|
||||
index d25aec3..e67e97d 100644
|
||||
--- a/lib/virtio/virtio.c
|
||||
+++ open-amp/lib/virtio/virtio.c
|
||||
@@ -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;
|
||||
-}
|
||||
-
|
||||
--
|
||||
2.25.1
|
||||
|
@ -51,6 +51,8 @@ open-amp.zip:
|
||||
$(Q) patch -p0 < 0014-rpmsg-add-cache-flash-when-hold-rx-buffer.patch
|
||||
$(Q) patch -p0 < 0015-rpmsg-do-cache_invalidate-when-real-data-returned.patch
|
||||
$(Q) patch -p0 < 0016-openamp-add-new-API-rpmsg_virtio_get_rxbuffer_size.patch
|
||||
$(Q) patch -p0 < 0017-virtio-follow-virtio-1.2-spec-add-more-virtio-status.patch
|
||||
$(Q) patch -p0 < 0018-virtio-decoupling-the-transport-layer-and-virtio-dev.patch
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user