Replace llist rpmsg buf with libmetal scatter/gather list
authorWendy Liang <jliang@xilinx.com>
Tue, 2 Aug 2016 22:50:47 +0000 (15:50 -0700)
committerWendy Liang <jliang@xilinx.com>
Thu, 13 Oct 2016 05:01:46 +0000 (22:01 -0700)
Use libmetal scatter/gather list to replace the llist buffers.

Signed-off-by: Wendy Liang <jliang@xilinx.com>
lib/include/openamp/rpmsg_core.h
lib/include/openamp/virtqueue.h
lib/rpmsg/remote_device.c
lib/rpmsg/rpmsg_core.c
lib/virtio/virtqueue.c

index 790df874749975aea19eded7ac0eed948ffd0c5a..0962a9f37ec58a7f2ff4f4f77ac1c866113deef0 100644 (file)
@@ -35,7 +35,6 @@
 #include "openamp/virtio.h"
 #include "openamp/hil.h"
 #include "openamp/sh_mem.h"
-#include "openamp/llist.h"
 #include "openamp/rpmsg.h"
 #include "metal/mutex.h"
 #include "metal/list.h"
index 83d2fb54f551797b4a38c43df23d76c319d4930b..2ab53717f1ee571e01b4c5614478518ffa1f755c 100644 (file)
@@ -34,7 +34,7 @@ typedef uint8_t boolean;
 
 #include "openamp/virtio_ring.h"
 #include "openamp/env.h"
-#include "openamp/llist.h"
+#include "metal/dma.h"
 
 /*Error Codes*/
 #define VQ_ERROR_BASE                                 -3000
@@ -197,11 +197,11 @@ int virtqueue_create(struct virtio_device *device, unsigned short id,
                     void (*notify) (struct virtqueue * vq),
                     struct virtqueue **v_queue);
 
-int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,
+int virtqueue_add_buffer(struct virtqueue *vq, struct metal_sg *sg,
                         int readable, int writable, void *cookie);
 
 int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,
-                               void *buffer_addr, uint32_t len, int writable,
+                               struct metal_sg *sg, int writable,
                                boolean has_next);
 
 void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t * len);
index ed132fc9cf72b9c1f40b8202992b2ac743da33e6..9187d69af0964eb6e59dec8d2ea436bd9477a4ab 100644 (file)
@@ -384,7 +384,7 @@ int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,
        struct virtqueue *vqs[RPMSG_MAX_VQ_PER_RDEV];
        struct proc_vring *vring_table;
        void *buffer;
-       struct llist node;
+       struct metal_sg sg;
        int idx, num_vrings, status;
 
        (void)flags;
@@ -429,6 +429,8 @@ int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,
        }
 
        if (rdev->role == RPMSG_REMOTE) {
+               sg.io = rdev->proc->sh_buff.io;
+               sg.len = RPMSG_BUFFER_SIZE;
                for (idx = 0; ((idx < rdev->rvq->vq_nentries)
                               && (idx < rdev->mem_pool->total_buffs / 2));
                     idx++) {
@@ -440,13 +442,11 @@ int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,
                                return RPMSG_ERR_NO_BUFF;
                        }
 
-                       node.data = buffer;
-                       node.attr = RPMSG_BUFFER_SIZE;
-                       node.next = RPMSG_NULL;
+                       sg.virt = buffer;
 
                        memset(buffer, 0x00, RPMSG_BUFFER_SIZE);
                        status =
-                           virtqueue_add_buffer(rdev->rvq, &node, 0, 1,
+                           virtqueue_add_buffer(rdev->rvq, &sg, 0, 1,
                                                 buffer);
 
                        if (status != RPMSG_SUCCESS) {
index 6245b3f64dfb32f1868923008caf8982c15be61c..cd11dcabce761d958ee8d115330853e14ba02c17 100644 (file)
@@ -341,24 +341,23 @@ void rpmsg_send_ns_message(struct remote_device *rdev,
 int rpmsg_enqueue_buffer(struct remote_device *rdev, void *buffer,
                         unsigned long len, unsigned short idx)
 {
-       struct llist node;
        int status;
+       struct metal_sg sg;
        struct metal_io_region *io;
 
-       /* Initialize buffer node */
-       node.data = buffer;
-       node.attr = len;
-       node.next = RPMSG_NULL;
-       node.prev = RPMSG_NULL;
-
        io = rdev->proc->sh_buff.io;
        if (io) {
                if (! (io->mem_flags & METAL_UNCACHED))
                        metal_cache_flush(buffer, (unsigned int)len);
        }
        if (rdev->role == RPMSG_REMOTE) {
-               status = virtqueue_add_buffer(rdev->tvq, &node, 0, 1, buffer);
+               /* Initialize buffer node */
+               sg.virt = buffer;
+               sg.len = len;
+               sg.io = io;
+               status = virtqueue_add_buffer(rdev->tvq, &sg, 0, 1, buffer);
        } else {
+               (void)sg;
                status = virtqueue_add_consumed_buffer(rdev->tvq, idx, len);
        }
 
@@ -379,17 +378,16 @@ int rpmsg_enqueue_buffer(struct remote_device *rdev, void *buffer,
 void rpmsg_return_buffer(struct remote_device *rdev, void *buffer,
                         unsigned long len, unsigned short idx)
 {
-       struct llist node;
-
-       /* Initialize buffer node */
-       node.data = buffer;
-       node.attr = len;
-       node.next = RPMSG_NULL;
-       node.prev = RPMSG_NULL;
+       struct metal_sg sg;
 
        if (rdev->role == RPMSG_REMOTE) {
-               virtqueue_add_buffer(rdev->rvq, &node, 0, 1, buffer);
+               /* Initialize buffer node */
+               sg.virt = buffer;
+               sg.len = len;
+               sg.io = rdev->proc->sh_buff.io;
+               virtqueue_add_buffer(rdev->rvq, &sg, 0, 1, buffer);
        } else {
+               (void)sg;
                virtqueue_add_consumed_buffer(rdev->rvq, idx, len);
        }
 }
index 3e1639be9be9b900e36199de490cee866124c06f..fcabeab349fee686e46493957f5bb01ecc8f61ed 100644 (file)
 #include <string.h>
 #include "openamp/virtqueue.h"
 #include "metal/atomic.h"
+#include "metal/dma.h"
+#include "metal/io.h"
 
 /* Prototype for internal functions. */
 static void vq_ring_init(struct virtqueue *);
 static void vq_ring_update_avail(struct virtqueue *, uint16_t);
 static uint16_t vq_ring_add_buffer(struct virtqueue *, struct vring_desc *,
-                                  uint16_t, struct llist *, int, int);
+                                  uint16_t, struct metal_sg *, int, int);
 static int vq_ring_enable_interrupt(struct virtqueue *, uint16_t);
 static void vq_ring_free_chain(struct virtqueue *, uint16_t);
 static int vq_ring_must_notify_host(struct virtqueue *vq);
@@ -120,14 +122,14 @@ int virtqueue_create(struct virtio_device *virt_dev, unsigned short id,
  *                            inserted before writable buffers
  *
  * @param vq                - Pointer to VirtIO queue control block.
- * @param buffer            - Pointer to buffer list
+ * @param sg                - Pointer to buffer scatter/gather list
  * @param readable          - Number of readable buffers
  * @param writable          - Number of writable buffers
  * @param cookie            - Pointer to hold call back data
  *
  * @return                  - Function status
  */
-int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,
+int virtqueue_add_buffer(struct virtqueue *vq, struct metal_sg *sg,
                         int readable, int writable, void *cookie)
 {
 
@@ -164,7 +166,7 @@ int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,
                dxp->ndescs = needed;
 
                /* Enqueue buffer onto the ring. */
-               idx = vq_ring_add_buffer(vq, vq->vq_ring.desc, head_idx, buffer,
+               idx = vq_ring_add_buffer(vq, vq->vq_ring.desc, head_idx, sg,
                                         readable, writable);
 
                vq->vq_desc_head_idx = idx;
@@ -193,8 +195,7 @@ int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,
  *
  * @param vq                    - Pointer to VirtIO queue control block
  * @param cookie                - Pointer to hold call back data
- * @param buffer_addr           - Address of buffer
- * @param len                   - Length of buffer
+ * @param sg                    - metal_scatter/gather struct element
  * @param writable              - If buffer writable
  * @param has_next              - If buffers for subsequent call are
  *                                to be chained
@@ -202,7 +203,7 @@ int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,
  * @return                      - Function status
  */
 int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,
-                               void *buffer_addr, uint32_t len, int writable,
+                               struct metal_sg *sg, int writable,
                                boolean has_next)
 {
 
@@ -229,8 +230,8 @@ int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,
                idx = head_idx;
 
                dp = &vq->vq_ring.desc[idx];
-               dp->addr = env_map_vatopa(buffer_addr);
-               dp->len = len;
+               dp->addr = metal_io_virt_to_phys(sg->io, sg->virt);
+               dp->len = sg->len;
                dp->flags = 0;
                idx = dp->next;
 
@@ -508,7 +509,7 @@ uint32_t virtqueue_get_desc_size(struct virtqueue * vq)
  */
 static uint16_t vq_ring_add_buffer(struct virtqueue *vq,
                                   struct vring_desc *desc, uint16_t head_idx,
-                                  struct llist *buffer, int readable,
+                                  struct metal_sg *sg, int readable,
                                   int writable)
 {
 
@@ -520,15 +521,14 @@ static uint16_t vq_ring_add_buffer(struct virtqueue *vq,
 
        needed = readable + writable;
 
-       for (i = 0, idx = head_idx; (i < needed && buffer != VQ_NULL);
-            i++, idx = dp->next, buffer = buffer->next) {
+       for (i = 0, idx = head_idx; i < needed; i++, idx = dp->next) {
 
                VQASSERT(vq, idx != VQ_RING_DESC_CHAIN_END,
                         "premature end of free desc chain");
 
                dp = &desc[idx];
-               dp->addr = env_map_vatopa(buffer->data);
-               dp->len = buffer->attr;
+               dp->addr = metal_io_virt_to_phys(sg[i].io, sg[i].virt);
+               dp->len = sg[i].len;
                dp->flags = 0;
 
                if (i < needed - 1)