Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

openamp: add new ops wait_tx_buffer() support #347

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/include/openamp/remoteproc.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,18 @@ struct remoteproc_ops {
int (*stop)(struct remoteproc *rproc);
int (*shutdown)(struct remoteproc *rproc);
int (*notify)(struct remoteproc *rproc, uint32_t id);
/**
* wait_notified
*
* 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 (*wait_notified)(struct remoteproc *rproc, uint32_t id);
/**
* get_mem
*
Expand Down
2 changes: 2 additions & 0 deletions lib/include/openamp/remoteproc_virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern "C" {

/* define vdev notification function user should implement */
typedef int (*rpvdev_notify_func)(void *priv, uint32_t id);
typedef int (*rpvdev_wait_notified_func)(void *priv, uint32_t id);
arnopo marked this conversation as resolved.
Show resolved Hide resolved

/**
* struct remoteproc_virtio
Expand All @@ -37,6 +38,7 @@ struct remoteproc_virtio {
void *vdev_rsc;
struct metal_io_region *vdev_rsc_io;
rpvdev_notify_func notify;
rpvdev_wait_notified_func wait_notified;
arnopo marked this conversation as resolved.
Show resolved Hide resolved
struct virtio_device vdev;
struct metal_list node;
};
Expand Down
1 change: 1 addition & 0 deletions lib/include/openamp/rpmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ extern "C" {
#define RPMSG_ERR_BUFF_SIZE (RPMSG_ERROR_BASE - 5)
#define RPMSG_ERR_INIT (RPMSG_ERROR_BASE - 6)
#define RPMSG_ERR_ADDR (RPMSG_ERROR_BASE - 7)
#define RPMSG_ERR_NXIO (RPMSG_ERROR_BASE - 8)

GUIDINGLI marked this conversation as resolved.
Show resolved Hide resolved
struct rpmsg_endpoint;
struct rpmsg_device;
Expand Down
9 changes: 9 additions & 0 deletions lib/include/openamp/rpmsg_virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@ rpmsg_virtio_create_virtqueues(struct rpmsg_virtio_device *rvdev,
callbacks);
}

static inline int
rpmsg_virtio_wait_notified(struct rpmsg_virtio_device *rvdev,
arnopo marked this conversation as resolved.
Show resolved Hide resolved
struct virtqueue *vq)
{
return rvdev->vdev->func->wait_notified ?
rvdev->vdev->func->wait_notified(rvdev->vdev, vq) :
RPMSG_ERR_NXIO;
}

/**
* rpmsg_virtio_get_buffer_size - get rpmsg virtio buffer size
*
Expand Down
1 change: 1 addition & 0 deletions lib/include/openamp/virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ struct virtio_dispatch {
void *src, int length);
void (*reset_device)(struct virtio_device *dev);
void (*notify)(struct virtqueue *vq);
int (*wait_notified)(struct virtio_device *dev, struct virtqueue *vq);
arnopo marked this conversation as resolved.
Show resolved Hide resolved
};

int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
Expand Down
11 changes: 11 additions & 0 deletions lib/remoteproc/remoteproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,16 @@ static int remoteproc_virtio_notify(void *priv, uint32_t id)
return 0;
}

static int remoteproc_virtio_wait_notified(void *priv, uint32_t id)
arnopo marked this conversation as resolved.
Show resolved Hide resolved
{
struct remoteproc *rproc = priv;

if (rproc->ops->wait_notified)
return rproc->ops->wait_notified(rproc, id);

return 0;
}

struct virtio_device *
remoteproc_create_virtio(struct remoteproc *rproc,
int vdev_id, unsigned int role,
Expand Down Expand Up @@ -927,6 +937,7 @@ remoteproc_create_virtio(struct remoteproc *rproc,
rproc_virtio_wait_remote_ready(vdev);

rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
rpvdev->wait_notified = remoteproc_virtio_wait_notified;
metal_list_add_tail(&rproc->vdevs, &rpvdev->node);
num_vrings = vdev_rsc->num_of_vrings;

Expand Down
14 changes: 14 additions & 0 deletions lib/remoteproc/remoteproc_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ static void rproc_virtio_virtqueue_notify(struct virtqueue *vq)
rpvdev->notify(rpvdev->priv, vring_info->notifyid);
}

static int rproc_virtio_wait_notified(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->wait_notified(rpvdev->priv, vring_info->notifyid);
}

static unsigned char rproc_virtio_get_status(struct virtio_device *vdev)
{
struct remoteproc_virtio *rpvdev;
Expand Down Expand Up @@ -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,
.wait_notified = rproc_virtio_wait_notified,
arnopo marked this conversation as resolved.
Show resolved Hide resolved
#ifndef VIRTIO_DEVICE_ONLY
/*
* We suppose here that the vdev is in a shared memory so that can
Expand Down
5 changes: 5 additions & 0 deletions lib/rpmsg/rpmsg_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,11 @@ static void *rpmsg_virtio_get_tx_payload_buffer(struct rpmsg_device *rdev,
metal_mutex_release(&rdev->lock);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to hold the lock, or re-lock the device during rpmsg_virtio_wait_tx_buffer()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need, you can assume the simplest user's implementation of wait_tx_buffer() is metal_sleep_usec().

if (rp_hdr || !tick_count)
break;

status = rpmsg_virtio_wait_notified(rvdev, rvdev->rvq);
if (status == RPMSG_SUCCESS)
continue;

metal_sleep_usec(RPMSG_TICKS_PER_INTERVAL);
tick_count--;
}
Expand Down