1
2
3
4
5
6
7
8
9
10
11#ifndef VIRTIO_H
12#define VIRTIO_H
13
14
15
16#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
17
18#define VIRTIO_CONFIG_S_DRIVER 2
19
20#define VIRTIO_CONFIG_S_DRIVER_OK 4
21
22#define VIRTIO_CONFIG_S_FAILED 0x80
23
24enum VirtioDevType {
25 VIRTIO_ID_NET = 1,
26 VIRTIO_ID_BLOCK = 2,
27 VIRTIO_ID_CONSOLE = 3,
28 VIRTIO_ID_BALLOON = 5,
29 VIRTIO_ID_SCSI = 8,
30};
31typedef enum VirtioDevType VirtioDevType;
32
33struct VqInfo {
34 uint64_t queue;
35 uint32_t align;
36 uint16_t index;
37 uint16_t num;
38} __attribute__((packed));
39typedef struct VqInfo VqInfo;
40
41struct VqConfig {
42 uint16_t index;
43 uint16_t num;
44} __attribute__((packed));
45typedef struct VqConfig VqConfig;
46
47#define VIRTIO_RING_SIZE (PAGE_SIZE * 8)
48#define VIRTIO_MAX_VQS 3
49#define KVM_S390_VIRTIO_RING_ALIGN 4096
50
51#define VRING_USED_F_NO_NOTIFY 1
52
53
54#define VRING_DESC_F_NEXT 1
55
56#define VRING_DESC_F_WRITE 2
57
58#define VRING_DESC_F_INDIRECT 4
59
60
61#define VRING_HIDDEN_IS_CHAIN 256
62
63
64struct VRingDesc {
65
66 uint64_t addr;
67
68 uint32_t len;
69
70 uint16_t flags;
71
72 uint16_t next;
73} __attribute__((packed));
74typedef struct VRingDesc VRingDesc;
75
76struct VRingAvail {
77 uint16_t flags;
78 uint16_t idx;
79 uint16_t ring[];
80} __attribute__((packed));
81typedef struct VRingAvail VRingAvail;
82
83
84struct VRingUsedElem {
85
86 uint32_t id;
87
88 uint32_t len;
89} __attribute__((packed));
90typedef struct VRingUsedElem VRingUsedElem;
91
92struct VRingUsed {
93 uint16_t flags;
94 uint16_t idx;
95 VRingUsedElem ring[];
96} __attribute__((packed));
97typedef struct VRingUsed VRingUsed;
98
99struct VRing {
100 unsigned int num;
101 int next_idx;
102 int used_idx;
103 VRingDesc *desc;
104 VRingAvail *avail;
105 VRingUsed *used;
106 SubChannelId schid;
107 long cookie;
108 int id;
109};
110typedef struct VRing VRing;
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129#define VIRTIO_BLK_T_IN 0
130#define VIRTIO_BLK_T_OUT 1
131
132
133#define VIRTIO_BLK_T_SCSI_CMD 2
134
135
136#define VIRTIO_BLK_T_FLUSH 4
137
138
139#define VIRTIO_BLK_T_BARRIER 0x80000000
140
141
142struct VirtioBlkOuthdr {
143
144 uint32_t type;
145
146 uint32_t ioprio;
147
148 uint64_t sector;
149};
150typedef struct VirtioBlkOuthdr VirtioBlkOuthdr;
151
152struct VirtioBlkConfig {
153 uint64_t capacity;
154 uint32_t size_max;
155 uint32_t seg_max;
156
157 struct VirtioBlkGeometry {
158 uint16_t cylinders;
159 uint8_t heads;
160 uint8_t sectors;
161 } geometry;
162
163 uint32_t blk_size;
164
165
166 uint8_t physical_block_exp;
167 uint8_t alignment_offset;
168 uint16_t min_io_size;
169
170 uint32_t opt_io_size;
171
172 uint8_t wce;
173} __attribute__((packed));
174typedef struct VirtioBlkConfig VirtioBlkConfig;
175
176enum guessed_disk_nature_type {
177 VIRTIO_GDN_NONE = 0,
178 VIRTIO_GDN_DASD = 1,
179 VIRTIO_GDN_CDROM = 2,
180 VIRTIO_GDN_SCSI = 3,
181};
182typedef enum guessed_disk_nature_type VirtioGDN;
183
184VirtioGDN virtio_guessed_disk_nature(void);
185void virtio_assume_eckd(void);
186void virtio_assume_iso9660(void);
187
188bool virtio_ipl_disk_is_valid(void);
189int virtio_get_block_size(void);
190uint8_t virtio_get_heads(void);
191uint8_t virtio_get_sectors(void);
192uint64_t virtio_get_blocks(void);
193int virtio_read_many(unsigned long sector, void *load_addr, int sec_num);
194
195#define VIRTIO_SECTOR_SIZE 512
196#define VIRTIO_ISO_BLOCK_SIZE 2048
197#define VIRTIO_SCSI_BLOCK_SIZE 512
198#define VIRTIO_DASD_DEFAULT_BLOCK_SIZE 4096
199
200static inline unsigned long virtio_sector_adjust(unsigned long sector)
201{
202 return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE);
203}
204
205struct VirtioScsiConfig {
206 uint32_t num_queues;
207 uint32_t seg_max;
208 uint32_t max_sectors;
209 uint32_t cmd_per_lun;
210 uint32_t event_info_size;
211 uint32_t sense_size;
212 uint32_t cdb_size;
213 uint16_t max_channel;
214 uint16_t max_target;
215 uint32_t max_lun;
216} __attribute__((packed));
217typedef struct VirtioScsiConfig VirtioScsiConfig;
218
219struct ScsiDevice {
220 uint16_t channel;
221 uint16_t target;
222 uint32_t lun;
223};
224typedef struct ScsiDevice ScsiDevice;
225
226struct VirtioNetConfig {
227 uint8_t mac[6];
228
229
230};
231typedef struct VirtioNetConfig VirtioNetConfig;
232
233struct VDev {
234 int nr_vqs;
235 VRing *vrings;
236 int cmd_vr_idx;
237 void *ring_area;
238 long wait_reply_timeout;
239 VirtioGDN guessed_disk_nature;
240 SubChannelId schid;
241 SenseId senseid;
242 union {
243 VirtioBlkConfig blk;
244 VirtioScsiConfig scsi;
245 VirtioNetConfig net;
246 } config;
247 ScsiDevice *scsi_device;
248 bool is_cdrom;
249 int scsi_block_size;
250 int blk_factor;
251 uint64_t scsi_last_block;
252 uint32_t scsi_dev_cyls;
253 uint8_t scsi_dev_heads;
254 bool scsi_device_selected;
255 ScsiDevice selected_scsi_device;
256 uint64_t netboot_start_addr;
257 uint32_t max_transfer;
258 uint32_t guest_features[2];
259};
260typedef struct VDev VDev;
261
262VDev *virtio_get_device(void);
263VirtioDevType virtio_get_device_type(void);
264
265struct VirtioCmd {
266 void *data;
267 int size;
268 int flags;
269};
270typedef struct VirtioCmd VirtioCmd;
271
272bool vring_notify(VRing *vr);
273int drain_irqs(SubChannelId schid);
274void vring_send_buf(VRing *vr, void *p, int len, int flags);
275int vr_poll(VRing *vr);
276int vring_wait_reply(void);
277int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd);
278void virtio_setup_ccw(VDev *vdev);
279
280int virtio_net_init(void *mac_addr);
281
282#endif
283