board: cssi: Add CPU board CMPCPRO
[platform/kernel/u-boot.git] / drivers / virtio / virtio-uclass.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
4  * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
5  *
6  * VirtIO is a virtualization standard for network and disk device drivers
7  * where just the guest's device driver "knows" it is running in a virtual
8  * environment, and cooperates with the hypervisor. This enables guests to
9  * get high performance network and disk operations, and gives most of the
10  * performance benefits of paravirtualization. In the U-Boot case, the guest
11  * is U-Boot itself, while the virtual environment are normally QEMU targets
12  * like ARM, RISC-V and x86.
13  *
14  * See http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf for
15  * the VirtIO specification v1.0.
16  */
17
18 #define LOG_CATEGORY UCLASS_VIRTIO
19
20 #include <common.h>
21 #include <bootdev.h>
22 #include <dm.h>
23 #include <log.h>
24 #include <malloc.h>
25 #include <virtio_types.h>
26 #include <virtio.h>
27 #include <dm/lists.h>
28 #include <linux/bug.h>
29
30 static const char *const virtio_drv_name[VIRTIO_ID_MAX_NUM] = {
31         [VIRTIO_ID_NET]         = VIRTIO_NET_DRV_NAME,
32         [VIRTIO_ID_BLOCK]       = VIRTIO_BLK_DRV_NAME,
33         [VIRTIO_ID_RNG]         = VIRTIO_RNG_DRV_NAME,
34 };
35
36 int virtio_get_config(struct udevice *vdev, unsigned int offset,
37                       void *buf, unsigned int len)
38 {
39         struct dm_virtio_ops *ops;
40
41         ops = virtio_get_ops(vdev->parent);
42
43         return ops->get_config(vdev->parent, offset, buf, len);
44 }
45
46 int virtio_set_config(struct udevice *vdev, unsigned int offset,
47                       void *buf, unsigned int len)
48 {
49         struct dm_virtio_ops *ops;
50
51         ops = virtio_get_ops(vdev->parent);
52
53         return ops->set_config(vdev->parent, offset, buf, len);
54 }
55
56 int virtio_generation(struct udevice *vdev, u32 *counter)
57 {
58         struct dm_virtio_ops *ops;
59
60         ops = virtio_get_ops(vdev->parent);
61         if (!ops->generation)
62                 return -ENOSYS;
63
64         return ops->generation(vdev->parent, counter);
65 }
66
67 int virtio_get_status(struct udevice *vdev, u8 *status)
68 {
69         struct dm_virtio_ops *ops;
70
71         ops = virtio_get_ops(vdev->parent);
72
73         return ops->get_status(vdev->parent, status);
74 }
75
76 int virtio_set_status(struct udevice *vdev, u8 status)
77 {
78         struct dm_virtio_ops *ops;
79
80         ops = virtio_get_ops(vdev->parent);
81
82         return ops->set_status(vdev->parent, status);
83 }
84
85 int virtio_reset(struct udevice *vdev)
86 {
87         struct dm_virtio_ops *ops;
88
89         ops = virtio_get_ops(vdev->parent);
90
91         return ops->reset(vdev->parent);
92 }
93
94 int virtio_get_features(struct udevice *vdev, u64 *features)
95 {
96         struct dm_virtio_ops *ops;
97
98         ops = virtio_get_ops(vdev->parent);
99
100         return ops->get_features(vdev->parent, features);
101 }
102
103 int virtio_set_features(struct udevice *vdev)
104 {
105         struct dm_virtio_ops *ops;
106
107         ops = virtio_get_ops(vdev->parent);
108
109         return ops->set_features(vdev->parent);
110 }
111
112 int virtio_find_vqs(struct udevice *vdev, unsigned int nvqs,
113                     struct virtqueue *vqs[])
114 {
115         struct dm_virtio_ops *ops;
116
117         ops = virtio_get_ops(vdev->parent);
118
119         return ops->find_vqs(vdev->parent, nvqs, vqs);
120 }
121
122 int virtio_del_vqs(struct udevice *vdev)
123 {
124         struct dm_virtio_ops *ops;
125
126         ops = virtio_get_ops(vdev->parent);
127
128         return ops->del_vqs(vdev->parent);
129 }
130
131 int virtio_notify(struct udevice *vdev, struct virtqueue *vq)
132 {
133         struct dm_virtio_ops *ops;
134
135         ops = virtio_get_ops(vdev->parent);
136
137         return ops->notify(vdev->parent, vq);
138 }
139
140 void virtio_add_status(struct udevice *vdev, u8 status)
141 {
142         u8 old;
143
144         if (!virtio_get_status(vdev, &old))
145                 virtio_set_status(vdev, old | status);
146 }
147
148 int virtio_finalize_features(struct udevice *vdev)
149 {
150         struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(vdev->parent);
151         u8 status;
152         int ret;
153
154         ret = virtio_set_features(vdev);
155         if (ret)
156                 return ret;
157
158         if (uc_priv->legacy)
159                 return 0;
160
161         virtio_add_status(vdev, VIRTIO_CONFIG_S_FEATURES_OK);
162         ret = virtio_get_status(vdev, &status);
163         if (ret)
164                 return ret;
165         if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
166                 debug("(%s): device refuses features %x\n", vdev->name, status);
167                 return -EINVAL;
168         }
169
170         return 0;
171 }
172
173 void virtio_driver_features_init(struct virtio_dev_priv *priv,
174                                  const u32 *feature,
175                                  u32 feature_size,
176                                  const u32 *feature_legacy,
177                                  u32 feature_legacy_size)
178 {
179         priv->feature_table = feature;
180         priv->feature_table_size = feature_size;
181         priv->feature_table_legacy = feature_legacy;
182         priv->feature_table_size_legacy = feature_legacy_size;
183 }
184
185 int virtio_init(void)
186 {
187         /* Enumerate all known virtio devices */
188         return uclass_probe_all(UCLASS_VIRTIO);
189 }
190
191 static int virtio_uclass_pre_probe(struct udevice *udev)
192 {
193         struct dm_virtio_ops *ops;
194
195         ops = (struct dm_virtio_ops *)(udev->driver->ops);
196
197         /*
198          * Check virtio transport driver ops here so that we don't need
199          * check these ops each time when the virtio_xxx APIs are called.
200          *
201          * Only generation op is optional. All other ops are must-have.
202          */
203         if (!ops->get_config || !ops->set_config ||
204             !ops->get_status || !ops->set_status ||
205             !ops->get_features || !ops->set_features ||
206             !ops->find_vqs || !ops->del_vqs ||
207             !ops->reset || !ops->notify)
208                 return -ENOENT;
209
210         return 0;
211 }
212
213 static int virtio_uclass_post_probe(struct udevice *udev)
214 {
215         struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
216         char dev_name[30], *str;
217         struct udevice *vdev;
218         const char *name;
219         int ret;
220
221         if (uc_priv->device >= VIRTIO_ID_MAX_NUM) {
222                 debug("(%s): virtio device ID %d exceeds maximum num\n",
223                       udev->name, uc_priv->device);
224                 return 0;
225         }
226
227         name = virtio_drv_name[uc_priv->device];
228         if (!name) {
229                 debug("(%s): underlying virtio device driver unavailable\n",
230                       udev->name);
231                 return 0;
232         }
233
234         snprintf(dev_name, sizeof(dev_name), "%s#%d", name, dev_seq(udev));
235         str = strdup(dev_name);
236         if (!str)
237                 return -ENOMEM;
238
239         ret = device_bind_driver(udev, name, str, &vdev);
240         if (ret == -ENOENT) {
241                 debug("(%s): no driver configured\n", udev->name);
242                 return 0;
243         }
244         if (ret) {
245                 free(str);
246                 return ret;
247         }
248         device_set_name_alloced(vdev);
249
250         if (uc_priv->device == VIRTIO_ID_BLOCK && !IS_ENABLED(CONFIG_SANDBOX)) {
251                 ret = bootdev_setup_sibling_blk(vdev, "virtio_bootdev");
252                 if (ret)
253                         return log_msg_ret("bootdev", ret);
254         }
255
256         INIT_LIST_HEAD(&uc_priv->vqs);
257
258         return 0;
259 }
260
261 static int virtio_uclass_child_post_bind(struct udevice *vdev)
262 {
263         /* Acknowledge that we've seen the device */
264         virtio_add_status(vdev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
265
266         return 0;
267 }
268
269 static int virtio_uclass_child_pre_probe(struct udevice *vdev)
270 {
271         struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(vdev->parent);
272         u64 device_features;
273         u64 driver_features;
274         u64 driver_features_legacy;
275         int i;
276         int ret;
277
278         /* bootdevs are not virtio devices */
279         if (device_get_uclass_id(vdev) == UCLASS_BOOTDEV)
280                 return 0;
281
282         /*
283          * Save the real virtio device (eg: virtio-net, virtio-blk) to
284          * the transport (parent) device's uclass priv for future use.
285          */
286         uc_priv->vdev = vdev;
287
288         /*
289          * We always start by resetting the device, in case a previous driver
290          * messed it up. This also tests that code path a little.
291          */
292         ret = virtio_reset(vdev);
293         if (ret)
294                 goto err;
295
296         /* We have a driver! */
297         virtio_add_status(vdev, VIRTIO_CONFIG_S_DRIVER);
298
299         /* Figure out what features the device supports */
300         virtio_get_features(vdev, &device_features);
301         debug("(%s) plain device features supported %016llx\n",
302               vdev->name, device_features);
303         if (!(device_features & (1ULL << VIRTIO_F_VERSION_1)))
304                 uc_priv->legacy = true;
305
306         /* Figure out what features the driver supports */
307         driver_features = 0;
308         for (i = 0; i < uc_priv->feature_table_size; i++) {
309                 unsigned int f = uc_priv->feature_table[i];
310
311                 WARN_ON(f >= 64);
312                 driver_features |= (1ULL << f);
313         }
314
315         /* Some drivers have a separate feature table for virtio v1.0 */
316         if (uc_priv->feature_table_legacy) {
317                 driver_features_legacy = 0;
318                 for (i = 0; i < uc_priv->feature_table_size_legacy; i++) {
319                         unsigned int f = uc_priv->feature_table_legacy[i];
320
321                         WARN_ON(f >= 64);
322                         driver_features_legacy |= (1ULL << f);
323                 }
324         } else {
325                 driver_features_legacy = driver_features;
326         }
327
328         if (uc_priv->legacy) {
329                 debug("(%s): legacy virtio device\n", vdev->name);
330                 uc_priv->features = driver_features_legacy & device_features;
331         } else {
332                 debug("(%s): v1.0 complaint virtio device\n", vdev->name);
333                 uc_priv->features = driver_features & device_features;
334         }
335
336         /* Transport features always preserved to pass to finalize_features */
337         for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++)
338                 if ((device_features & (1ULL << i)) &&
339                     (i == VIRTIO_F_VERSION_1))
340                         __virtio_set_bit(vdev->parent, i);
341
342         debug("(%s) final negotiated features supported %016llx\n",
343               vdev->name, uc_priv->features);
344         ret = virtio_finalize_features(vdev);
345         if (ret)
346                 goto err;
347
348         return 0;
349
350 err:
351         virtio_add_status(vdev, VIRTIO_CONFIG_S_FAILED);
352         return ret;
353 }
354
355 static int virtio_uclass_child_post_probe(struct udevice *vdev)
356 {
357         /* Indicates that the driver is set up and ready to drive the device */
358         virtio_add_status(vdev, VIRTIO_CONFIG_S_DRIVER_OK);
359
360         return 0;
361 }
362
363 static int virtio_bootdev_bind(struct udevice *dev)
364 {
365         struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
366
367         ucp->prio = BOOTDEVP_4_SCAN_FAST;
368
369         return 0;
370 }
371
372 static int virtio_bootdev_hunt(struct bootdev_hunter *info, bool show)
373 {
374         int ret;
375
376         ret = uclass_probe_all(UCLASS_VIRTIO);
377         if (ret && ret != -ENOENT)
378                 return log_msg_ret("vir", ret);
379
380         return 0;
381 }
382
383 UCLASS_DRIVER(virtio) = {
384         .name   = "virtio",
385         .id     = UCLASS_VIRTIO,
386         .flags  = DM_UC_FLAG_SEQ_ALIAS,
387         .pre_probe = virtio_uclass_pre_probe,
388         .post_probe = virtio_uclass_post_probe,
389         .child_post_bind = virtio_uclass_child_post_bind,
390         .child_pre_probe = virtio_uclass_child_pre_probe,
391         .child_post_probe = virtio_uclass_child_post_probe,
392         .per_device_auto        = sizeof(struct virtio_dev_priv),
393 };
394
395 struct bootdev_ops virtio_bootdev_ops = {
396 };
397
398 static const struct udevice_id virtio_bootdev_ids[] = {
399         { .compatible = "u-boot,bootdev-virtio" },
400         { }
401 };
402
403 U_BOOT_DRIVER(virtio_bootdev) = {
404         .name           = "virtio_bootdev",
405         .id             = UCLASS_BOOTDEV,
406         .ops            = &virtio_bootdev_ops,
407         .bind           = virtio_bootdev_bind,
408         .of_match       = virtio_bootdev_ids,
409 };
410
411 BOOTDEV_HUNTER(virtio_bootdev_hunter) = {
412         .prio           = BOOTDEVP_4_SCAN_FAST,
413         .uclass         = UCLASS_VIRTIO,
414         .hunt           = virtio_bootdev_hunt,
415         .drv            = DM_DRIVER_REF(virtio_bootdev),
416 };