remoteproc: support virtio config space.

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>
This commit is contained in:
Sjur Brændeland 2013-02-21 18:15:39 +01:00 committed by Ohad Ben-Cohen
parent a2b950ac7b
commit 92b38f8514
3 changed files with 64 additions and 22 deletions

View File

@ -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;

View File

@ -173,25 +173,35 @@ error:
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");
}
@ -199,13 +209,19 @@ static void rproc_virtio_reset(struct virtio_device *vdev)
static u32 rproc_virtio_get_features(struct virtio_device *vdev)
{
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct fw_rsc_vdev *rsc;
return rvdev->dfeatures;
rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;
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);
@ -213,13 +229,44 @@ static void rproc_virtio_finalize_features(struct virtio_device *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 = {
@ -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,
};
/*

View File

@ -469,8 +469,6 @@ 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 {
@ -478,8 +476,6 @@ struct rproc_vdev {
struct rproc *rproc;
struct virtio_device vdev;
struct rproc_vring vring[RVDEV_NUM_VRINGS];
unsigned long dfeatures;
unsigned long gfeatures;
u32 rsc_offset;
};