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