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::FromBytes; 15 use zerocopy::Immutable; 16 use zerocopy::IntoBytes; 17 use zerocopy::KnownLayout; 18 19 /// Virtio feature bits that are specific to a device type. 20 /// 21 /// Per virtio 1.2 spec, features 0 to 23 and 50 to 127 are feature bits for the specific device 22 /// type. Features beyond 63 are not representable in the current `u64` type used to store sets of 23 /// features, so bits 64 to 127 are not included in this mask. 24 pub const VIRTIO_DEVICE_TYPE_SPECIFIC_FEATURES_MASK: u64 = 0xfffc_0000_00ff_ffff; 25 26 pub 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 105 pub mod fs { 106 /// The maximum allowable length of the tag used to identify a specific virtio-fs device. 107 pub const FS_MAX_TAG_LEN: usize = 36; 108 } 109 110 pub 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 /* The following capabilities are not upstreamed. */ 121 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 136 pub 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 } 159 } 160 161 pub mod media { 162 const QUEUE_SIZE: u16 = 256; 163 pub const QUEUE_SIZES: &[u16] = &[QUEUE_SIZE, QUEUE_SIZE]; 164 } 165 166 pub mod video { 167 use data_model::Le32; 168 use serde::Deserialize; 169 use serde::Serialize; 170 use serde_keyvalue::FromKeyValues; 171 use zerocopy::FromBytes; 172 use zerocopy::Immutable; 173 use zerocopy::IntoBytes; 174 use zerocopy::KnownLayout; 175 176 pub const CMD_QUEUE_INDEX: usize = 0; 177 pub const EVENT_QUEUE_INDEX: usize = 1; 178 pub const NUM_QUEUES: usize = 2; 179 180 pub const VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES: u32 = 0; 181 pub const VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG: u32 = 1; 182 pub const VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT: u32 = 2; 183 184 #[derive(Debug, Clone, Copy)] 185 pub enum VideoDeviceType { 186 Decoder, 187 Encoder, 188 } 189 190 #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] 191 #[serde(rename_all = "kebab-case")] 192 pub enum VideoBackendType { 193 #[cfg(feature = "libvda")] 194 Libvda, 195 #[cfg(feature = "libvda")] 196 LibvdaVd, 197 #[cfg(feature = "ffmpeg")] 198 Ffmpeg, 199 #[cfg(feature = "vaapi")] 200 Vaapi, 201 } 202 203 #[derive(Debug, Serialize, Deserialize, FromKeyValues)] 204 pub struct VideoDeviceConfig { 205 pub backend: VideoBackendType, 206 } 207 208 /// The same set of virtio features is supported by the ffmpeg decoder and encoder. ffmpeg_supported_virtio_features() -> u64209 pub fn ffmpeg_supported_virtio_features() -> u64 { 210 1u64 << VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES 211 | 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG 212 | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT 213 } 214 215 /// The same set of virtio features is supported by the vaapi decoder and encoder. vaapi_supported_virtio_features() -> u64216 pub fn vaapi_supported_virtio_features() -> u64 { 217 1u64 << VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES 218 | 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG 219 | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT 220 } 221 222 /// The same set of virtio features is supported by the vda decoder and encoder. vda_supported_virtio_features() -> u64223 pub fn vda_supported_virtio_features() -> u64 { 224 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT 225 } 226 backend_supported_virtio_features(backend: VideoBackendType) -> u64227 pub fn backend_supported_virtio_features(backend: VideoBackendType) -> u64 { 228 match backend { 229 #[cfg(feature = "libvda")] 230 VideoBackendType::Libvda | VideoBackendType::LibvdaVd => { 231 vda_supported_virtio_features() 232 } 233 #[cfg(feature = "ffmpeg")] 234 VideoBackendType::Ffmpeg => ffmpeg_supported_virtio_features(), 235 #[cfg(feature = "vaapi")] 236 VideoBackendType::Vaapi => vaapi_supported_virtio_features(), 237 } 238 } 239 240 #[repr(C)] 241 #[derive(Debug, Default, Copy, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)] 242 pub struct virtio_video_config { 243 pub version: Le32, 244 pub max_caps_length: Le32, 245 pub max_resp_length: Le32, 246 pub device_name: [u8; 32], 247 } 248 } 249 250 pub mod vsock { 251 pub const NUM_QUEUES: usize = 3; 252 } 253 254 pub mod wl { 255 pub const NUM_QUEUES: usize = 2; 256 257 pub const VIRTIO_WL_F_TRANS_FLAGS: u32 = 0x01; 258 pub const VIRTIO_WL_F_SEND_FENCES: u32 = 0x02; 259 pub const VIRTIO_WL_F_USE_SHMEM: u32 = 0x03; 260 } 261 262 pub mod console { 263 use data_model::Le16; 264 use data_model::Le32; 265 use zerocopy::FromBytes; 266 use zerocopy::Immutable; 267 use zerocopy::IntoBytes; 268 use zerocopy::KnownLayout; 269 270 pub const VIRTIO_CONSOLE_F_SIZE: u32 = 0; 271 pub const VIRTIO_CONSOLE_F_MULTIPORT: u32 = 1; 272 pub const VIRTIO_CONSOLE_F_EMERG_WRITE: u32 = 2; 273 274 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)] 275 #[repr(C)] 276 pub struct virtio_console_config { 277 pub cols: Le16, 278 pub rows: Le16, 279 pub max_nr_ports: Le32, 280 pub emerg_wr: Le32, 281 } 282 283 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)] 284 #[repr(C)] 285 pub struct virtio_console_control { 286 pub id: Le32, 287 pub event: Le16, 288 pub value: Le16, 289 } 290 291 #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)] 292 #[repr(C)] 293 pub struct virtio_console_resize { 294 pub cols: Le16, 295 pub rows: Le16, 296 } 297 298 pub const VIRTIO_CONSOLE_DEVICE_READY: u16 = 0; 299 pub const VIRTIO_CONSOLE_DEVICE_ADD: u16 = 1; 300 pub const VIRTIO_CONSOLE_DEVICE_REMOVE: u16 = 2; 301 pub const VIRTIO_CONSOLE_PORT_READY: u16 = 3; 302 pub const VIRTIO_CONSOLE_CONSOLE_PORT: u16 = 4; 303 pub const VIRTIO_CONSOLE_RESIZE: u16 = 5; 304 pub const VIRTIO_CONSOLE_PORT_OPEN: u16 = 6; 305 pub const VIRTIO_CONSOLE_PORT_NAME: u16 = 7; 306 } 307