]> git.proxmox.com Git - mirror_qemu.git/blame - pc-bios/s390-ccw/virtio.h
pc-bios/s390-ccw: add virtio-scsi implementation
[mirror_qemu.git] / pc-bios / s390-ccw / virtio.h
CommitLineData
1e17c2c1
AG
1/*
2 * Virtio driver bits
3 *
4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or (at
7 * your option) any later version. See the COPYING file in the top-level
8 * directory.
9 */
10
11#ifndef VIRTIO_H
12#define VIRTIO_H
13
14#include "s390-ccw.h"
15
16/* Status byte for guest to report progress, and synchronize features. */
17/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
18#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
19/* We have found a driver for the device. */
20#define VIRTIO_CONFIG_S_DRIVER 2
21/* Driver has used its parts of the config, and is happy */
22#define VIRTIO_CONFIG_S_DRIVER_OK 4
23/* We've given up on this device. */
24#define VIRTIO_CONFIG_S_FAILED 0x80
25
b88d7fa5 26enum VirtioDevType {
1e17c2c1
AG
27 VIRTIO_ID_NET = 1,
28 VIRTIO_ID_BLOCK = 2,
29 VIRTIO_ID_CONSOLE = 3,
30 VIRTIO_ID_BALLOON = 5,
31};
b88d7fa5
ED
32typedef enum VirtioDevType VirtioDevType;
33
34struct VirtioDevHeader {
35 VirtioDevType type:8;
36 uint8_t num_vq;
37 uint8_t feature_len;
38 uint8_t config_len;
39 uint8_t status;
40 uint8_t vqconfig[];
1e17c2c1 41} __attribute__((packed));
b88d7fa5 42typedef struct VirtioDevHeader VirtioDevHeader;
1e17c2c1 43
b88d7fa5
ED
44struct VirtioVqConfig {
45 uint64_t token;
46 uint64_t address;
47 uint16_t num;
48 uint8_t pad[6];
1e17c2c1 49} __attribute__((packed));
b88d7fa5 50typedef struct VirtioVqConfig VirtioVqConfig;
1e17c2c1 51
b88d7fa5
ED
52struct VqInfo {
53 uint64_t queue;
54 uint32_t align;
55 uint16_t index;
56 uint16_t num;
1e17c2c1 57} __attribute__((packed));
b88d7fa5 58typedef struct VqInfo VqInfo;
1e17c2c1 59
b88d7fa5
ED
60struct VqConfig {
61 uint16_t index;
62 uint16_t num;
abbbe3de 63} __attribute__((packed));
b88d7fa5 64typedef struct VqConfig VqConfig;
abbbe3de 65
b88d7fa5
ED
66struct VirtioDev {
67 VirtioDevHeader *header;
68 VirtioVqConfig *vqconfig;
1e17c2c1
AG
69 char *host_features;
70 char *guest_features;
71 char *config;
72};
b88d7fa5 73typedef struct VirtioDev VirtioDev;
1e17c2c1 74
85129891
ED
75#define VIRTIO_RING_SIZE (PAGE_SIZE * 8)
76#define VIRTIO_MAX_VQS 3
abd696e4 77#define KVM_S390_VIRTIO_RING_ALIGN 4096
1e17c2c1
AG
78
79#define VRING_USED_F_NO_NOTIFY 1
80
81/* This marks a buffer as continuing via the next field. */
82#define VRING_DESC_F_NEXT 1
83/* This marks a buffer as write-only (otherwise read-only). */
84#define VRING_DESC_F_WRITE 2
85/* This means the buffer contains a list of buffer descriptors. */
86#define VRING_DESC_F_INDIRECT 4
87
88/* Internal flag to mark follow-up segments as such */
89#define VRING_HIDDEN_IS_CHAIN 256
90
91/* Virtio ring descriptors: 16 bytes. These can chain together via "next". */
b88d7fa5 92struct VRingDesc {
1e17c2c1 93 /* Address (guest-physical). */
b88d7fa5 94 uint64_t addr;
1e17c2c1 95 /* Length. */
b88d7fa5 96 uint32_t len;
1e17c2c1 97 /* The flags as indicated above. */
b88d7fa5 98 uint16_t flags;
1e17c2c1 99 /* We chain unused descriptors via this, too */
b88d7fa5 100 uint16_t next;
1e17c2c1 101} __attribute__((packed));
b88d7fa5 102typedef struct VRingDesc VRingDesc;
1e17c2c1 103
b88d7fa5
ED
104struct VRingAvail {
105 uint16_t flags;
106 uint16_t idx;
107 uint16_t ring[];
1e17c2c1 108} __attribute__((packed));
b88d7fa5 109typedef struct VRingAvail VRingAvail;
1e17c2c1 110
b88d7fa5
ED
111/* uint32_t is used here for ids for padding reasons. */
112struct VRingUsedElem {
1e17c2c1 113 /* Index of start of used descriptor chain. */
b88d7fa5 114 uint32_t id;
1e17c2c1 115 /* Total length of the descriptor chain which was used (written to) */
b88d7fa5 116 uint32_t len;
1e17c2c1 117} __attribute__((packed));
b88d7fa5 118typedef struct VRingUsedElem VRingUsedElem;
1e17c2c1 119
b88d7fa5
ED
120struct VRingUsed {
121 uint16_t flags;
122 uint16_t idx;
123 VRingUsedElem ring[];
1e17c2c1 124} __attribute__((packed));
b88d7fa5 125typedef struct VRingUsed VRingUsed;
1e17c2c1 126
b88d7fa5 127struct VRing {
1e17c2c1
AG
128 unsigned int num;
129 int next_idx;
441ea695 130 int used_idx;
b88d7fa5
ED
131 VRingDesc *desc;
132 VRingAvail *avail;
133 VRingUsed *used;
134 SubChannelId schid;
85129891
ED
135 long cookie;
136 int id;
1e17c2c1 137};
b88d7fa5 138typedef struct VRing VRing;
1e17c2c1
AG
139
140
141/***********************************************
142 * Virtio block *
143 ***********************************************/
144
145/*
146 * Command types
147 *
148 * Usage is a bit tricky as some bits are used as flags and some are not.
149 *
150 * Rules:
151 * VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or
152 * VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own
153 * and may not be combined with any of the other flags.
154 */
155
156/* These two define direction. */
157#define VIRTIO_BLK_T_IN 0
158#define VIRTIO_BLK_T_OUT 1
159
160/* This bit says it's a scsi command, not an actual read or write. */
161#define VIRTIO_BLK_T_SCSI_CMD 2
162
163/* Cache flush command */
164#define VIRTIO_BLK_T_FLUSH 4
165
166/* Barrier before this op. */
167#define VIRTIO_BLK_T_BARRIER 0x80000000
168
169/* This is the first element of the read scatter-gather list. */
b88d7fa5 170struct VirtioBlkOuthdr {
1e17c2c1 171 /* VIRTIO_BLK_T* */
b88d7fa5 172 uint32_t type;
1e17c2c1 173 /* io priority. */
b88d7fa5 174 uint32_t ioprio;
1e17c2c1 175 /* Sector (ie. 512 byte offset) */
b88d7fa5 176 uint64_t sector;
1e17c2c1 177};
b88d7fa5 178typedef struct VirtioBlkOuthdr VirtioBlkOuthdr;
1e17c2c1 179
b88d7fa5
ED
180struct VirtioBlkConfig {
181 uint64_t capacity; /* in 512-byte sectors */
182 uint32_t size_max; /* max segment size (if VIRTIO_BLK_F_SIZE_MAX) */
183 uint32_t seg_max; /* max number of segments (if VIRTIO_BLK_F_SEG_MAX) */
91a03f9b 184
b88d7fa5
ED
185 struct VirtioBlkGeometry {
186 uint16_t cylinders;
187 uint8_t heads;
188 uint8_t sectors;
91a03f9b
ED
189 } geometry; /* (if VIRTIO_BLK_F_GEOMETRY) */
190
b88d7fa5 191 uint32_t blk_size; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
91a03f9b
ED
192
193 /* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */
b88d7fa5
ED
194 uint8_t physical_block_exp; /* exponent for physical blk per logical blk */
195 uint8_t alignment_offset; /* alignment offset in logical blocks */
196 uint16_t min_io_size; /* min I/O size without performance penalty
91a03f9b 197 in logical blocks */
b88d7fa5 198 uint32_t opt_io_size; /* optimal sustained I/O size in logical blks */
91a03f9b 199
b88d7fa5
ED
200 uint8_t wce; /* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
201} __attribute__((packed));
202typedef struct VirtioBlkConfig VirtioBlkConfig;
91a03f9b 203
a1102ceb
ED
204enum guessed_disk_nature_type {
205 VIRTIO_GDN_NONE = 0,
206 VIRTIO_GDN_DASD = 1,
207 VIRTIO_GDN_CDROM = 2,
208 VIRTIO_GDN_SCSI = 3,
209};
210typedef enum guessed_disk_nature_type VirtioGDN;
211
212VirtioGDN virtio_guessed_disk_nature(void);
91a03f9b
ED
213void virtio_assume_scsi(void);
214void virtio_assume_eckd(void);
866cac91 215void virtio_assume_iso9660(void);
91a03f9b
ED
216
217extern bool virtio_disk_is_scsi(void);
218extern bool virtio_disk_is_eckd(void);
219extern bool virtio_ipl_disk_is_valid(void);
220extern int virtio_get_block_size(void);
91a03f9b
ED
221extern uint8_t virtio_get_heads(void);
222extern uint8_t virtio_get_sectors(void);
f04db28b 223extern uint64_t virtio_get_blocks(void);
91a03f9b
ED
224extern int virtio_read_many(ulong sector, void *load_addr, int sec_num);
225
226#define VIRTIO_SECTOR_SIZE 512
227
91a03f9b
ED
228static inline ulong virtio_sector_adjust(ulong sector)
229{
38150be8 230 return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE);
91a03f9b
ED
231}
232
69429682
ED
233struct VDev {
234 int nr_vqs;
235 VRing *vrings;
236 int cmd_vr_idx;
237 void *ring_area;
238 long wait_reply_timeout;
a1102ceb 239 VirtioGDN guessed_disk_nature;
69429682
ED
240 SubChannelId schid;
241 SenseId senseid;
242 union {
243 VirtioBlkConfig blk;
244 } config;
245};
246typedef struct VDev VDev;
247
248VDev *virtio_get_device(void);
249VirtioDevType virtio_get_device_type(void);
250
8944edc3
ED
251struct VirtioCmd {
252 void *data;
253 int size;
254 int flags;
255};
256typedef struct VirtioCmd VirtioCmd;
257
258int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd);
259
1e17c2c1 260#endif /* VIRTIO_H */