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
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
29 VIRTIO_ID_CONSOLE = 3,
30 VIRTIO_ID_BALLOON = 5,
33 typedef enum VirtioDevType VirtioDevType;
35 struct VirtioDevHeader {
42 } __attribute__((packed));
43 typedef struct VirtioDevHeader VirtioDevHeader;
45 struct VirtioVqConfig {
50 } __attribute__((packed));
51 typedef struct VirtioVqConfig VirtioVqConfig;
58 } __attribute__((packed));
59 typedef struct VqInfo VqInfo;
64 } __attribute__((packed));
65 typedef struct VqConfig VqConfig;
68 VirtioDevHeader *header;
69 VirtioVqConfig *vqconfig;
74 typedef struct VirtioDev VirtioDev;
76 #define VIRTIO_RING_SIZE (PAGE_SIZE * 8)
77 #define VIRTIO_MAX_VQS 3
78 #define KVM_S390_VIRTIO_RING_ALIGN 4096
80 #define VRING_USED_F_NO_NOTIFY 1
82 /* This marks a buffer as continuing via the next field. */
83 #define VRING_DESC_F_NEXT 1
84 /* This marks a buffer as write-only (otherwise read-only). */
85 #define VRING_DESC_F_WRITE 2
86 /* This means the buffer contains a list of buffer descriptors. */
87 #define VRING_DESC_F_INDIRECT 4
89 /* Internal flag to mark follow-up segments as such */
90 #define VRING_HIDDEN_IS_CHAIN 256
92 /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */
94 /* Address (guest-physical). */
98 /* The flags as indicated above. */
100 /* We chain unused descriptors via this, too */
102 } __attribute__((packed));
103 typedef struct VRingDesc VRingDesc;
109 } __attribute__((packed));
110 typedef struct VRingAvail VRingAvail;
112 /* uint32_t is used here for ids for padding reasons. */
113 struct VRingUsedElem {
114 /* Index of start of used descriptor chain. */
116 /* Total length of the descriptor chain which was used (written to) */
118 } __attribute__((packed));
119 typedef struct VRingUsedElem VRingUsedElem;
124 VRingUsedElem ring[];
125 } __attribute__((packed));
126 typedef struct VRingUsed VRingUsed;
139 typedef struct VRing VRing;
142 /***********************************************
144 ***********************************************/
149 * Usage is a bit tricky as some bits are used as flags and some are not.
152 * VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or
153 * VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own
154 * and may not be combined with any of the other flags.
157 /* These two define direction. */
158 #define VIRTIO_BLK_T_IN 0
159 #define VIRTIO_BLK_T_OUT 1
161 /* This bit says it's a scsi command, not an actual read or write. */
162 #define VIRTIO_BLK_T_SCSI_CMD 2
164 /* Cache flush command */
165 #define VIRTIO_BLK_T_FLUSH 4
167 /* Barrier before this op. */
168 #define VIRTIO_BLK_T_BARRIER 0x80000000
170 /* This is the first element of the read scatter-gather list. */
171 struct VirtioBlkOuthdr {
176 /* Sector (ie. 512 byte offset) */
179 typedef struct VirtioBlkOuthdr VirtioBlkOuthdr;
181 struct VirtioBlkConfig {
182 uint64_t capacity; /* in 512-byte sectors */
183 uint32_t size_max; /* max segment size (if VIRTIO_BLK_F_SIZE_MAX) */
184 uint32_t seg_max; /* max number of segments (if VIRTIO_BLK_F_SEG_MAX) */
186 struct VirtioBlkGeometry {
190 } geometry; /* (if VIRTIO_BLK_F_GEOMETRY) */
192 uint32_t blk_size; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
194 /* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */
195 uint8_t physical_block_exp; /* exponent for physical blk per logical blk */
196 uint8_t alignment_offset; /* alignment offset in logical blocks */
197 uint16_t min_io_size; /* min I/O size without performance penalty
199 uint32_t opt_io_size; /* optimal sustained I/O size in logical blks */
201 uint8_t wce; /* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
202 } __attribute__((packed));
203 typedef struct VirtioBlkConfig VirtioBlkConfig;
205 enum guessed_disk_nature_type {
208 VIRTIO_GDN_CDROM = 2,
211 typedef enum guessed_disk_nature_type VirtioGDN;
213 VirtioGDN virtio_guessed_disk_nature(void);
214 void virtio_assume_scsi(void);
215 void virtio_assume_eckd(void);
216 void virtio_assume_iso9660(void);
218 extern bool virtio_disk_is_scsi(void);
219 extern bool virtio_disk_is_eckd(void);
220 extern bool virtio_ipl_disk_is_valid(void);
221 extern int virtio_get_block_size(void);
222 extern uint8_t virtio_get_heads(void);
223 extern uint8_t virtio_get_sectors(void);
224 extern uint64_t virtio_get_blocks(void);
225 extern int virtio_read_many(ulong sector, void *load_addr, int sec_num);
227 #define VIRTIO_SECTOR_SIZE 512
228 #define VIRTIO_ISO_BLOCK_SIZE 2048
229 #define VIRTIO_SCSI_BLOCK_SIZE 512
231 static inline ulong virtio_sector_adjust(ulong sector)
233 return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE);
236 struct VirtioScsiConfig {
239 uint32_t max_sectors;
240 uint32_t cmd_per_lun;
241 uint32_t event_info_size;
244 uint16_t max_channel;
247 } __attribute__((packed));
248 typedef struct VirtioScsiConfig VirtioScsiConfig;
251 uint16_t channel; /* Always 0 in QEMU */
252 uint16_t target; /* will be scanned over */
253 uint32_t lun; /* will be reported */
255 typedef struct ScsiDevice ScsiDevice;
262 long wait_reply_timeout;
263 VirtioGDN guessed_disk_nature;
268 VirtioScsiConfig scsi;
270 ScsiDevice *scsi_device;
274 uint64_t scsi_last_block;
275 uint32_t scsi_dev_cyls;
276 uint8_t scsi_dev_heads;
277 bool scsi_device_selected;
278 ScsiDevice selected_scsi_device;
279 uint64_t netboot_start_addr;
280 uint32_t max_transfer;
282 typedef struct VDev VDev;
284 VDev *virtio_get_device(void);
285 VirtioDevType virtio_get_device_type(void);
292 typedef struct VirtioCmd VirtioCmd;
294 int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd);
296 #endif /* VIRTIO_H */