1use guid::Guid;
7use hvlite_pcat_locator::RomFileLocation;
8use input_core::InputData;
9use memory_range::MemoryRange;
10use mesh::MeshPayload;
11use mesh::payload::Protobuf;
12use net_backend_resources::mac_address::MacAddress;
13use std::fmt;
14use std::fs::File;
15use vm_resource::Resource;
16use vm_resource::kind::PciDeviceHandleKind;
17use vm_resource::kind::VirtioDeviceHandle;
18use vm_resource::kind::VmbusDeviceHandleKind;
19use vmgs_resources::VmgsResource;
20use vmotherboard::ChipsetDeviceHandle;
21use vmotherboard::options::BaseChipsetManifest;
22
23#[derive(MeshPayload, Debug)]
24pub struct Config {
25 pub load_mode: LoadMode,
26 pub floppy_disks: Vec<floppy_resources::FloppyDiskConfig>,
27 pub ide_disks: Vec<ide_resources::IdeDeviceConfig>,
28 pub vpci_devices: Vec<VpciDeviceConfig>,
29 pub memory: MemoryConfig,
30 pub processor_topology: ProcessorTopologyConfig,
31 pub hypervisor: HypervisorConfig,
32 pub chipset: BaseChipsetManifest,
33 pub vmbus: Option<VmbusConfig>,
34 pub vtl2_vmbus: Option<VmbusConfig>,
35 #[cfg(windows)]
36 pub kernel_vmnics: Vec<KernelVmNicConfig>,
37 pub input: mesh::Receiver<InputData>,
38 pub framebuffer: Option<framebuffer::Framebuffer>,
39 pub vga_firmware: Option<RomFileLocation>,
40 pub vtl2_gfx: bool,
41 pub virtio_console_pci: bool,
42 pub virtio_serial: Option<SerialPipes>,
43 pub virtio_devices: Vec<(VirtioBus, Resource<VirtioDeviceHandle>)>,
44 #[cfg(windows)]
45 pub vpci_resources: Vec<virt_whp::device::DeviceHandle>,
46 pub vmgs: Option<VmgsResource>,
47 pub secure_boot_enabled: bool,
48 pub custom_uefi_vars: firmware_uefi_custom_vars::CustomVars,
49 pub firmware_event_send: Option<mesh::Sender<get_resources::ged::FirmwareEvent>>,
51 pub debugger_rpc: Option<mesh::Receiver<vmm_core_defs::debug_rpc::DebugRequest>>,
52 pub vmbus_devices: Vec<(DeviceVtl, Resource<VmbusDeviceHandleKind>)>,
53 pub chipset_devices: Vec<ChipsetDeviceHandle>,
54 pub generation_id_recv: Option<mesh::Receiver<[u8; 16]>>,
55 pub rtc_delta_milliseconds: i64,
57}
58
59const DEFAULT_LOW_MMAP_GAP_SIZE_X86: u64 = 1024 * 1024 * 128;
61const DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64: u64 = 1024 * 1024 * 512;
62
63pub const DEFAULT_MMIO_GAPS_X86: [MemoryRange; 2] = [
65 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_X86..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x10_0000_0000), ];
68
69pub const DEFAULT_MMIO_GAPS_X86_WITH_VTL2: [MemoryRange; 3] = [
71 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_X86..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x20_0000_0000), MemoryRange::new(0x20_0000_0000..0x20_4000_0000), ];
75
76pub const DEFAULT_MMIO_GAPS_AARCH64: [MemoryRange; 2] = [
78 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x10_0000_0000), ];
81
82pub const DEFAULT_MMIO_GAPS_AARCH64_WITH_VTL2: [MemoryRange; 3] = [
84 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x20_0000_0000), MemoryRange::new(0x20_0000_0000..0x20_4000_0000), ];
88
89pub const DEFAULT_GIC_DISTRIBUTOR_BASE: u64 = 0xFFFF_0000;
90pub const DEFAULT_GIC_REDISTRIBUTORS_BASE: u64 = if cfg!(target_os = "linux") {
92 0xEFFF_0000
93} else {
94 0xEFFE_E000
95};
96
97#[derive(MeshPayload, Debug)]
98pub enum LoadMode {
99 Linux {
100 kernel: File,
101 initrd: Option<File>,
102 cmdline: String,
103 enable_serial: bool,
104 custom_dsdt: Option<Vec<u8>>,
105 },
106 Uefi {
107 firmware: File,
108 enable_debugging: bool,
109 enable_memory_protections: bool,
110 disable_frontpage: bool,
111 enable_tpm: bool,
112 enable_battery: bool,
113 enable_serial: bool,
114 enable_vpci_boot: bool,
115 uefi_console_mode: Option<UefiConsoleMode>,
116 default_boot_always_attempt: bool,
117 },
118 Pcat {
119 firmware: RomFileLocation,
120 boot_order: [PcatBootDevice; 4],
121 },
122 Igvm {
123 file: File,
124 cmdline: String,
125 vtl2_base_address: Vtl2BaseAddressType,
126 com_serial: Option<SerialInformation>,
127 },
128 None,
129}
130
131#[derive(Debug, Clone, Copy, MeshPayload)]
132pub struct SerialInformation {
133 pub io_port: u16,
134 pub irq: u32,
135}
136
137#[derive(Debug, Clone, Copy, MeshPayload)]
140pub enum Vtl2BaseAddressType {
141 File,
144 Absolute(u64),
147 MemoryLayout { size: Option<u64> },
155 Vtl2Allocate { size: Option<u64> },
163}
164
165#[derive(Debug, MeshPayload)]
166pub struct VpciDeviceConfig {
167 pub vtl: DeviceVtl,
168 pub instance_id: Guid,
169 pub resource: Resource<PciDeviceHandleKind>,
170}
171
172#[derive(Debug, Protobuf)]
173pub struct ProcessorTopologyConfig {
174 pub proc_count: u32,
175 pub vps_per_socket: Option<u32>,
176 pub enable_smt: Option<bool>,
177 pub arch: Option<ArchTopologyConfig>,
178}
179
180#[derive(Debug, Protobuf, Default, Clone)]
181pub struct X86TopologyConfig {
182 pub apic_id_offset: u32,
183 pub x2apic: X2ApicConfig,
184}
185
186#[derive(Debug, Default, Copy, Clone, Protobuf)]
187pub enum X2ApicConfig {
188 #[default]
189 Auto,
192 Supported,
195 Unsupported,
197 Enabled,
199}
200
201#[derive(Debug, Protobuf, Default, Clone)]
202pub struct Aarch64TopologyConfig {
203 pub gic_config: Option<GicConfig>,
204}
205
206#[derive(Debug, Protobuf, Clone)]
207pub struct GicConfig {
208 pub gic_distributor_base: u64,
209 pub gic_redistributors_base: u64,
210}
211
212#[derive(Debug, Protobuf, Clone)]
213pub enum ArchTopologyConfig {
214 X86(X86TopologyConfig),
215 Aarch64(Aarch64TopologyConfig),
216}
217
218#[derive(Debug, MeshPayload)]
219pub struct MemoryConfig {
220 pub mem_size: u64,
221 pub mmio_gaps: Vec<MemoryRange>,
222 pub prefetch_memory: bool,
223}
224
225#[derive(Debug, MeshPayload, Default)]
226pub struct VmbusConfig {
227 pub vsock_listener: Option<unix_socket::UnixListener>,
228 pub vsock_path: Option<String>,
229 pub vmbus_max_version: Option<u32>,
230 #[cfg(windows)]
231 pub vmbusproxy_handle: Option<vmbus_proxy::ProxyHandle>,
232 pub vtl2_redirect: bool,
233}
234
235#[derive(Debug, MeshPayload, Default)]
236pub struct HypervisorConfig {
237 pub with_hv: bool,
238 pub user_mode_hv_enlightenments: bool,
239 pub user_mode_apic: bool,
240 pub with_vtl2: Option<Vtl2Config>,
241 pub with_isolation: Option<IsolationType>,
242}
243
244#[derive(Debug, Copy, Clone, MeshPayload)]
245pub enum Hypervisor {
246 Kvm,
247 MsHv,
248 Whp,
249 Hvf,
250}
251
252impl fmt::Display for Hypervisor {
253 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254 f.pad(match self {
255 Self::Kvm => "kvm",
256 Self::MsHv => "mshv",
257 Self::Whp => "whp",
258 Self::Hvf => "hvf",
259 })
260 }
261}
262
263#[derive(Debug, MeshPayload)]
265pub struct SerialPipes {
266 pub input: Option<File>,
272 pub output: Option<File>,
280}
281
282impl SerialPipes {
283 pub fn try_clone(&self) -> std::io::Result<Self> {
284 Ok(Self {
285 input: self.input.as_ref().map(File::try_clone).transpose()?,
286 output: self.output.as_ref().map(File::try_clone).transpose()?,
287 })
288 }
289}
290
291#[derive(Debug, MeshPayload)]
292pub struct KernelVmNicConfig {
293 pub instance_id: Guid,
294 pub mac_address: MacAddress,
295 pub switch_port_id: SwitchPortId,
296}
297
298#[derive(Clone, Debug, MeshPayload)]
299pub struct SwitchPortId {
300 pub switch: Guid,
301 pub port: Guid,
302}
303
304pub const DEFAULT_PCAT_BOOT_ORDER: [PcatBootDevice; 4] = [
305 PcatBootDevice::Optical,
306 PcatBootDevice::HardDrive,
307 PcatBootDevice::Network,
308 PcatBootDevice::Floppy,
309];
310
311#[derive(MeshPayload, Debug, Clone, Copy, PartialEq)]
312pub enum PcatBootDevice {
313 Floppy,
314 HardDrive,
315 Optical,
316 Network,
317}
318
319#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
320pub enum VirtioBus {
321 Mmio,
322 Pci,
323}
324
325#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
327pub enum LateMapVtl0MemoryPolicy {
328 Halt,
330 Log,
332 InjectException,
334}
335
336impl From<LateMapVtl0MemoryPolicy> for virt::LateMapVtl0MemoryPolicy {
337 fn from(value: LateMapVtl0MemoryPolicy) -> Self {
338 match value {
339 LateMapVtl0MemoryPolicy::Halt => virt::LateMapVtl0MemoryPolicy::Halt,
340 LateMapVtl0MemoryPolicy::Log => virt::LateMapVtl0MemoryPolicy::Log,
341 LateMapVtl0MemoryPolicy::InjectException => {
342 virt::LateMapVtl0MemoryPolicy::InjectException
343 }
344 }
345 }
346}
347
348#[derive(Debug, Clone, MeshPayload)]
354pub struct Vtl2Config {
355 pub vtl0_alias_map: bool,
358 pub late_map_vtl0_memory: Option<LateMapVtl0MemoryPolicy>,
362}
363
364#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
366pub enum IsolationType {
367 Vbs,
368}
369
370impl From<IsolationType> for virt::IsolationType {
371 fn from(value: IsolationType) -> Self {
372 match value {
373 IsolationType::Vbs => Self::Vbs,
374 }
375 }
376}
377
378#[derive(Copy, Clone, Debug, PartialEq, Eq, MeshPayload)]
380pub enum DeviceVtl {
381 Vtl0,
382 Vtl1,
383 Vtl2,
384}
385
386#[derive(Copy, Clone, Debug, MeshPayload)]
387pub enum UefiConsoleMode {
388 Default,
389 Com1,
390 Com2,
391 None,
392}