From 1f4b71d5760f24a9870959e063ae94a06a2dfa64 Mon Sep 17 00:00:00 2001 From: wangbowen6 Date: Sat, 20 May 2023 18:41:15 +0800 Subject: [PATCH] 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 --- ...rtio-1.2-spec-add-more-virtio-status.patch | 93 +++ ...g-the-transport-layer-and-virtio-dev.patch | 635 ++++++++++++++++++ openamp/open-amp.defs | 2 + 3 files changed, 730 insertions(+) create mode 100644 openamp/0017-virtio-follow-virtio-1.2-spec-add-more-virtio-status.patch create mode 100644 openamp/0018-virtio-decoupling-the-transport-layer-and-virtio-dev.patch diff --git a/openamp/0017-virtio-follow-virtio-1.2-spec-add-more-virtio-status.patch b/openamp/0017-virtio-follow-virtio-1.2-spec-add-more-virtio-status.patch new file mode 100644 index 0000000000..bc6eaef94a --- /dev/null +++ b/openamp/0017-virtio-follow-virtio-1.2-spec-add-more-virtio-status.patch @@ -0,0 +1,93 @@ +From 61a7811f09b529341351c19ce1644b7e790daa5f Mon Sep 17 00:00:00 2001 +From: wangbowen6 +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 +--- + 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 + diff --git a/openamp/0018-virtio-decoupling-the-transport-layer-and-virtio-dev.patch b/openamp/0018-virtio-decoupling-the-transport-layer-and-virtio-dev.patch new file mode 100644 index 0000000000..77068e8eab --- /dev/null +++ b/openamp/0018-virtio-decoupling-the-transport-layer-and-virtio-dev.patch @@ -0,0 +1,635 @@ +From 3ed768a2ce3b35e64c56cd69eb48e4436bdc4c12 Mon Sep 17 00:00:00 2001 +From: wangbowen6 +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 +--- + 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 + #include + ++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 + diff --git a/openamp/open-amp.defs b/openamp/open-amp.defs index e9430aed72..e7e70fd56f 100644 --- a/openamp/open-amp.defs +++ b/openamp/open-amp.defs @@ -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