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