1 /* $OpenBSD: virtio.h,v 1.5 2016/09/02 17:08:28 stefan Exp $ */ 2 3 /* 4 * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <dev/pci/virtioreg.h> 20 21 #define VIRTQUEUE_ALIGN(n) (((n)+(VIRTIO_PAGE_SIZE-1))& \ 22 ~(VIRTIO_PAGE_SIZE-1)) 23 24 /* Queue sizes must be power of two */ 25 #define VIORND_QUEUE_SIZE 64 26 #define VIORND_QUEUE_MASK (VIORND_QUEUE_SIZE - 1) 27 28 #define VIOBLK_QUEUE_SIZE 64 29 #define VIOBLK_QUEUE_MASK (VIOBLK_QUEUE_SIZE - 1) 30 31 #define VIONET_QUEUE_SIZE 64 32 #define VIONET_QUEUE_MASK (VIONET_QUEUE_SIZE - 1) 33 34 /* All the devices we support have either 1 or 2 queues */ 35 #define VIRTIO_MAX_QUEUES 2 36 37 /* 38 * This struct stores notifications from a virtio driver. There is 39 * one such struct per virtio device. 40 */ 41 struct virtio_io_cfg { 42 uint32_t device_feature; 43 uint32_t guest_feature; 44 uint32_t queue_address; 45 uint16_t queue_size; 46 uint16_t queue_select; 47 uint16_t queue_notify; 48 uint8_t device_status; 49 uint8_t isr_status; 50 }; 51 52 /* 53 * A virtio device can have several virtqs. For example, vionet has one virtq 54 * each for transmitting and receiving packets. This struct describes the state 55 * of one virtq, such as their address in memory, size, offsets of rings, etc. 56 * There is one virtio_vq_info per virtq. 57 */ 58 struct virtio_vq_info { 59 /* Guest physical address of virtq */ 60 uint32_t qa; 61 62 /* Queue size: number of queue entries in virtq */ 63 uint32_t qs; 64 65 /* 66 * The offset of the 'available' ring within the virtq located at 67 * guest physical address qa above 68 */ 69 uint32_t vq_availoffset; 70 71 /* 72 * The offset of the 'used' ring within the virtq located at guest 73 * physical address qa above 74 */ 75 uint32_t vq_usedoffset; 76 77 /* 78 * The index into a slot of the 'available' ring that a virtio device 79 * can consume next 80 */ 81 uint16_t last_avail; 82 83 /* 84 * The most recent index into the 'available' ring that a virtio 85 * driver notified to the host. 86 */ 87 uint16_t notified_avail; 88 }; 89 90 struct viornd_dev { 91 struct virtio_io_cfg cfg; 92 93 struct virtio_vq_info vq[VIRTIO_MAX_QUEUES]; 94 }; 95 96 struct vioblk_dev { 97 struct virtio_io_cfg cfg; 98 99 struct virtio_vq_info vq[VIRTIO_MAX_QUEUES]; 100 101 int fd; 102 uint64_t sz; 103 }; 104 105 struct vionet_dev { 106 pthread_mutex_t mutex; 107 struct event event; 108 109 struct virtio_io_cfg cfg; 110 111 struct virtio_vq_info vq[VIRTIO_MAX_QUEUES]; 112 113 int fd, rx_added; 114 int rx_pending; 115 uint32_t vm_id; 116 int irq; 117 uint8_t mac[6]; 118 }; 119 120 struct virtio_net_hdr { 121 uint8_t flags; 122 uint8_t gso_type; 123 uint16_t hdr_len; 124 uint16_t gso_size; 125 uint16_t csum_start; 126 uint16_t csum_offset; 127 128 /* 129 * num_buffers is only used if VIRTIO_NET_F_MRG_RXBUF is negotiated. 130 * vmd(8) doesn't negotiate that, but the field is listed here 131 * for completeness sake. 132 */ 133 /* uint16_t num_buffers; */ 134 }; 135 136 137 void virtio_init(struct vm_create_params *, int *, int *); 138 uint32_t vring_size(uint32_t); 139 140 int virtio_rnd_io(int, uint16_t, uint32_t *, uint8_t *, void *); 141 void viornd_update_qs(void); 142 void viornd_update_qa(void); 143 int viornd_notifyq(void); 144 145 int virtio_blk_io(int, uint16_t, uint32_t *, uint8_t *, void *); 146 void vioblk_update_qs(struct vioblk_dev *); 147 void vioblk_update_qa(struct vioblk_dev *); 148 int vioblk_notifyq(struct vioblk_dev *); 149 150 int virtio_net_io(int, uint16_t, uint32_t *, uint8_t *, void *); 151 void vionet_update_qs(struct vionet_dev *); 152 void vionet_update_qa(struct vionet_dev *); 153 int vionet_notifyq(struct vionet_dev *); 154 void vionet_notify_rx(struct vionet_dev *); 155 int vionet_process_rx(void); 156 int vionet_enq_rx(struct vionet_dev *, char *, ssize_t, int *); 157 158 const char *vioblk_cmd_name(uint32_t); 159