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