Skip to content

Commit

Permalink
remoteproc: support virtio config space.
Browse files Browse the repository at this point in the history
Support virtio configuration space and device status. The virtio
device can now access the resource table in shared memory.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
Acked-by: Ido Yariv <ido@wizery.com>
[rebase and style changes]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
  • Loading branch information
Sjur Brændeland authored and ohadbc committed Apr 7, 2013
1 parent a2b950a commit 92b38f8
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 22 deletions.
3 changes: 0 additions & 3 deletions drivers/remoteproc/remoteproc_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,6 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
goto free_rvdev;
}

/* remember the device features */
rvdev->dfeatures = rsc->dfeatures;

/* remember the resource offset*/
rvdev->rsc_offset = offset;

Expand Down
79 changes: 64 additions & 15 deletions drivers/remoteproc/remoteproc_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,53 +173,100 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
return ret;
}

/*
* We don't support yet real virtio status semantics.
*
* The plan is to provide this via the VDEV resource entry
* which is part of the firmware: this way the remote processor
* will be able to access the status values as set by us.
*/
static u8 rproc_virtio_get_status(struct virtio_device *vdev)
{
return 0;
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct fw_rsc_vdev *rsc;

rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;

return rsc->status;
}

static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status)
{
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct fw_rsc_vdev *rsc;

rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;

rsc->status = status;
dev_dbg(&vdev->dev, "status: %d\n", status);
}

static void rproc_virtio_reset(struct virtio_device *vdev)
{
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct fw_rsc_vdev *rsc;

rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;

rsc->status = 0;
dev_dbg(&vdev->dev, "reset !\n");
}

/* provide the vdev features as retrieved from the firmware */
static u32 rproc_virtio_get_features(struct virtio_device *vdev)
{
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct fw_rsc_vdev *rsc;

rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;

return rvdev->dfeatures;
return rsc->dfeatures;
}

static void rproc_virtio_finalize_features(struct virtio_device *vdev)
{
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct fw_rsc_vdev *rsc;

rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;

/* Give virtio_ring a chance to accept features */
vring_transport_features(vdev);

/*
* Remember the finalized features of our vdev, and provide it
* to the remote processor once it is powered on.
*
* Similarly to the status field, we don't expose yet the negotiated
* features to the remote processors at this point. This will be
* fixed as part of a small resource table overhaul and then an
* extension of the virtio resource entries.
*/
rvdev->gfeatures = vdev->features[0];
rsc->gfeatures = vdev->features[0];
}

static void rproc_virtio_get(struct virtio_device *vdev, unsigned offset,
void *buf, unsigned len)
{
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct fw_rsc_vdev *rsc;
void *cfg;

rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;
cfg = &rsc->vring[rsc->num_of_vrings];

if (offset + len > rsc->config_len || offset + len < len) {
dev_err(&vdev->dev, "rproc_virtio_get: access out of bounds\n");
return;
}

memcpy(buf, cfg + offset, len);
}

static void rproc_virtio_set(struct virtio_device *vdev, unsigned offset,
const void *buf, unsigned len)
{
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct fw_rsc_vdev *rsc;
void *cfg;

rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;
cfg = &rsc->vring[rsc->num_of_vrings];

if (offset + len > rsc->config_len || offset + len < len) {
dev_err(&vdev->dev, "rproc_virtio_set: access out of bounds\n");
return;
}

memcpy(cfg + offset, buf, len);
}

static const struct virtio_config_ops rproc_virtio_config_ops = {
Expand All @@ -230,6 +277,8 @@ static const struct virtio_config_ops rproc_virtio_config_ops = {
.reset = rproc_virtio_reset,
.set_status = rproc_virtio_set_status,
.get_status = rproc_virtio_get_status,
.get = rproc_virtio_get,
.set = rproc_virtio_set,
};

/*
Expand Down
4 changes: 0 additions & 4 deletions include/linux/remoteproc.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,17 +469,13 @@ struct rproc_vring {
* @rproc: the rproc handle
* @vdev: the virio device
* @vring: the vrings for this vdev
* @dfeatures: virtio device features
* @gfeatures: virtio guest features
* @rsc_offset: offset of the vdev's resource entry
*/
struct rproc_vdev {
struct list_head node;
struct rproc *rproc;
struct virtio_device vdev;
struct rproc_vring vring[RVDEV_NUM_VRINGS];
unsigned long dfeatures;
unsigned long gfeatures;
u32 rsc_offset;
};

Expand Down

0 comments on commit 92b38f8

Please sign in to comment.