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