nuttx/openamp/0004-openamp-add-new-ops-notify_wait-support.patch

190 lines
6.5 KiB
Diff
Raw Permalink Normal View History

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 04/10] 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