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:
Родитель
a2b950ac7b
Коммит
92b38f8514
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче