• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 video {
160     use data_model::Le32;
161     use serde::Deserialize;
162     use serde::Serialize;
163     use serde_keyvalue::FromKeyValues;
164     use zerocopy::AsBytes;
165     use zerocopy::FromBytes;
166     use zerocopy::FromZeroes;
167 
168     pub const CMD_QUEUE_INDEX: usize = 0;
169     pub const EVENT_QUEUE_INDEX: usize = 1;
170     pub const NUM_QUEUES: usize = 2;
171 
172     pub const VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES: u32 = 0;
173     pub const VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG: u32 = 1;
174     pub const VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT: u32 = 2;
175 
176     #[derive(Debug, Clone, Copy)]
177     pub enum VideoDeviceType {
178         Decoder,
179         Encoder,
180     }
181 
182     #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
183     #[serde(rename_all = "kebab-case")]
184     pub enum VideoBackendType {
185         #[cfg(feature = "libvda")]
186         Libvda,
187         #[cfg(feature = "libvda")]
188         LibvdaVd,
189         #[cfg(feature = "ffmpeg")]
190         Ffmpeg,
191         #[cfg(feature = "vaapi")]
192         Vaapi,
193     }
194 
195     #[derive(Debug, Serialize, Deserialize, FromKeyValues)]
196     pub struct VideoDeviceConfig {
197         pub backend: VideoBackendType,
198     }
199 
200     /// The same set of virtio features is supported by the ffmpeg decoder and encoder.
ffmpeg_supported_virtio_features() -> u64201     pub fn ffmpeg_supported_virtio_features() -> u64 {
202         1u64 << VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES
203             | 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG
204             | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT
205     }
206 
207     /// The same set of virtio features is supported by the vaapi decoder and encoder.
vaapi_supported_virtio_features() -> u64208     pub fn vaapi_supported_virtio_features() -> u64 {
209         1u64 << VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES
210             | 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG
211             | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT
212     }
213 
214     /// The same set of virtio features is supported by the vda decoder and encoder.
vda_supported_virtio_features() -> u64215     pub fn vda_supported_virtio_features() -> u64 {
216         1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT
217     }
218 
backend_supported_virtio_features(backend: VideoBackendType) -> u64219     pub fn backend_supported_virtio_features(backend: VideoBackendType) -> u64 {
220         match backend {
221             #[cfg(feature = "libvda")]
222             VideoBackendType::Libvda | VideoBackendType::LibvdaVd => {
223                 vda_supported_virtio_features()
224             }
225             #[cfg(feature = "ffmpeg")]
226             VideoBackendType::Ffmpeg => ffmpeg_supported_virtio_features(),
227             #[cfg(feature = "vaapi")]
228             VideoBackendType::Vaapi => vaapi_supported_virtio_features(),
229         }
230     }
231 
232     #[repr(C)]
233     #[derive(Debug, Default, Copy, Clone, FromZeroes, FromBytes, AsBytes)]
234     pub struct virtio_video_config {
235         pub version: Le32,
236         pub max_caps_length: Le32,
237         pub max_resp_length: Le32,
238         pub device_name: [u8; 32],
239     }
240 }
241 
242 pub mod vsock {
243     pub const NUM_QUEUES: usize = 3;
244 }
245 
246 pub mod wl {
247     pub const NUM_QUEUES: usize = 2;
248 
249     pub const VIRTIO_WL_F_TRANS_FLAGS: u32 = 0x01;
250     pub const VIRTIO_WL_F_SEND_FENCES: u32 = 0x02;
251     pub const VIRTIO_WL_F_USE_SHMEM: u32 = 0x03;
252 }
253 
254 pub mod console {
255     pub const VIRTIO_CONSOLE_F_SIZE: u32 = 0;
256     pub const VIRTIO_CONSOLE_F_MULTIPORT: u32 = 1;
257     pub const VIRTIO_CONSOLE_F_EMERG_WRITE: u32 = 2;
258 }
259