xref: /minix/minix/include/minix/virtio.h (revision 7f5f010b)
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