aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBin Meng2018-10-15 04:21:25 -0500
committerSimon Glass2018-11-14 11:16:28 -0600
commit640aae0fb1f8b5741e62782cf06fc0f1beb0f612 (patch)
tree731a017023f272e6d30db386cea6233d1fa65159
parent699aae0800983b0230bffe999d149e7323537cb3 (diff)
downloadu-boot-640aae0fb1f8b5741e62782cf06fc0f1beb0f612.tar.gz
u-boot-640aae0fb1f8b5741e62782cf06fc0f1beb0f612.tar.xz
u-boot-640aae0fb1f8b5741e62782cf06fc0f1beb0f612.zip
virtio: Add a Sandbox transport driver
This driver provides support for Sandbox implementation of virtio transport driver which is used for testing purpose only. Two drivers are provided. The 2nd one is a driver that lacks the 'notify' op. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
-rw-r--r--drivers/virtio/Kconfig8
-rw-r--r--drivers/virtio/Makefile1
-rw-r--r--drivers/virtio/virtio_sandbox.c233
3 files changed, 242 insertions, 0 deletions
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 753912f0f9..a9d5fd07b7 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -37,6 +37,14 @@ config VIRTIO_PCI
37 This driver provides support for virtio based paravirtual device 37 This driver provides support for virtio based paravirtual device
38 drivers over PCI. 38 drivers over PCI.
39 39
40config VIRTIO_SANDBOX
41 bool "Sandbox driver for virtio devices"
42 depends on SANDBOX
43 select VIRTIO
44 help
45 This driver provides support for Sandbox implementation of virtio
46 transport driver which is used for testing purpose only.
47
40config VIRTIO_NET 48config VIRTIO_NET
41 bool "virtio net driver" 49 bool "virtio net driver"
42 depends on VIRTIO 50 depends on VIRTIO
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 072fb563b3..4579044ae3 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -6,5 +6,6 @@
6obj-y += virtio-uclass.o virtio_ring.o 6obj-y += virtio-uclass.o virtio_ring.o
7obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o 7obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
8obj-$(CONFIG_VIRTIO_PCI) += virtio_pci_legacy.o virtio_pci_modern.o 8obj-$(CONFIG_VIRTIO_PCI) += virtio_pci_legacy.o virtio_pci_modern.o
9obj-$(CONFIG_VIRTIO_SANDBOX) += virtio_sandbox.o
9obj-$(CONFIG_VIRTIO_NET) += virtio_net.o 10obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
10obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o 11obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
diff --git a/drivers/virtio/virtio_sandbox.c b/drivers/virtio/virtio_sandbox.c
new file mode 100644
index 0000000000..2addb1ebc5
--- /dev/null
+++ b/drivers/virtio/virtio_sandbox.c
@@ -0,0 +1,233 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
4 *
5 * VirtIO Sandbox transport driver, for testing purpose only
6 */
7
8#include <common.h>
9#include <dm.h>
10#include <virtio_types.h>
11#include <virtio.h>
12#include <virtio_ring.h>
13#include <linux/compat.h>
14#include <linux/io.h>
15
16struct virtio_sandbox_priv {
17 u8 id;
18 u8 status;
19 u64 device_features;
20 u64 driver_features;
21 ulong queue_desc;
22 ulong queue_available;
23 ulong queue_used;
24};
25
26static int virtio_sandbox_get_config(struct udevice *udev, unsigned int offset,
27 void *buf, unsigned int len)
28{
29 return 0;
30}
31
32static int virtio_sandbox_set_config(struct udevice *udev, unsigned int offset,
33 const void *buf, unsigned int len)
34{
35 return 0;
36}
37
38static int virtio_sandbox_get_status(struct udevice *udev, u8 *status)
39{
40 struct virtio_sandbox_priv *priv = dev_get_priv(udev);
41
42 *status = priv->status;
43
44 return 0;
45}
46
47static int virtio_sandbox_set_status(struct udevice *udev, u8 status)
48{
49 struct virtio_sandbox_priv *priv = dev_get_priv(udev);
50
51 /* We should never be setting status to 0 */
52 WARN_ON(status == 0);
53
54 priv->status = status;
55
56 return 0;
57}
58
59static int virtio_sandbox_reset(struct udevice *udev)
60{
61 struct virtio_sandbox_priv *priv = dev_get_priv(udev);
62
63 /* 0 status means a reset */
64 priv->status = 0;
65
66 return 0;
67}
68
69static int virtio_sandbox_get_features(struct udevice *udev, u64 *features)
70{
71 struct virtio_sandbox_priv *priv = dev_get_priv(udev);
72
73 *features = priv->device_features;
74
75 return 0;
76}
77
78static int virtio_sandbox_set_features(struct udevice *udev)
79{
80 struct virtio_sandbox_priv *priv = dev_get_priv(udev);
81 struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
82
83 priv->driver_features = uc_priv->features;
84
85 return 0;
86}
87
88static struct virtqueue *virtio_sandbox_setup_vq(struct udevice *udev,
89 unsigned int index)
90{
91 struct virtio_sandbox_priv *priv = dev_get_priv(udev);
92 struct virtqueue *vq;
93 ulong addr;
94 int err;
95
96 /* Create the vring */
97 vq = vring_create_virtqueue(index, 4, 4096, udev);
98 if (!vq) {
99 err = -ENOMEM;
100 goto error_new_virtqueue;
101 }
102
103 addr = virtqueue_get_desc_addr(vq);
104 priv->queue_desc = addr;
105
106 addr = virtqueue_get_avail_addr(vq);
107 priv->queue_available = addr;
108
109 addr = virtqueue_get_used_addr(vq);
110 priv->queue_used = addr;
111
112 return vq;
113
114error_new_virtqueue:
115 return ERR_PTR(err);
116}
117
118static void virtio_sandbox_del_vq(struct virtqueue *vq)
119{
120 vring_del_virtqueue(vq);
121}
122
123static int virtio_sandbox_del_vqs(struct udevice *udev)
124{
125 struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
126 struct virtqueue *vq, *n;
127
128 list_for_each_entry_safe(vq, n, &uc_priv->vqs, list)
129 virtio_sandbox_del_vq(vq);
130
131 return 0;
132}
133
134static int virtio_sandbox_find_vqs(struct udevice *udev, unsigned int nvqs,
135 struct virtqueue *vqs[])
136{
137 int i;
138
139 for (i = 0; i < nvqs; ++i) {
140 vqs[i] = virtio_sandbox_setup_vq(udev, i);
141 if (IS_ERR(vqs[i])) {
142 virtio_sandbox_del_vqs(udev);
143 return PTR_ERR(vqs[i]);
144 }
145 }
146
147 return 0;
148}
149
150static int virtio_sandbox_notify(struct udevice *udev, struct virtqueue *vq)
151{
152 return 0;
153}
154
155static int virtio_sandbox_probe(struct udevice *udev)
156{
157 struct virtio_sandbox_priv *priv = dev_get_priv(udev);
158 struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
159
160 /* fake some information for testing */
161 priv->device_features = VIRTIO_F_VERSION_1;
162 uc_priv->device = VIRTIO_ID_BLOCK;
163 uc_priv->vendor = ('u' << 24) | ('b' << 16) | ('o' << 8) | 't';
164
165 return 0;
166}
167
168/* check virtio device driver's remove routine was called to reset the device */
169static int virtio_sandbox_child_post_remove(struct udevice *vdev)
170{
171 u8 status;
172
173 virtio_get_status(vdev, &status);
174 if (status)
175 panic("virtio device was not reset\n");
176
177 return 0;
178}
179
180static const struct dm_virtio_ops virtio_sandbox1_ops = {
181 .get_config = virtio_sandbox_get_config,
182 .set_config = virtio_sandbox_set_config,
183 .get_status = virtio_sandbox_get_status,
184 .set_status = virtio_sandbox_set_status,
185 .reset = virtio_sandbox_reset,
186 .get_features = virtio_sandbox_get_features,
187 .set_features = virtio_sandbox_set_features,
188 .find_vqs = virtio_sandbox_find_vqs,
189 .del_vqs = virtio_sandbox_del_vqs,
190 .notify = virtio_sandbox_notify,
191};
192
193static const struct udevice_id virtio_sandbox1_ids[] = {
194 { .compatible = "sandbox,virtio1" },
195 { }
196};
197
198U_BOOT_DRIVER(virtio_sandbox1) = {
199 .name = "virtio-sandbox1",
200 .id = UCLASS_VIRTIO,
201 .of_match = virtio_sandbox1_ids,
202 .ops = &virtio_sandbox1_ops,
203 .probe = virtio_sandbox_probe,
204 .child_post_remove = virtio_sandbox_child_post_remove,
205 .priv_auto_alloc_size = sizeof(struct virtio_sandbox_priv),
206};
207
208/* this one without notify op */
209static const struct dm_virtio_ops virtio_sandbox2_ops = {
210 .get_config = virtio_sandbox_get_config,
211 .set_config = virtio_sandbox_set_config,
212 .get_status = virtio_sandbox_get_status,
213 .set_status = virtio_sandbox_set_status,
214 .reset = virtio_sandbox_reset,
215 .get_features = virtio_sandbox_get_features,
216 .set_features = virtio_sandbox_set_features,
217 .find_vqs = virtio_sandbox_find_vqs,
218 .del_vqs = virtio_sandbox_del_vqs,
219};
220
221static const struct udevice_id virtio_sandbox2_ids[] = {
222 { .compatible = "sandbox,virtio2" },
223 { }
224};
225
226U_BOOT_DRIVER(virtio_sandbox2) = {
227 .name = "virtio-sandbox2",
228 .id = UCLASS_VIRTIO,
229 .of_match = virtio_sandbox2_ids,
230 .ops = &virtio_sandbox2_ops,
231 .probe = virtio_sandbox_probe,
232 .priv_auto_alloc_size = sizeof(struct virtio_sandbox_priv),
233};