Commit 92b38f85 authored by Sjur Brændeland's avatar Sjur Brændeland Committed by Ohad Ben-Cohen
Browse files

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: default avatarSjur Brændeland <sjur.brandeland@stericsson.com>
Acked-by: default avatarIdo Yariv <ido@wizery.com>
[rebase and style changes]
Signed-off-by: default avatarOhad Ben-Cohen <ohad@wizery.com>
parent a2b950ac
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -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;

+64 −15
Original line number Diff line number Diff line
@@ -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;

	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);
@@ -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,
};

/*
+0 −4
Original line number Diff line number Diff line
@@ -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;
};