]>
Commit | Line | Data |
---|---|---|
1e17c2c1 AG |
1 | /* |
2 | * Virtio driver bits | |
3 | * | |
4 | * Copyright (c) 2013 Alexander Graf <[email protected]> | |
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 | ||
26 | enum virtio_dev_type { | |
27 | VIRTIO_ID_NET = 1, | |
28 | VIRTIO_ID_BLOCK = 2, | |
29 | VIRTIO_ID_CONSOLE = 3, | |
30 | VIRTIO_ID_BALLOON = 5, | |
31 | }; | |
32 | ||
33 | struct virtio_dev_header { | |
34 | enum virtio_dev_type type : 8; | |
35 | u8 num_vq; | |
36 | u8 feature_len; | |
37 | u8 config_len; | |
38 | u8 status; | |
39 | u8 vqconfig[]; | |
40 | } __attribute__((packed)); | |
41 | ||
42 | struct virtio_vqconfig { | |
43 | u64 token; | |
44 | u64 address; | |
45 | u16 num; | |
46 | u8 pad[6]; | |
47 | } __attribute__((packed)); | |
48 | ||
49 | struct vq_info_block { | |
50 | u64 queue; | |
51 | u32 align; | |
52 | u16 index; | |
53 | u16 num; | |
54 | } __attribute__((packed)); | |
55 | ||
abbbe3de CH |
56 | struct vq_config_block { |
57 | u16 index; | |
58 | u16 num; | |
59 | } __attribute__((packed)); | |
60 | ||
1e17c2c1 AG |
61 | struct virtio_dev { |
62 | struct virtio_dev_header *header; | |
63 | struct virtio_vqconfig *vqconfig; | |
64 | char *host_features; | |
65 | char *guest_features; | |
66 | char *config; | |
67 | }; | |
68 | ||
abd696e4 | 69 | #define KVM_S390_VIRTIO_RING_ALIGN 4096 |
1e17c2c1 AG |
70 | |
71 | #define VRING_USED_F_NO_NOTIFY 1 | |
72 | ||
73 | /* This marks a buffer as continuing via the next field. */ | |
74 | #define VRING_DESC_F_NEXT 1 | |
75 | /* This marks a buffer as write-only (otherwise read-only). */ | |
76 | #define VRING_DESC_F_WRITE 2 | |
77 | /* This means the buffer contains a list of buffer descriptors. */ | |
78 | #define VRING_DESC_F_INDIRECT 4 | |
79 | ||
80 | /* Internal flag to mark follow-up segments as such */ | |
81 | #define VRING_HIDDEN_IS_CHAIN 256 | |
82 | ||
83 | /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ | |
84 | struct vring_desc { | |
85 | /* Address (guest-physical). */ | |
86 | u64 addr; | |
87 | /* Length. */ | |
88 | u32 len; | |
89 | /* The flags as indicated above. */ | |
90 | u16 flags; | |
91 | /* We chain unused descriptors via this, too */ | |
92 | u16 next; | |
93 | } __attribute__((packed)); | |
94 | ||
95 | struct vring_avail { | |
96 | u16 flags; | |
97 | u16 idx; | |
98 | u16 ring[]; | |
99 | } __attribute__((packed)); | |
100 | ||
101 | /* u32 is used here for ids for padding reasons. */ | |
102 | struct vring_used_elem { | |
103 | /* Index of start of used descriptor chain. */ | |
104 | u32 id; | |
105 | /* Total length of the descriptor chain which was used (written to) */ | |
106 | u32 len; | |
107 | } __attribute__((packed)); | |
108 | ||
109 | struct vring_used { | |
110 | u16 flags; | |
111 | u16 idx; | |
112 | struct vring_used_elem ring[]; | |
113 | } __attribute__((packed)); | |
114 | ||
115 | struct vring { | |
116 | unsigned int num; | |
117 | int next_idx; | |
441ea695 | 118 | int used_idx; |
1e17c2c1 AG |
119 | struct vring_desc *desc; |
120 | struct vring_avail *avail; | |
121 | struct vring_used *used; | |
122 | struct subchannel_id schid; | |
123 | }; | |
124 | ||
125 | ||
126 | /*********************************************** | |
127 | * Virtio block * | |
128 | ***********************************************/ | |
129 | ||
130 | /* | |
131 | * Command types | |
132 | * | |
133 | * Usage is a bit tricky as some bits are used as flags and some are not. | |
134 | * | |
135 | * Rules: | |
136 | * VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or | |
137 | * VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own | |
138 | * and may not be combined with any of the other flags. | |
139 | */ | |
140 | ||
141 | /* These two define direction. */ | |
142 | #define VIRTIO_BLK_T_IN 0 | |
143 | #define VIRTIO_BLK_T_OUT 1 | |
144 | ||
145 | /* This bit says it's a scsi command, not an actual read or write. */ | |
146 | #define VIRTIO_BLK_T_SCSI_CMD 2 | |
147 | ||
148 | /* Cache flush command */ | |
149 | #define VIRTIO_BLK_T_FLUSH 4 | |
150 | ||
151 | /* Barrier before this op. */ | |
152 | #define VIRTIO_BLK_T_BARRIER 0x80000000 | |
153 | ||
154 | /* This is the first element of the read scatter-gather list. */ | |
155 | struct virtio_blk_outhdr { | |
156 | /* VIRTIO_BLK_T* */ | |
157 | u32 type; | |
158 | /* io priority. */ | |
159 | u32 ioprio; | |
160 | /* Sector (ie. 512 byte offset) */ | |
161 | u64 sector; | |
162 | }; | |
163 | ||
91a03f9b ED |
164 | typedef struct VirtioBlkConfig { |
165 | u64 capacity; /* in 512-byte sectors */ | |
166 | u32 size_max; /* max segment size (if VIRTIO_BLK_F_SIZE_MAX) */ | |
167 | u32 seg_max; /* max number of segments (if VIRTIO_BLK_F_SEG_MAX) */ | |
168 | ||
169 | struct virtio_blk_geometry { | |
170 | u16 cylinders; | |
171 | u8 heads; | |
172 | u8 sectors; | |
173 | } geometry; /* (if VIRTIO_BLK_F_GEOMETRY) */ | |
174 | ||
175 | u32 blk_size; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ | |
176 | ||
177 | /* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */ | |
178 | u8 physical_block_exp; /* exponent for physical block per logical block */ | |
179 | u8 alignment_offset; /* alignment offset in logical blocks */ | |
180 | u16 min_io_size; /* min I/O size without performance penalty | |
181 | in logical blocks */ | |
182 | u32 opt_io_size; /* optimal sustained I/O size in logical blocks */ | |
183 | ||
184 | u8 wce; /* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */ | |
185 | } __attribute__((packed)) VirtioBlkConfig; | |
186 | ||
187 | bool virtio_guessed_disk_nature(void); | |
188 | void virtio_assume_scsi(void); | |
189 | void virtio_assume_eckd(void); | |
190 | ||
191 | extern bool virtio_disk_is_scsi(void); | |
192 | extern bool virtio_disk_is_eckd(void); | |
193 | extern bool virtio_ipl_disk_is_valid(void); | |
194 | extern int virtio_get_block_size(void); | |
91a03f9b ED |
195 | extern uint8_t virtio_get_heads(void); |
196 | extern uint8_t virtio_get_sectors(void); | |
f04db28b | 197 | extern uint64_t virtio_get_blocks(void); |
91a03f9b ED |
198 | extern int virtio_read_many(ulong sector, void *load_addr, int sec_num); |
199 | ||
200 | #define VIRTIO_SECTOR_SIZE 512 | |
201 | ||
202 | static inline ulong virtio_eckd_sector_adjust(ulong sector) | |
203 | { | |
204 | return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE); | |
205 | } | |
206 | ||
207 | static inline ulong virtio_sector_adjust(ulong sector) | |
208 | { | |
209 | return virtio_disk_is_eckd() ? virtio_eckd_sector_adjust(sector) : sector; | |
210 | } | |
211 | ||
1e17c2c1 | 212 | #endif /* VIRTIO_H */ |