190 lines
6.5 KiB
Diff
190 lines
6.5 KiB
Diff
From ddc209c9475a2822ffe5d18441bd01718acdbc11 Mon Sep 17 00:00:00 2001
|
|
From: ligd <liguiding1@xiaomi.com>
|
|
Date: Fri, 29 Jul 2022 22:57:23 +0800
|
|
Subject: [PATCH 4/9] openamp: add new ops notify_wait() support
|
|
|
|
This can avoid looping check tx buffer
|
|
|
|
Change-Id: Ie340ed06c306ce978ff165aacaf5b830e3645af8
|
|
Signed-off-by: ligd <liguiding1@xiaomi.com>
|
|
---
|
|
lib/include/openamp/remoteproc.h | 12 ++++++++++++
|
|
lib/include/openamp/remoteproc_virtio.h | 2 ++
|
|
lib/include/openamp/rpmsg.h | 1 +
|
|
lib/include/openamp/rpmsg_virtio.h | 9 +++++++++
|
|
lib/include/openamp/virtio.h | 1 +
|
|
lib/remoteproc/remoteproc.c | 11 +++++++++++
|
|
lib/remoteproc/remoteproc_virtio.c | 14 ++++++++++++++
|
|
lib/rpmsg/rpmsg_virtio.c | 7 +++++++
|
|
8 files changed, 57 insertions(+)
|
|
|
|
diff --git a/lib/include/openamp/remoteproc.h open-amp/lib/include/openamp/remoteproc.h
|
|
index d1efab85..f6554404 100644
|
|
--- a/lib/include/openamp/remoteproc.h
|
|
+++ open-amp/lib/include/openamp/remoteproc.h
|
|
@@ -428,6 +428,18 @@ struct remoteproc_ops {
|
|
int (*stop)(struct remoteproc *rproc);
|
|
int (*shutdown)(struct remoteproc *rproc);
|
|
int (*notify)(struct remoteproc *rproc, uint32_t id);
|
|
+ /**
|
|
+ * notify_wait
|
|
+ *
|
|
+ * Wait for remote notified, when there is no TX buffer anymore.
|
|
+ * Set to NULL means use usleep to wait TX buffer available.
|
|
+ *
|
|
+ * @rproc - pointer to remoteproc instance
|
|
+ * @id - the notifyid
|
|
+ *
|
|
+ * return 0 means there is notify available, otherwise negative value.
|
|
+ */
|
|
+ int (*notify_wait)(struct remoteproc *rproc, uint32_t id);
|
|
/**
|
|
* get_mem
|
|
*
|
|
diff --git a/lib/include/openamp/remoteproc_virtio.h open-amp/lib/include/openamp/remoteproc_virtio.h
|
|
index 6609a1fd..e65488d5 100644
|
|
--- a/lib/include/openamp/remoteproc_virtio.h
|
|
+++ open-amp/lib/include/openamp/remoteproc_virtio.h
|
|
@@ -25,6 +25,7 @@ extern "C" {
|
|
|
|
/* define vdev notification function user should implement */
|
|
typedef int (*rpvdev_notify_func)(void *priv, uint32_t id);
|
|
+typedef int (*rpvdev_notify_wait)(void *priv, uint32_t id);
|
|
|
|
/**
|
|
* struct remoteproc_virtio
|
|
@@ -40,6 +41,7 @@ struct remoteproc_virtio {
|
|
void *vdev_rsc;
|
|
struct metal_io_region *vdev_rsc_io;
|
|
rpvdev_notify_func notify;
|
|
+ rpvdev_notify_wait notify_wait;
|
|
struct virtio_device vdev;
|
|
struct metal_list node;
|
|
};
|
|
diff --git a/lib/include/openamp/rpmsg.h open-amp/lib/include/openamp/rpmsg.h
|
|
index dbe42ea6..14440e20 100644
|
|
--- a/lib/include/openamp/rpmsg.h
|
|
+++ open-amp/lib/include/openamp/rpmsg.h
|
|
@@ -50,6 +50,7 @@ extern "C" {
|
|
#define RPMSG_ERR_INIT (RPMSG_ERROR_BASE - 6)
|
|
#define RPMSG_ERR_ADDR (RPMSG_ERROR_BASE - 7)
|
|
#define RPMSG_ERR_PERM (RPMSG_ERROR_BASE - 8)
|
|
+#define RPMSG_ERR_NXIO (RPMSG_ERROR_BASE - 9)
|
|
|
|
struct rpmsg_endpoint;
|
|
struct rpmsg_device;
|
|
diff --git a/lib/include/openamp/rpmsg_virtio.h open-amp/lib/include/openamp/rpmsg_virtio.h
|
|
index 0b22e840..11cb6df9 100644
|
|
--- a/lib/include/openamp/rpmsg_virtio.h
|
|
+++ open-amp/lib/include/openamp/rpmsg_virtio.h
|
|
@@ -148,6 +148,15 @@ rpmsg_virtio_create_virtqueues(struct rpmsg_virtio_device *rvdev,
|
|
callbacks);
|
|
}
|
|
|
|
+static inline int
|
|
+rpmsg_virtio_notify_wait(struct rpmsg_virtio_device *rvdev,
|
|
+ struct virtqueue *vq)
|
|
+{
|
|
+ return rvdev->vdev->func->notify_wait ?
|
|
+ rvdev->vdev->func->notify_wait(rvdev->vdev, vq) :
|
|
+ RPMSG_ERR_NXIO;
|
|
+}
|
|
+
|
|
/**
|
|
* rpmsg_virtio_get_buffer_size - get rpmsg virtio buffer size
|
|
*
|
|
diff --git a/lib/include/openamp/virtio.h open-amp/lib/include/openamp/virtio.h
|
|
index 916132b4..0303a5b3 100644
|
|
--- a/lib/include/openamp/virtio.h
|
|
+++ open-amp/lib/include/openamp/virtio.h
|
|
@@ -162,6 +162,7 @@ struct virtio_dispatch {
|
|
void *src, int length);
|
|
void (*reset_device)(struct virtio_device *dev);
|
|
void (*notify)(struct virtqueue *vq);
|
|
+ int (*notify_wait)(struct virtio_device *dev, struct virtqueue *vq);
|
|
};
|
|
|
|
int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
|
|
diff --git a/lib/remoteproc/remoteproc.c open-amp/lib/remoteproc/remoteproc.c
|
|
index f7f9f2df..001b11bf 100644
|
|
--- a/lib/remoteproc/remoteproc.c
|
|
+++ open-amp/lib/remoteproc/remoteproc.c
|
|
@@ -899,6 +899,16 @@ static int remoteproc_virtio_notify(void *priv, uint32_t id)
|
|
return 0;
|
|
}
|
|
|
|
+static int remoteproc_virtio_notify_wait(void *priv, uint32_t id)
|
|
+{
|
|
+ struct remoteproc *rproc = priv;
|
|
+
|
|
+ if (rproc->ops->notify_wait)
|
|
+ return rproc->ops->notify_wait(rproc, id);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
struct virtio_device *
|
|
remoteproc_create_virtio(struct remoteproc *rproc,
|
|
int vdev_id, unsigned int role,
|
|
@@ -957,6 +967,7 @@ remoteproc_create_virtio(struct remoteproc *rproc,
|
|
rproc_virtio_wait_remote_ready(vdev);
|
|
|
|
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;
|
|
|
|
diff --git a/lib/remoteproc/remoteproc_virtio.c open-amp/lib/remoteproc/remoteproc_virtio.c
|
|
index 169e5b5f..4375c4c3 100644
|
|
--- a/lib/remoteproc/remoteproc_virtio.c
|
|
+++ open-amp/lib/remoteproc/remoteproc_virtio.c
|
|
@@ -30,6 +30,19 @@ static void rproc_virtio_virtqueue_notify(struct virtqueue *vq)
|
|
rpvdev->notify(rpvdev->priv, vring_info->notifyid);
|
|
}
|
|
|
|
+static int rproc_virtio_notify_wait(struct virtio_device *vdev,
|
|
+ struct virtqueue *vq)
|
|
+{
|
|
+ struct remoteproc_virtio *rpvdev;
|
|
+ struct virtio_vring_info *vring_info;
|
|
+ unsigned int vq_id = vq->vq_queue_index;
|
|
+
|
|
+ rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
|
|
+ vring_info = &vdev->vrings_info[vq_id];
|
|
+
|
|
+ return rpvdev->notify_wait(rpvdev->priv, vring_info->notifyid);
|
|
+}
|
|
+
|
|
static unsigned char rproc_virtio_get_status(struct virtio_device *vdev)
|
|
{
|
|
struct remoteproc_virtio *rpvdev;
|
|
@@ -179,6 +192,7 @@ static const struct virtio_dispatch remoteproc_virtio_dispatch_funcs = {
|
|
.get_features = rproc_virtio_get_features,
|
|
.read_config = rproc_virtio_read_config,
|
|
.notify = rproc_virtio_virtqueue_notify,
|
|
+ .notify_wait = rproc_virtio_notify_wait,
|
|
#ifndef VIRTIO_DEVICE_ONLY
|
|
/*
|
|
* We suppose here that the vdev is in a shared memory so that can
|
|
diff --git a/lib/rpmsg/rpmsg_virtio.c open-amp/lib/rpmsg/rpmsg_virtio.c
|
|
index c56e0cea..4960aa8a 100644
|
|
--- a/lib/rpmsg/rpmsg_virtio.c
|
|
+++ open-amp/lib/rpmsg/rpmsg_virtio.c
|
|
@@ -373,6 +373,13 @@ static void *rpmsg_virtio_get_tx_payload_buffer(struct rpmsg_device *rdev,
|
|
metal_mutex_release(&rdev->lock);
|
|
if (rp_hdr || !tick_count)
|
|
break;
|
|
+
|
|
+ status = rpmsg_virtio_notify_wait(rvdev, rvdev->rvq);
|
|
+ if (status == RPMSG_SUCCESS)
|
|
+ continue;
|
|
+ else if (status != RPMSG_ERR_NXIO)
|
|
+ break;
|
|
+
|
|
metal_sleep_usec(RPMSG_TICKS_PER_INTERVAL);
|
|
tick_count--;
|
|
}
|
|
--
|
|
2.25.1
|
|
|