cputlb: Split out load/store_memop
[qemu/ar7.git] / pc-bios / s390-ccw / virtio.h
blob19fceb6495f3c129de9d1e4179011976f3bb879f
1 /*
2 * Virtio driver bits
4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
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 */
11 #ifndef VIRTIO_H
12 #define VIRTIO_H
14 /* Status byte for guest to report progress, and synchronize features. */
15 /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
16 #define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
17 /* We have found a driver for the device. */
18 #define VIRTIO_CONFIG_S_DRIVER 2
19 /* Driver has used its parts of the config, and is happy */
20 #define VIRTIO_CONFIG_S_DRIVER_OK 4
21 /* We've given up on this device. */
22 #define VIRTIO_CONFIG_S_FAILED 0x80
24 enum 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,
31 typedef enum VirtioDevType VirtioDevType;
33 struct VqInfo {
34 uint64_t queue;
35 uint32_t align;
36 uint16_t index;
37 uint16_t num;
38 } __attribute__((packed));
39 typedef struct VqInfo VqInfo;
41 struct VqConfig {
42 uint16_t index;
43 uint16_t num;
44 } __attribute__((packed));
45 typedef struct VqConfig VqConfig;
47 #define VIRTIO_RING_SIZE (PAGE_SIZE * 8)
48 #define VIRTIO_MAX_VQS 3
49 #define KVM_S390_VIRTIO_RING_ALIGN 4096
51 #define VRING_USED_F_NO_NOTIFY 1
53 /* This marks a buffer as continuing via the next field. */
54 #define VRING_DESC_F_NEXT 1
55 /* This marks a buffer as write-only (otherwise read-only). */
56 #define VRING_DESC_F_WRITE 2
57 /* This means the buffer contains a list of buffer descriptors. */
58 #define VRING_DESC_F_INDIRECT 4
60 /* Internal flag to mark follow-up segments as such */
61 #define VRING_HIDDEN_IS_CHAIN 256
63 /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */
64 struct VRingDesc {
65 /* Address (guest-physical). */
66 uint64_t addr;
67 /* Length. */
68 uint32_t len;
69 /* The flags as indicated above. */
70 uint16_t flags;
71 /* We chain unused descriptors via this, too */
72 uint16_t next;
73 } __attribute__((packed));
74 typedef struct VRingDesc VRingDesc;
76 struct VRingAvail {
77 uint16_t flags;
78 uint16_t idx;
79 uint16_t ring[];
80 } __attribute__((packed));
81 typedef struct VRingAvail VRingAvail;
83 /* uint32_t is used here for ids for padding reasons. */
84 struct VRingUsedElem {
85 /* Index of start of used descriptor chain. */
86 uint32_t id;
87 /* Total length of the descriptor chain which was used (written to) */
88 uint32_t len;
89 } __attribute__((packed));
90 typedef struct VRingUsedElem VRingUsedElem;
92 struct VRingUsed {
93 uint16_t flags;
94 uint16_t idx;
95 VRingUsedElem ring[];
96 } __attribute__((packed));
97 typedef struct VRingUsed VRingUsed;
99 struct 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;
110 typedef struct VRing VRing;
113 /***********************************************
114 * Virtio block *
115 ***********************************************/
118 * Command types
120 * Usage is a bit tricky as some bits are used as flags and some are not.
122 * Rules:
123 * VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or
124 * VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own
125 * and may not be combined with any of the other flags.
128 /* These two define direction. */
129 #define VIRTIO_BLK_T_IN 0
130 #define VIRTIO_BLK_T_OUT 1
132 /* This bit says it's a scsi command, not an actual read or write. */
133 #define VIRTIO_BLK_T_SCSI_CMD 2
135 /* Cache flush command */
136 #define VIRTIO_BLK_T_FLUSH 4
138 /* Barrier before this op. */
139 #define VIRTIO_BLK_T_BARRIER 0x80000000
141 /* This is the first element of the read scatter-gather list. */
142 struct VirtioBlkOuthdr {
143 /* VIRTIO_BLK_T* */
144 uint32_t type;
145 /* io priority. */
146 uint32_t ioprio;
147 /* Sector (ie. 512 byte offset) */
148 uint64_t sector;
150 typedef struct VirtioBlkOuthdr VirtioBlkOuthdr;
152 struct VirtioBlkConfig {
153 uint64_t capacity; /* in 512-byte sectors */
154 uint32_t size_max; /* max segment size (if VIRTIO_BLK_F_SIZE_MAX) */
155 uint32_t seg_max; /* max number of segments (if VIRTIO_BLK_F_SEG_MAX) */
157 struct VirtioBlkGeometry {
158 uint16_t cylinders;
159 uint8_t heads;
160 uint8_t sectors;
161 } geometry; /* (if VIRTIO_BLK_F_GEOMETRY) */
163 uint32_t blk_size; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
165 /* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */
166 uint8_t physical_block_exp; /* exponent for physical blk per logical blk */
167 uint8_t alignment_offset; /* alignment offset in logical blocks */
168 uint16_t min_io_size; /* min I/O size without performance penalty
169 in logical blocks */
170 uint32_t opt_io_size; /* optimal sustained I/O size in logical blks */
172 uint8_t wce; /* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
173 } __attribute__((packed));
174 typedef struct VirtioBlkConfig VirtioBlkConfig;
176 enum guessed_disk_nature_type {
177 VIRTIO_GDN_NONE = 0,
178 VIRTIO_GDN_DASD = 1,
179 VIRTIO_GDN_CDROM = 2,
180 VIRTIO_GDN_SCSI = 3,
182 typedef enum guessed_disk_nature_type VirtioGDN;
184 VirtioGDN virtio_guessed_disk_nature(void);
185 void virtio_assume_scsi(void);
186 void virtio_assume_eckd(void);
187 void virtio_assume_iso9660(void);
189 extern bool virtio_disk_is_scsi(void);
190 extern bool virtio_disk_is_eckd(void);
191 extern bool virtio_ipl_disk_is_valid(void);
192 extern int virtio_get_block_size(void);
193 extern uint8_t virtio_get_heads(void);
194 extern uint8_t virtio_get_sectors(void);
195 extern uint64_t virtio_get_blocks(void);
196 extern int virtio_read_many(ulong sector, void *load_addr, int sec_num);
198 #define VIRTIO_SECTOR_SIZE 512
199 #define VIRTIO_ISO_BLOCK_SIZE 2048
200 #define VIRTIO_SCSI_BLOCK_SIZE 512
202 static inline ulong virtio_sector_adjust(ulong sector)
204 return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE);
207 struct VirtioScsiConfig {
208 uint32_t num_queues;
209 uint32_t seg_max;
210 uint32_t max_sectors;
211 uint32_t cmd_per_lun;
212 uint32_t event_info_size;
213 uint32_t sense_size;
214 uint32_t cdb_size;
215 uint16_t max_channel;
216 uint16_t max_target;
217 uint32_t max_lun;
218 } __attribute__((packed));
219 typedef struct VirtioScsiConfig VirtioScsiConfig;
221 struct ScsiDevice {
222 uint16_t channel; /* Always 0 in QEMU */
223 uint16_t target; /* will be scanned over */
224 uint32_t lun; /* will be reported */
226 typedef struct ScsiDevice ScsiDevice;
228 struct VirtioNetConfig {
229 uint8_t mac[6];
230 /* uint16_t status; */ /* Only with VIRTIO_NET_F_STATUS */
231 /* uint16_t max_virtqueue_pairs; */ /* Only with VIRTIO_NET_F_MQ */
233 typedef struct VirtioNetConfig VirtioNetConfig;
235 struct VDev {
236 int nr_vqs;
237 VRing *vrings;
238 int cmd_vr_idx;
239 void *ring_area;
240 long wait_reply_timeout;
241 VirtioGDN guessed_disk_nature;
242 SubChannelId schid;
243 SenseId senseid;
244 union {
245 VirtioBlkConfig blk;
246 VirtioScsiConfig scsi;
247 VirtioNetConfig net;
248 } config;
249 ScsiDevice *scsi_device;
250 bool is_cdrom;
251 int scsi_block_size;
252 int blk_factor;
253 uint64_t scsi_last_block;
254 uint32_t scsi_dev_cyls;
255 uint8_t scsi_dev_heads;
256 bool scsi_device_selected;
257 ScsiDevice selected_scsi_device;
258 uint64_t netboot_start_addr;
259 uint32_t max_transfer;
260 uint32_t guest_features[2];
262 typedef struct VDev VDev;
264 VDev *virtio_get_device(void);
265 VirtioDevType virtio_get_device_type(void);
267 struct VirtioCmd {
268 void *data;
269 int size;
270 int flags;
272 typedef struct VirtioCmd VirtioCmd;
274 bool vring_notify(VRing *vr);
275 int drain_irqs(SubChannelId schid);
276 void vring_send_buf(VRing *vr, void *p, int len, int flags);
277 int vr_poll(VRing *vr);
278 int vring_wait_reply(void);
279 int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd);
280 void virtio_setup_ccw(VDev *vdev);
282 int virtio_net_init(void *mac_addr);
284 #endif /* VIRTIO_H */