1 /* 2 * Generic virtio library for MINIX 3 3 * 4 * Copyright (c) 2013, A. Welzel, <arne.welzel@gmail.com> 5 * 6 * This software is released under the BSD license. See the LICENSE file 7 * included in the main directory of this source distribution for the 8 * license terms and conditions. 9 */ 10 11 #ifndef _MINIX_VIRTIO_H 12 #define _MINIX_VIRTIO_H 1 13 14 #include <sys/types.h> 15 16 #define VIRTIO_VENDOR_ID 0x1AF4 17 18 #define VIRTIO_HOST_F_OFF 0x0000 19 #define VIRTIO_GUEST_F_OFF 0x0004 20 #define VIRTIO_QADDR_OFF 0x0008 21 22 #define VIRTIO_QSIZE_OFF 0x000C 23 #define VIRTIO_QSEL_OFF 0x000E 24 #define VIRTIO_QNOTFIY_OFF 0x0010 25 26 #define VIRTIO_DEV_STATUS_OFF 0x0012 27 #define VIRTIO_ISR_STATUS_OFF 0x0013 28 #define VIRTIO_DEV_SPECIFIC_OFF 0x0014 29 /* if msi is enabled, device specific headers shift by 4 */ 30 #define VIRTIO_MSI_ADD_OFF 0x0004 31 #define VIRTIO_STATUS_ACK 0x01 32 #define VIRTIO_STATUS_DRV 0x02 33 #define VIRTIO_STATUS_DRV_OK 0x04 34 #define VIRTIO_STATUS_FAIL 0x80 35 36 37 /* Feature description */ 38 struct virtio_feature { 39 const char *name; 40 u8_t bit; 41 u8_t host_support; 42 u8_t guest_support; 43 }; 44 45 /* Forward declaration of struct virtio_device. 46 * 47 * This structure is opaque to the caller. 48 */ 49 struct virtio_device; 50 51 /* Find a virtio device with subdevice id subdevid. Returns a pointer 52 * to an opaque virtio_device instance. 53 */ 54 struct virtio_device *virtio_setup_device(u16_t subdevid, 55 const char *name, 56 struct virtio_feature *features, 57 int feature_count, 58 int threads, int skip); 59 60 /* Attempt to allocate queue_cnt memory for queues */ 61 int virtio_alloc_queues(struct virtio_device *dev, int num_queues); 62 63 /* Register the IRQ policy and indicate to the host we are ready to go */ 64 void virtio_device_ready(struct virtio_device *dev); 65 66 /* Unregister the IRQ and reset the device */ 67 void virtio_reset_device(struct virtio_device *dev); 68 69 /* Free the memory used by all queues */ 70 void virtio_free_queues(struct virtio_device *dev); 71 72 /* Free all memory allocated for the device (except the queue memory, 73 * which has to be freed before with virtio_free_queues()). 74 * 75 * Don't touch the device afterwards! This is like free(dev). 76 */ 77 void virtio_free_device(struct virtio_device *dev); 78 79 80 /* Feature helpers */ 81 int virtio_guest_supports(struct virtio_device *dev, int bit); 82 int virtio_host_supports(struct virtio_device *dev, int bit); 83 84 /* 85 * Use num vumap_phys elements and chain these as vring_desc elements 86 * into the vring. 87 * 88 * Kick the queue if needed. 89 * 90 * data is opaque and returned by virtio_from_queue() when the host 91 * processed the descriptor chain. 92 * 93 * Note: The last bit of vp_addr is used to flag whether an iovec is 94 * writable. This implies that only word aligned buffers can be 95 * used. 96 */ 97 int virtio_to_queue(struct virtio_device *dev, int qidx, 98 struct vumap_phys *bufs, size_t num, void *data); 99 100 /* 101 * If the host used a chain of descriptors, return 0 and set data 102 * as was given to virtio_to_queue(). If the host has not processed 103 * any element returns -1. 104 */ 105 int virtio_from_queue(struct virtio_device *dev, int qidx, void **data); 106 107 /* IRQ related functions */ 108 void virtio_irq_enable(struct virtio_device *dev); 109 void virtio_irq_disable(struct virtio_device *dev); 110 111 /* Checks the ISR field of the device and returns true if 112 * the interrupt was for this device. 113 */ 114 int virtio_had_irq(struct virtio_device *dev); 115 116 117 u32_t virtio_read32(struct virtio_device *dev, i32_t offset); 118 u16_t virtio_read16(struct virtio_device *dev, i32_t offset); 119 u8_t virtio_read8(struct virtio_device *dev, i32_t offset); 120 void virtio_write32(struct virtio_device *dev, i32_t offset, u32_t val); 121 void virtio_write16(struct virtio_device *dev, i32_t offset, u16_t val); 122 void virtio_write8(struct virtio_device *dev, i32_t offset, u8_t val); 123 124 125 /* 126 * Device specific reads take MSI offset into account and all reads 127 * are at offset 20. 128 * 129 * Something like: 130 * read(off) --> readX(20 + (msi ? 4 : 0) + off) 131 */ 132 u32_t virtio_sread32(struct virtio_device *dev, i32_t offset); 133 u16_t virtio_sread16(struct virtio_device *dev, i32_t offset); 134 u8_t virtio_sread8(struct virtio_device *dev, i32_t offset); 135 void virtio_swrite32(struct virtio_device *dev, i32_t offset, u32_t val); 136 void virtio_swrite16(struct virtio_device *dev, i32_t offset, u16_t val); 137 void virtio_swrite8(struct virtio_device *dev, i32_t offset, u8_t val); 138 139 #endif /* _MINIX_VIRTIO_H */ 140