virtio-uclass.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  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. #define LOG_CATEGORY UCLASS_VIRTIO
  18. #include <common.h>
  19. #include <dm.h>
  20. #include <log.h>
  21. #include <malloc.h>
  22. #include <virtio_types.h>
  23. #include <virtio.h>
  24. #include <dm/lists.h>
  25. #include <linux/bug.h>
  26. static const char *const virtio_drv_name[VIRTIO_ID_MAX_NUM] = {
  27. [VIRTIO_ID_NET] = VIRTIO_NET_DRV_NAME,
  28. [VIRTIO_ID_BLOCK] = VIRTIO_BLK_DRV_NAME,
  29. [VIRTIO_ID_RNG] = VIRTIO_RNG_DRV_NAME,
  30. };
  31. int virtio_get_config(struct udevice *vdev, unsigned int offset,
  32. void *buf, unsigned int len)
  33. {
  34. struct dm_virtio_ops *ops;
  35. ops = virtio_get_ops(vdev->parent);
  36. return ops->get_config(vdev->parent, offset, buf, len);
  37. }
  38. int virtio_set_config(struct udevice *vdev, unsigned int offset,
  39. void *buf, unsigned int len)
  40. {
  41. struct dm_virtio_ops *ops;
  42. ops = virtio_get_ops(vdev->parent);
  43. return ops->set_config(vdev->parent, offset, buf, len);
  44. }
  45. int virtio_generation(struct udevice *vdev, u32 *counter)
  46. {
  47. struct dm_virtio_ops *ops;
  48. ops = virtio_get_ops(vdev->parent);
  49. if (!ops->generation)
  50. return -ENOSYS;
  51. return ops->generation(vdev->parent, counter);
  52. }
  53. int virtio_get_status(struct udevice *vdev, u8 *status)
  54. {
  55. struct dm_virtio_ops *ops;
  56. ops = virtio_get_ops(vdev->parent);
  57. return ops->get_status(vdev->parent, status);
  58. }
  59. int virtio_set_status(struct udevice *vdev, u8 status)
  60. {
  61. struct dm_virtio_ops *ops;
  62. ops = virtio_get_ops(vdev->parent);
  63. return ops->set_status(vdev->parent, status);
  64. }
  65. int virtio_reset(struct udevice *vdev)
  66. {
  67. struct dm_virtio_ops *ops;
  68. ops = virtio_get_ops(vdev->parent);
  69. return ops->reset(vdev->parent);
  70. }
  71. int virtio_get_features(struct udevice *vdev, u64 *features)
  72. {
  73. struct dm_virtio_ops *ops;
  74. ops = virtio_get_ops(vdev->parent);
  75. return ops->get_features(vdev->parent, features);
  76. }
  77. int virtio_set_features(struct udevice *vdev)
  78. {
  79. struct dm_virtio_ops *ops;
  80. ops = virtio_get_ops(vdev->parent);
  81. return ops->set_features(vdev->parent);
  82. }
  83. int virtio_find_vqs(struct udevice *vdev, unsigned int nvqs,
  84. struct virtqueue *vqs[])
  85. {
  86. struct dm_virtio_ops *ops;
  87. ops = virtio_get_ops(vdev->parent);
  88. return ops->find_vqs(vdev->parent, nvqs, vqs);
  89. }
  90. int virtio_del_vqs(struct udevice *vdev)
  91. {
  92. struct dm_virtio_ops *ops;
  93. ops = virtio_get_ops(vdev->parent);
  94. return ops->del_vqs(vdev->parent);
  95. }
  96. int virtio_notify(struct udevice *vdev, struct virtqueue *vq)
  97. {
  98. struct dm_virtio_ops *ops;
  99. ops = virtio_get_ops(vdev->parent);
  100. return ops->notify(vdev->parent, vq);
  101. }
  102. void virtio_add_status(struct udevice *vdev, u8 status)
  103. {
  104. u8 old;
  105. if (!virtio_get_status(vdev, &old))
  106. virtio_set_status(vdev, old | status);
  107. }
  108. int virtio_finalize_features(struct udevice *vdev)
  109. {
  110. struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(vdev->parent);
  111. u8 status;
  112. int ret;
  113. ret = virtio_set_features(vdev);
  114. if (ret)
  115. return ret;
  116. if (uc_priv->legacy)
  117. return 0;
  118. virtio_add_status(vdev, VIRTIO_CONFIG_S_FEATURES_OK);
  119. ret = virtio_get_status(vdev, &status);
  120. if (ret)
  121. return ret;
  122. if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
  123. debug("(%s): device refuses features %x\n", vdev->name, status);
  124. return -ENODEV;
  125. }
  126. return 0;
  127. }
  128. void virtio_driver_features_init(struct virtio_dev_priv *priv,
  129. const u32 *feature,
  130. u32 feature_size,
  131. const u32 *feature_legacy,
  132. u32 feature_legacy_size)
  133. {
  134. priv->feature_table = feature;
  135. priv->feature_table_size = feature_size;
  136. priv->feature_table_legacy = feature_legacy;
  137. priv->feature_table_size_legacy = feature_legacy_size;
  138. }
  139. int virtio_init(void)
  140. {
  141. struct udevice *bus;
  142. int ret;
  143. /* Enumerate all known virtio devices */
  144. ret = uclass_first_device(UCLASS_VIRTIO, &bus);
  145. if (ret)
  146. return ret;
  147. while (bus) {
  148. ret = uclass_next_device(&bus);
  149. if (ret)
  150. break;
  151. }
  152. return ret;
  153. }
  154. static int virtio_uclass_pre_probe(struct udevice *udev)
  155. {
  156. struct dm_virtio_ops *ops;
  157. ops = (struct dm_virtio_ops *)(udev->driver->ops);
  158. /*
  159. * Check virtio transport driver ops here so that we don't need
  160. * check these ops each time when the virtio_xxx APIs are called.
  161. *
  162. * Only generation op is optional. All other ops are must-have.
  163. */
  164. if (!ops->get_config || !ops->set_config ||
  165. !ops->get_status || !ops->set_status ||
  166. !ops->get_features || !ops->set_features ||
  167. !ops->find_vqs || !ops->del_vqs ||
  168. !ops->reset || !ops->notify)
  169. return -ENOENT;
  170. return 0;
  171. }
  172. static int virtio_uclass_post_probe(struct udevice *udev)
  173. {
  174. struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
  175. char dev_name[30], *str;
  176. struct udevice *vdev;
  177. int ret;
  178. if (uc_priv->device >= VIRTIO_ID_MAX_NUM) {
  179. debug("(%s): virtio device ID %d exceeds maximum num\n",
  180. udev->name, uc_priv->device);
  181. return 0;
  182. }
  183. if (!virtio_drv_name[uc_priv->device]) {
  184. debug("(%s): underlying virtio device driver unavailable\n",
  185. udev->name);
  186. return 0;
  187. }
  188. snprintf(dev_name, sizeof(dev_name), "%s#%d",
  189. virtio_drv_name[uc_priv->device], dev_seq(udev));
  190. str = strdup(dev_name);
  191. if (!str)
  192. return -ENOMEM;
  193. ret = device_bind_driver(udev, virtio_drv_name[uc_priv->device],
  194. str, &vdev);
  195. if (ret == -ENOENT) {
  196. debug("(%s): no driver configured\n", udev->name);
  197. return 0;
  198. }
  199. if (ret) {
  200. free(str);
  201. return ret;
  202. }
  203. device_set_name_alloced(vdev);
  204. INIT_LIST_HEAD(&uc_priv->vqs);
  205. return 0;
  206. }
  207. static int virtio_uclass_child_post_bind(struct udevice *vdev)
  208. {
  209. /* Acknowledge that we've seen the device */
  210. virtio_add_status(vdev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
  211. return 0;
  212. }
  213. static int virtio_uclass_child_pre_probe(struct udevice *vdev)
  214. {
  215. struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(vdev->parent);
  216. u64 device_features;
  217. u64 driver_features;
  218. u64 driver_features_legacy;
  219. int i;
  220. int ret;
  221. /*
  222. * Save the real virtio device (eg: virtio-net, virtio-blk) to
  223. * the transport (parent) device's uclass priv for future use.
  224. */
  225. uc_priv->vdev = vdev;
  226. /*
  227. * We always start by resetting the device, in case a previous driver
  228. * messed it up. This also tests that code path a little.
  229. */
  230. ret = virtio_reset(vdev);
  231. if (ret)
  232. goto err;
  233. /* We have a driver! */
  234. virtio_add_status(vdev, VIRTIO_CONFIG_S_DRIVER);
  235. /* Figure out what features the device supports */
  236. virtio_get_features(vdev, &device_features);
  237. debug("(%s) plain device features supported %016llx\n",
  238. vdev->name, device_features);
  239. if (!(device_features & (1ULL << VIRTIO_F_VERSION_1)))
  240. uc_priv->legacy = true;
  241. /* Figure out what features the driver supports */
  242. driver_features = 0;
  243. for (i = 0; i < uc_priv->feature_table_size; i++) {
  244. unsigned int f = uc_priv->feature_table[i];
  245. WARN_ON(f >= 64);
  246. driver_features |= (1ULL << f);
  247. }
  248. /* Some drivers have a separate feature table for virtio v1.0 */
  249. if (uc_priv->feature_table_legacy) {
  250. driver_features_legacy = 0;
  251. for (i = 0; i < uc_priv->feature_table_size_legacy; i++) {
  252. unsigned int f = uc_priv->feature_table_legacy[i];
  253. WARN_ON(f >= 64);
  254. driver_features_legacy |= (1ULL << f);
  255. }
  256. } else {
  257. driver_features_legacy = driver_features;
  258. }
  259. if (uc_priv->legacy) {
  260. debug("(%s): legacy virtio device\n", vdev->name);
  261. uc_priv->features = driver_features_legacy & device_features;
  262. } else {
  263. debug("(%s): v1.0 complaint virtio device\n", vdev->name);
  264. uc_priv->features = driver_features & device_features;
  265. }
  266. /* Transport features always preserved to pass to finalize_features */
  267. for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++)
  268. if ((device_features & (1ULL << i)) &&
  269. (i == VIRTIO_F_VERSION_1))
  270. __virtio_set_bit(vdev->parent, i);
  271. debug("(%s) final negotiated features supported %016llx\n",
  272. vdev->name, uc_priv->features);
  273. ret = virtio_finalize_features(vdev);
  274. if (ret)
  275. goto err;
  276. return 0;
  277. err:
  278. virtio_add_status(vdev, VIRTIO_CONFIG_S_FAILED);
  279. return ret;
  280. }
  281. static int virtio_uclass_child_post_probe(struct udevice *vdev)
  282. {
  283. /* Indicates that the driver is set up and ready to drive the device */
  284. virtio_add_status(vdev, VIRTIO_CONFIG_S_DRIVER_OK);
  285. return 0;
  286. }
  287. UCLASS_DRIVER(virtio) = {
  288. .name = "virtio",
  289. .id = UCLASS_VIRTIO,
  290. .flags = DM_UC_FLAG_SEQ_ALIAS,
  291. .pre_probe = virtio_uclass_pre_probe,
  292. .post_probe = virtio_uclass_post_probe,
  293. .child_post_bind = virtio_uclass_child_post_bind,
  294. .child_pre_probe = virtio_uclass_child_pre_probe,
  295. .child_post_probe = virtio_uclass_child_post_probe,
  296. .per_device_auto = sizeof(struct virtio_dev_priv),
  297. };