1/* 2 * Copyright (c) 2014 ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#ifndef VIRTIO_VIRTIO_DEVICE_H 11#define VIRTIO_VIRTIO_DEVICE_H 12 13struct virtio_device; 14 15/* 16 * 2.1 Device Status Field 17 */ 18 19/// The device is in the reset state (not discovered by the guest) 20#define VIRTIO_DEVICE_STATUS_RESET 0x00 21 22/// Guest OS has found the device and recognized it as a valid virtio device. 23#define VIRTIO_DEVICE_STATUS_ACKNOWLEDGE 0x01 24 25/// Guest OS knows how to drive the device i.e. recognized as valid virtio device. 26#define VIRTIO_DEVICE_STATUS_DRIVER 0x02 27 28/// Driver is set up and ready to drive the device. 29#define VIRTIO_DEVICE_STATUS_DRIVER_OK 0x04 30 31/// Driver has acknowledged all the features it understands 32#define VIRTIO_DEVICE_STATUS_FEATURES_OK 0x08 33 34/// Something went wrong in the guest, and it has given up on the device. 35#define VIRTIO_DEVICE_STATUS_FAILED 0x80 36 37/* 38 * 5.0 Device Types 39 * The following device IDs are used to identify different types of virtio 40 * devices. Some device IDs are reserved for devices which are not currently 41 * defined in this standard. 42 */ 43 44/// Invalid device identifier 45#define VIRTIO_DEVICE_TYPE_INVALID 0x00 46 47/// Device type for network interface cards 48#define VIRTIO_DEVICE_TYPE_NET 0x01 49 50/// Device type for block devices 51#define VIRTIO_DEVICE_TYPE_BLOCK 0x02 52 53/// Device type for console devices 54#define VIRTIO_DEVICE_TYPE_CONSOLE 0x03 55 56/// Device type for entorpy devices 57#define VIRTIO_DEVICE_TYPE_ENTORPY 0x04 58 59//#define VIRTIO_DEVICE_TYPE_LEGACY_BALLOON 5 60 61/// Device type for IO memory devices 62#define VIRTIO_DEVICE_TYPE_IOMEM 0x06 63 64/// Device type for rpmgs devices 65#define VIRTIO_DEVICE_TYPE_RPMSG 0x07 66 67/// Device type for SCSI host devices 68#define VIRTIO_DEVICE_TYPE_SCSIHOST 0x08 69 70/// Device type for 9P transport devices 71#define VIRTIO_DEVICE_TYPE_9PTRANSP 0x09 72 73/// Device type for MAC 802.11 WLAn devices 74#define VIRTIO_DEVICE_TYPE_WLAN 0x0A 75 76/// Device type for RPROC serial devices 77#define VIRTIO_DEVICE_TYPE_SERIAL 0x0B 78 79/// Device type for virtio CAIF devices 80#define VIRTIO_DEVICE_TYPE_CAIF 0x0C 81 82/// Device type for memory ballooning devices 83#define VIRTIO_DEVICE_TYPE_BALLOON 0x0D 84 85/// Device type for GPU devices 86#define VIRTIO_DEVICE_TYPE_GPU 0x0E 87 88/// Device type for timer / clock devices 89#define VIRTIO_DEVICE_TYPE_TIMER 0x0F 90 91/** 92 * specifies the possible virtio backends to be used 93 */ 94enum virtio_backend { 95 VIRTIO_DEVICE_BACKEND_INVALID, 96 VIRTIO_DEVICE_BACKEND_PCI, 97 VIRTIO_DEVICE_BACKEND_MMIO, 98 VIRTIO_DEVICE_BACKEND_IO, 99}; 100 101/** 102 * driver specific device status 103 */ 104enum virtio_state { 105 VIRTIO_DEVICE_S_INVALID, 106 VIRTIO_DEVICE_S_INITIALIZING, 107 VIRTIO_DEVICE_S_READY, 108 VIRTIO_DEVICE_S_TERMINATING, 109 VIRTIO_DEVICE_S_ERROR, 110}; 111 112/* 113 * 4.1.2 PCI Device Discovery 114 * 115 * Any PCI device with Vendor ID 0x1AF4, and Device ID 0x1000 through 0x103F 116 * inclusive is a virtio device. The Subsystem Device ID indicates which virtio 117 * device is supported by the device. 118 */ 119#define VIRTIO_PCI_VENDOR_ID 0x1AF4 120#define VIRTIO_PCI_DEVICE_ID 0x1000 121#define VIRTIO_PCI_DEVICE_ID2 0x103F 122 123#define VIRTIO_DEVICE_NAME_MAX 32 124 125#define VIRTIO_DEVICE_HC_IFACE_MAX 32 126 127 128/* 129 * Function pointers type definitions 130 */ 131 132/// interrupt handler when the device configuration space changes 133typedef void (*config_intr_handler_t)(struct virtio_device *dev); 134 135/// device specific initialization function 136typedef errval_t (*virtio_device_setup_t)(struct virtio_device *dev, 137 void *state); 138 139struct virtio_backend_arg { 140 enum virtio_backend type; 141 union { 142 struct { 143 struct capref dev_cap; ///< 144 void *dev_base; 145 size_t dev_size; 146 } mmio; 147 struct { 148 struct capref dev_cap; 149 /* TODO: fill in needed fieds */ 150 } pci; 151 struct { 152 struct capref dev_cap; 153 /* TODO: fill in needed fieds */ 154 } io; 155 } args; 156}; 157 158 159/** 160 * contains necessary values for the device initialization process 161 */ 162struct virtio_device_setup 163{ 164 uint8_t dev_type; ///< expected VirtIO type of the device 165 char dev_name[VIRTIO_DEVICE_NAME_MAX]; 166 struct capref dev_cap; 167 void *dev_t_st; ///< pointer to device type specific state 168 uint64_t features; ///< VirtIO feature bits supported 169 170 struct virtio_backend_arg backend; ///< arguments for the backend 171 172 virtio_device_setup_t setup_fn; 173 void *setup_arg; 174 175 config_intr_handler_t config_intr_fn; 176 177 uint16_t vq_num; 178 struct virtqueue_setup *vq_setup; 179#ifdef __VIRTIO_HOST__ 180 enum virtio_host hc_type; 181 char *hc_iface; 182 struct virtio_host_cb *hc_cb; 183 lpaddr_t hc_offset; 184#endif 185}; 186 187 188 189 190/** 191 * \brief initializes a new VirtIO device based on the values passed with the 192 * device init struct. The device registers have already to be mapped. * 193 * 194 * \param dev device structure to initialize 195 * \param init additional information passed for the init process 196 * \param dev_regs memory location of the device registers 197 */ 198errval_t virtio_device_open(struct virtio_device **dev, 199 struct virtio_device_setup *init); 200 201/** 202 * \brief initializes a new VirtIO device based on the values passed with the 203 * device init struct. The supplied cap contains the memory range of the 204 * device registers. 205 * 206 * \param dev device structure to initialize 207 * \param init additional information passed for the init process 208 * \param dev_cap capability representing the device registers 209 */ 210errval_t virtio_device_open_with_cap(struct virtio_device **dev, 211 struct virtio_device_setup *init, 212 struct capref dev_cap); 213 214/** 215 * \brief closes a virtio device. 216 * 217 * \param dev the device to be closed 218 * 219 * \returns SYS_ERR_OK on success 220 */ 221errval_t virtio_device_close(struct virtio_device *dev); 222 223/** 224 * \brief resets the virtio device 225 * 226 * \param dev the device to reset 227 * 228 * \returns SYS_ERR_OK on success 229 */ 230errval_t virtio_device_reset(struct virtio_device *dev); 231 232/** 233 * \brief returns the status of a virtio device 234 * 235 * \param the device to query for status 236 * \param returned status 237 * 238 * \returns SYS_ERR_OK on success 239 */ 240errval_t virtio_device_get_status(struct virtio_device *dev, 241 uint32_t *ret_status); 242 243/** 244 * \brief sets the status bit of the device 245 * 246 * \param dev the VirtIO device 247 * \param status the status bit to set 248 * 249 * \return SYS_ERR_OK on success 250 */ 251errval_t virtio_device_set_status(struct virtio_device *dev, 252 uint8_t status); 253 254/** 255 * \brief tells the device which features the driver understands 256 * 257 * \param dev the VirtIO device 258 * \param features bitmap of understood features 259 * 260 * \return SYS_ERR_OK on success 261 */ 262errval_t virtio_device_set_driver_features(struct virtio_device *dev, 263 uint64_t features); 264 265/** 266 * \brief queries the device which features it understands 267 * 268 * \param dev the VirtIO device 269 * \param features bitmap of understood features by the device 270 * 271 * \return SYS_ERR_OK on success 272 */ 273errval_t virtio_device_get_device_features(struct virtio_device *dev, 274 uint64_t *ret_features); 275 276/** 277 * \brief wrapper for calling the device specific initialization function 278 * 279 * \param dev the VirtIO device 280 * \param arg argument pointer to the initialization function 281 * 282 * \returns SYS_ERR_OK on success 283 * VIRTIO_ERR_* on failure 284 */ 285errval_t virtio_device_specific_setup(struct virtio_device *dev, 286 void *arg); 287 288/** 289 * \brief checks if a certain feature is negotiated and understood by both 290 * device and driver. 291 * 292 * \param dev the VirtIO device 293 * \param feature feature bit to check 294 * 295 * \returns true - if feature bit was set 296 * false - if the featurebit was not set 297 */ 298bool virtio_device_has_feature(struct virtio_device *dev, 299 uint8_t feature); 300 301/** 302 * \brief negotiates the supported features based on the offered device features 303 * and the supplied driver features 304 * 305 * \param dev the VirtIO device 306 * \param driver_featurs bitmask of understood features by the device 307 * 308 * \returns SYS_ERR_OK on success 309 */ 310errval_t virtio_device_feature_negotiate(struct virtio_device *dev, 311 uint64_t driver_features); 312 313/** 314 * \brief reads the device configuration space and copies it into a local buffer 315 * 316 * \param vdev virtio device 317 * \param buf pointer to the buffer to store the data 318 * \param len the length of the buffer 319 * 320 * \returns SYS_ERR_OK on success 321 */ 322errval_t virtio_device_config_read(struct virtio_device *vdev, 323 void *buf, 324 size_t len); 325/** 326 * \brief writes to the configuration space of a device 327 * 328 * \param vdev virtio device 329 * \param buf pointer to the buffer with data to update 330 * \param len the length of the buffer 331 * 332 * \returns SYS_ERR_OK on success 333 */ 334errval_t virtio_device_config_write(struct virtio_device *dev, 335 void *config, 336 size_t offset, 337 size_t length); 338 339/** 340 * \brief Returns the pointer to the device specific structure 341 * 342 * \param vdev to get the device specific pointer 343 * 344 * \returns device specific struct pointer 345 */ 346void *virtio_device_get_type_state(struct virtio_device *vdev); 347 348/** 349 * \brief allocates the virtqueues for this device based on the setup information 350 * 351 * \param vdev virtio device to allocate the queues for 352 * \param vq_setup setup information for the virtqueues 353 * \param vq_num number of virtqueues to allocate 354 * 355 * \returns SYS_ERR_OK on success 356 */ 357errval_t virtio_device_virtqueue_alloc(struct virtio_device *vdev, 358 struct virtqueue_setup *vq_setup, 359 uint16_t vq_num); 360 361/** 362 * \brief notifies the host about new descriptors available in the 363 * available ring 364 * 365 * \param vdev VirtIO device 366 * \param virtq_id the virtq to signal on 367 * 368 * \return SYS_ERR_OK on success 369 */ 370errval_t virtio_device_notify_host(struct virtio_device *vdev, 371 uint16_t virtq_id); 372 373#ifdef __VIRTIO_HOST__ 374/** 375 * \brief returns a pointer to a virtqueue of the device 376 * 377 * \param vdev VirtIO device 378 * \param vq_idx the queue index of the queue we want 379 * 380 * \returns pointer to the requested virtqueue 381 * NULL if no such virtqueue exists 382 */ 383struct virtqueue_host *virtio_device_get_host_virtq(struct virtio_device *vdev, 384 uint16_t vq_idx); 385#else 386/** 387 * \brief returns a pointer to a virtqueue of the device 388 * 389 * \param vdev VirtIO device 390 * \param vq_idx the queue index of the queue we want 391 * 392 * \returns pointer to the requested virtqueue 393 * NULL if no such virtqueue exists 394 */ 395struct virtqueue *virtio_device_get_virtq(struct virtio_device *vdev, 396 uint16_t vq_idx); 397 398 399/** 400 * \brief exposes the virtqueue to the device such that it can be used 401 * 402 * \param dev the VirtIO device 403 * \param vq the virtqueue to be added to the device 404 * 405 * \return SYS_ERR_OK on success 406 */ 407errval_t virtio_device_set_virtq(struct virtio_device *dev, 408 struct virtqueue *vq); 409#endif 410/** 411 * \brief sets the interrupt handler for the configuration space interrupts 412 * 413 * \param dev the VirtIO device 414 * \param fn handler function 415 * 416 * \return SYS_ERR_OK on success 417 */ 418errval_t virtio_device_set_config_intr_handler(struct virtio_device *dev, 419 config_intr_handler_t fn); 420 421#endif // VIRTIO_VIRTIO_DEVICE_H 422