1use data_model::Le16;
10use data_model::Le32;
11use data_model::Le64;
12use serde::Deserialize;
13use serde::Serialize;
14use zerocopy::FromBytes;
15use zerocopy::Immutable;
16use zerocopy::IntoBytes;
17use zerocopy::KnownLayout;
18
19pub const VIRTIO_DEVICE_TYPE_SPECIFIC_FEATURES_MASK: u64 = 0xfffc_0000_00ff_ffff;
25
26pub mod block {
27 use super::*;
28
29 pub const VIRTIO_BLK_T_IN: u32 = 0;
30 pub const VIRTIO_BLK_T_OUT: u32 = 1;
31 pub const VIRTIO_BLK_T_FLUSH: u32 = 4;
32 pub const VIRTIO_BLK_T_GET_ID: u32 = 8;
33 pub const VIRTIO_BLK_T_DISCARD: u32 = 11;
34 pub const VIRTIO_BLK_T_WRITE_ZEROES: u32 = 13;
35
36 pub const VIRTIO_BLK_S_OK: u8 = 0;
37 pub const VIRTIO_BLK_S_IOERR: u8 = 1;
38 pub const VIRTIO_BLK_S_UNSUPP: u8 = 2;
39
40 pub const VIRTIO_BLK_F_SEG_MAX: u32 = 2;
41 pub const VIRTIO_BLK_F_RO: u32 = 5;
42 pub const VIRTIO_BLK_F_BLK_SIZE: u32 = 6;
43 pub const VIRTIO_BLK_F_FLUSH: u32 = 9;
44 pub const VIRTIO_BLK_F_MQ: u32 = 12;
45 pub const VIRTIO_BLK_F_DISCARD: u32 = 13;
46 pub const VIRTIO_BLK_F_WRITE_ZEROES: u32 = 14;
47
48 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
49 #[repr(C)]
50 pub struct virtio_blk_geometry {
51 cylinders: Le16,
52 heads: u8,
53 sectors: u8,
54 }
55
56 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
57 #[repr(C)]
58 pub struct virtio_blk_topology {
59 physical_block_exp: u8,
60 alignment_offset: u8,
61 min_io_size: Le16,
62 opt_io_size: Le32,
63 }
64
65 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
66 #[repr(C, packed)]
67 pub struct virtio_blk_config {
68 pub capacity: Le64,
69 pub size_max: Le32,
70 pub seg_max: Le32,
71 pub geometry: virtio_blk_geometry,
72 pub blk_size: Le32,
73 pub topology: virtio_blk_topology,
74 pub writeback: u8,
75 pub unused0: u8,
76 pub num_queues: Le16,
77 pub max_discard_sectors: Le32,
78 pub max_discard_seg: Le32,
79 pub discard_sector_alignment: Le32,
80 pub max_write_zeroes_sectors: Le32,
81 pub max_write_zeroes_seg: Le32,
82 pub write_zeroes_may_unmap: u8,
83 pub unused1: [u8; 3],
84 }
85
86 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
87 #[repr(C)]
88 pub(crate) struct virtio_blk_req_header {
89 pub req_type: Le32,
90 pub reserved: Le32,
91 pub sector: Le64,
92 }
93
94 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
95 #[repr(C)]
96 pub(crate) struct virtio_blk_discard_write_zeroes {
97 pub sector: Le64,
98 pub num_sectors: Le32,
99 pub flags: Le32,
100 }
101
102 pub(crate) const VIRTIO_BLK_DISCARD_WRITE_ZEROES_FLAG_UNMAP: u32 = 1 << 0;
103}
104
105pub mod fs {
106 pub const FS_MAX_TAG_LEN: usize = 36;
108}
109
110pub mod gpu {
111 use super::*;
112
113 pub const NUM_QUEUES: usize = 2;
114
115 pub const VIRTIO_GPU_F_VIRGL: u32 = 0;
116 pub const VIRTIO_GPU_F_EDID: u32 = 1;
117 pub const VIRTIO_GPU_F_RESOURCE_UUID: u32 = 2;
118 pub const VIRTIO_GPU_F_RESOURCE_BLOB: u32 = 3;
119 pub const VIRTIO_GPU_F_CONTEXT_INIT: u32 = 4;
120 pub const VIRTIO_GPU_F_FENCE_PASSING: u32 = 5;
122 pub const VIRTIO_GPU_F_CREATE_GUEST_HANDLE: u32 = 6;
123
124 pub const VIRTIO_GPU_SHM_ID_HOST_VISIBLE: u8 = 0x0001;
125
126 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
127 #[repr(C)]
128 pub struct virtio_gpu_config {
129 pub events_read: Le32,
130 pub events_clear: Le32,
131 pub num_scanouts: Le32,
132 pub num_capsets: Le32,
133 }
134}
135
136pub mod snd {
137 use super::*;
138
139 #[derive(
140 Copy,
141 Clone,
142 Default,
143 FromBytes,
144 Immutable,
145 IntoBytes,
146 KnownLayout,
147 Serialize,
148 Deserialize,
149 PartialEq,
150 Eq,
151 Debug,
152 )]
153 #[repr(C, packed)]
154 pub struct virtio_snd_config {
155 pub jacks: Le32,
156 pub streams: Le32,
157 pub chmaps: Le32,
158 pub controls: Le32,
159 }
160}
161
162pub mod media {
163 const QUEUE_SIZE: u16 = 256;
164 pub const QUEUE_SIZES: &[u16] = &[QUEUE_SIZE, QUEUE_SIZE];
165}
166
167pub mod video {
168 use data_model::Le32;
169 use serde::Deserialize;
170 use serde::Serialize;
171 use serde_keyvalue::FromKeyValues;
172 use zerocopy::FromBytes;
173 use zerocopy::Immutable;
174 use zerocopy::IntoBytes;
175 use zerocopy::KnownLayout;
176
177 pub const CMD_QUEUE_INDEX: usize = 0;
178 pub const EVENT_QUEUE_INDEX: usize = 1;
179 pub const NUM_QUEUES: usize = 2;
180
181 pub const VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES: u32 = 0;
182 pub const VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG: u32 = 1;
183 pub const VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT: u32 = 2;
184
185 #[derive(Debug, Clone, Copy)]
186 pub enum VideoDeviceType {
187 Decoder,
188 Encoder,
189 }
190
191 #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
192 #[serde(rename_all = "kebab-case")]
193 pub enum VideoBackendType {
194 #[cfg(feature = "libvda")]
195 Libvda,
196 #[cfg(feature = "libvda")]
197 LibvdaVd,
198 #[cfg(feature = "ffmpeg")]
199 Ffmpeg,
200 #[cfg(feature = "vaapi")]
201 Vaapi,
202 }
203
204 #[derive(Debug, Serialize, Deserialize, FromKeyValues)]
205 pub struct VideoDeviceConfig {
206 pub backend: VideoBackendType,
207 }
208
209 pub fn ffmpeg_supported_virtio_features() -> u64 {
211 1u64 << VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES
212 | 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG
213 | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT
214 }
215
216 pub fn vaapi_supported_virtio_features() -> u64 {
218 1u64 << VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES
219 | 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG
220 | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT
221 }
222
223 pub fn vda_supported_virtio_features() -> u64 {
225 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT
226 }
227
228 pub fn backend_supported_virtio_features(backend: VideoBackendType) -> u64 {
229 match backend {
230 #[cfg(feature = "libvda")]
231 VideoBackendType::Libvda | VideoBackendType::LibvdaVd => {
232 vda_supported_virtio_features()
233 }
234 #[cfg(feature = "ffmpeg")]
235 VideoBackendType::Ffmpeg => ffmpeg_supported_virtio_features(),
236 #[cfg(feature = "vaapi")]
237 VideoBackendType::Vaapi => vaapi_supported_virtio_features(),
238 }
239 }
240
241 #[repr(C)]
242 #[derive(Debug, Default, Copy, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
243 pub struct virtio_video_config {
244 pub version: Le32,
245 pub max_caps_length: Le32,
246 pub max_resp_length: Le32,
247 pub device_name: [u8; 32],
248 }
249}
250
251pub mod vsock {
252 pub const NUM_QUEUES: usize = 3;
253}
254
255pub mod wl {
256 pub const NUM_QUEUES: usize = 2;
257
258 pub const VIRTIO_WL_F_TRANS_FLAGS: u32 = 0x01;
259 pub const VIRTIO_WL_F_SEND_FENCES: u32 = 0x02;
260 pub const VIRTIO_WL_F_USE_SHMEM: u32 = 0x03;
261}
262
263pub mod console {
264 use data_model::Le16;
265 use data_model::Le32;
266 use zerocopy::FromBytes;
267 use zerocopy::Immutable;
268 use zerocopy::IntoBytes;
269 use zerocopy::KnownLayout;
270
271 pub const VIRTIO_CONSOLE_F_SIZE: u32 = 0;
272 pub const VIRTIO_CONSOLE_F_MULTIPORT: u32 = 1;
273 pub const VIRTIO_CONSOLE_F_EMERG_WRITE: u32 = 2;
274
275 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
276 #[repr(C)]
277 pub struct virtio_console_config {
278 pub cols: Le16,
279 pub rows: Le16,
280 pub max_nr_ports: Le32,
281 pub emerg_wr: Le32,
282 }
283
284 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
285 #[repr(C)]
286 pub struct virtio_console_control {
287 pub id: Le32,
288 pub event: Le16,
289 pub value: Le16,
290 }
291
292 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
293 #[repr(C)]
294 pub struct virtio_console_resize {
295 pub cols: Le16,
296 pub rows: Le16,
297 }
298
299 pub const VIRTIO_CONSOLE_DEVICE_READY: u16 = 0;
300 pub const VIRTIO_CONSOLE_DEVICE_ADD: u16 = 1;
301 pub const VIRTIO_CONSOLE_DEVICE_REMOVE: u16 = 2;
302 pub const VIRTIO_CONSOLE_PORT_READY: u16 = 3;
303 pub const VIRTIO_CONSOLE_CONSOLE_PORT: u16 = 4;
304 pub const VIRTIO_CONSOLE_RESIZE: u16 = 5;
305 pub const VIRTIO_CONSOLE_PORT_OPEN: u16 = 6;
306 pub const VIRTIO_CONSOLE_PORT_NAME: u16 = 7;
307}