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 pcie_root_complexes: Vec<PcieRootComplexConfig>,
29 pub vpci_devices: Vec<VpciDeviceConfig>,
30 pub memory: MemoryConfig,
31 pub processor_topology: ProcessorTopologyConfig,
32 pub hypervisor: HypervisorConfig,
33 pub chipset: BaseChipsetManifest,
34 pub vmbus: Option<VmbusConfig>,
35 pub vtl2_vmbus: Option<VmbusConfig>,
36 #[cfg(windows)]
37 pub kernel_vmnics: Vec<KernelVmNicConfig>,
38 pub input: mesh::Receiver<InputData>,
39 pub framebuffer: Option<framebuffer::Framebuffer>,
40 pub vga_firmware: Option<RomFileLocation>,
41 pub vtl2_gfx: bool,
42 pub virtio_console_pci: bool,
43 pub virtio_serial: Option<SerialPipes>,
44 pub virtio_devices: Vec<(VirtioBus, Resource<VirtioDeviceHandle>)>,
45 #[cfg(windows)]
46 pub vpci_resources: Vec<virt_whp::device::DeviceHandle>,
47 pub vmgs: Option<VmgsResource>,
48 pub secure_boot_enabled: bool,
49 pub custom_uefi_vars: firmware_uefi_custom_vars::CustomVars,
50 pub firmware_event_send: Option<mesh::Sender<get_resources::ged::FirmwareEvent>>,
52 pub debugger_rpc: Option<mesh::Receiver<vmm_core_defs::debug_rpc::DebugRequest>>,
53 pub vmbus_devices: Vec<(DeviceVtl, Resource<VmbusDeviceHandleKind>)>,
54 pub chipset_devices: Vec<ChipsetDeviceHandle>,
55 pub generation_id_recv: Option<mesh::Receiver<[u8; 16]>>,
56 pub rtc_delta_milliseconds: i64,
58 pub automatic_guest_reset: bool,
60}
61
62const DEFAULT_LOW_MMAP_GAP_SIZE_X86: u64 = 1024 * 1024 * 128;
64const DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64: u64 = 1024 * 1024 * 512;
65
66pub const DEFAULT_MMIO_GAPS_X86: [MemoryRange; 2] = [
68 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_X86..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x10_0000_0000), ];
71
72pub const DEFAULT_MMIO_GAPS_X86_WITH_VTL2: [MemoryRange; 3] = [
74 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), ];
78
79pub const DEFAULT_MMIO_GAPS_AARCH64: [MemoryRange; 2] = [
81 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x10_0000_0000), ];
84
85pub const DEFAULT_MMIO_GAPS_AARCH64_WITH_VTL2: [MemoryRange; 3] = [
87 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), ];
91
92pub const DEFAULT_GIC_DISTRIBUTOR_BASE: u64 = 0xFFFF_0000;
93pub const DEFAULT_GIC_REDISTRIBUTORS_BASE: u64 = if cfg!(target_os = "linux") {
95 0xEFFF_0000
96} else {
97 0xEFFE_E000
98};
99
100pub const DEFAULT_PCIE_ECAM_BASE: u64 = 0x8_0000_0000; #[derive(MeshPayload, Debug)]
103pub enum LoadMode {
104 Linux {
105 kernel: File,
106 initrd: Option<File>,
107 cmdline: String,
108 enable_serial: bool,
109 custom_dsdt: Option<Vec<u8>>,
110 },
111 Uefi {
112 firmware: File,
113 enable_debugging: bool,
114 enable_memory_protections: bool,
115 disable_frontpage: bool,
116 enable_tpm: bool,
117 enable_battery: bool,
118 enable_serial: bool,
119 enable_vpci_boot: bool,
120 uefi_console_mode: Option<UefiConsoleMode>,
121 default_boot_always_attempt: bool,
122 },
123 Pcat {
124 firmware: RomFileLocation,
125 boot_order: [PcatBootDevice; 4],
126 },
127 Igvm {
128 file: File,
129 cmdline: String,
130 vtl2_base_address: Vtl2BaseAddressType,
131 com_serial: Option<SerialInformation>,
132 },
133 None,
134}
135
136#[derive(Debug, Clone, Copy, MeshPayload)]
137pub struct SerialInformation {
138 pub io_port: u16,
139 pub irq: u32,
140}
141
142#[derive(Debug, Clone, Copy, MeshPayload)]
145pub enum Vtl2BaseAddressType {
146 File,
149 Absolute(u64),
152 MemoryLayout { size: Option<u64> },
160 Vtl2Allocate { size: Option<u64> },
168}
169
170#[derive(Debug, MeshPayload)]
171pub struct PcieRootComplexConfig {
172 pub index: u32,
173 pub name: String,
174 pub segment: u16,
175 pub start_bus: u8,
176 pub end_bus: u8,
177 pub low_mmio_size: u32,
178 pub high_mmio_size: u64,
179 pub ports: Vec<PcieRootPortConfig>,
180}
181
182#[derive(Debug, MeshPayload)]
183pub struct PcieRootPortConfig {
184 pub name: String,
185}
186
187#[derive(Debug, MeshPayload)]
188pub struct VpciDeviceConfig {
189 pub vtl: DeviceVtl,
190 pub instance_id: Guid,
193 pub resource: Resource<PciDeviceHandleKind>,
194}
195
196#[derive(Debug, Protobuf)]
197pub struct ProcessorTopologyConfig {
198 pub proc_count: u32,
199 pub vps_per_socket: Option<u32>,
200 pub enable_smt: Option<bool>,
201 pub arch: Option<ArchTopologyConfig>,
202}
203
204#[derive(Debug, Protobuf, Default, Clone)]
205pub struct X86TopologyConfig {
206 pub apic_id_offset: u32,
207 pub x2apic: X2ApicConfig,
208}
209
210#[derive(Debug, Default, Copy, Clone, Protobuf)]
211pub enum X2ApicConfig {
212 #[default]
213 Auto,
216 Supported,
219 Unsupported,
221 Enabled,
223}
224
225#[derive(Debug, Protobuf, Default, Clone)]
226pub enum PmuGsivConfig {
227 #[default]
228 Platform,
230 Gsiv(u32),
232}
233
234#[derive(Debug, Protobuf, Default, Clone)]
235pub struct Aarch64TopologyConfig {
236 pub gic_config: Option<GicConfig>,
237 pub pmu_gsiv: PmuGsivConfig,
238}
239
240#[derive(Debug, Protobuf, Clone)]
241pub struct GicConfig {
242 pub gic_distributor_base: u64,
243 pub gic_redistributors_base: u64,
244}
245
246#[derive(Debug, Protobuf, Clone)]
247pub enum ArchTopologyConfig {
248 X86(X86TopologyConfig),
249 Aarch64(Aarch64TopologyConfig),
250}
251
252#[derive(Debug, MeshPayload)]
253pub struct MemoryConfig {
254 pub mem_size: u64,
255 pub mmio_gaps: Vec<MemoryRange>,
256 pub prefetch_memory: bool,
257 pub pcie_ecam_base: u64,
258}
259
260#[derive(Debug, MeshPayload, Default)]
261pub struct VmbusConfig {
262 pub vsock_listener: Option<unix_socket::UnixListener>,
263 pub vsock_path: Option<String>,
264 pub vmbus_max_version: Option<u32>,
265 #[cfg(windows)]
266 pub vmbusproxy_handle: Option<vmbus_proxy::ProxyHandle>,
267 pub vtl2_redirect: bool,
268}
269
270#[derive(Debug, MeshPayload, Default)]
271pub struct HypervisorConfig {
272 pub with_hv: bool,
273 pub user_mode_hv_enlightenments: bool,
274 pub user_mode_apic: bool,
275 pub with_vtl2: Option<Vtl2Config>,
276 pub with_isolation: Option<IsolationType>,
277}
278
279#[derive(Debug, Copy, Clone, MeshPayload)]
280pub enum Hypervisor {
281 Kvm,
282 MsHv,
283 Whp,
284 Hvf,
285}
286
287impl fmt::Display for Hypervisor {
288 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
289 f.pad(match self {
290 Self::Kvm => "kvm",
291 Self::MsHv => "mshv",
292 Self::Whp => "whp",
293 Self::Hvf => "hvf",
294 })
295 }
296}
297
298#[derive(Debug, MeshPayload)]
300pub struct SerialPipes {
301 pub input: Option<File>,
307 pub output: Option<File>,
315}
316
317impl SerialPipes {
318 pub fn try_clone(&self) -> std::io::Result<Self> {
319 Ok(Self {
320 input: self.input.as_ref().map(File::try_clone).transpose()?,
321 output: self.output.as_ref().map(File::try_clone).transpose()?,
322 })
323 }
324}
325
326#[derive(Debug, MeshPayload)]
327pub struct KernelVmNicConfig {
328 pub instance_id: Guid,
329 pub mac_address: MacAddress,
330 pub switch_port_id: SwitchPortId,
331}
332
333#[derive(Clone, Debug, MeshPayload)]
334pub struct SwitchPortId {
335 pub switch: Guid,
336 pub port: Guid,
337}
338
339pub const DEFAULT_PCAT_BOOT_ORDER: [PcatBootDevice; 4] = [
340 PcatBootDevice::Optical,
341 PcatBootDevice::HardDrive,
342 PcatBootDevice::Network,
343 PcatBootDevice::Floppy,
344];
345
346#[derive(MeshPayload, Debug, Clone, Copy, PartialEq)]
347pub enum PcatBootDevice {
348 Floppy,
349 HardDrive,
350 Optical,
351 Network,
352}
353
354#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
355pub enum VirtioBus {
356 Mmio,
357 Pci,
358}
359
360#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
362pub enum LateMapVtl0MemoryPolicy {
363 Halt,
365 Log,
367 InjectException,
369}
370
371impl From<LateMapVtl0MemoryPolicy> for virt::LateMapVtl0MemoryPolicy {
372 fn from(value: LateMapVtl0MemoryPolicy) -> Self {
373 match value {
374 LateMapVtl0MemoryPolicy::Halt => virt::LateMapVtl0MemoryPolicy::Halt,
375 LateMapVtl0MemoryPolicy::Log => virt::LateMapVtl0MemoryPolicy::Log,
376 LateMapVtl0MemoryPolicy::InjectException => {
377 virt::LateMapVtl0MemoryPolicy::InjectException
378 }
379 }
380 }
381}
382
383#[derive(Debug, Clone, MeshPayload)]
389pub struct Vtl2Config {
390 pub vtl0_alias_map: bool,
393 pub late_map_vtl0_memory: Option<LateMapVtl0MemoryPolicy>,
397}
398
399#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
401pub enum IsolationType {
402 Vbs,
403}
404
405impl From<IsolationType> for virt::IsolationType {
406 fn from(value: IsolationType) -> Self {
407 match value {
408 IsolationType::Vbs => Self::Vbs,
409 }
410 }
411}
412
413#[derive(Copy, Clone, Debug, PartialEq, Eq, MeshPayload)]
415pub enum DeviceVtl {
416 Vtl0,
417 Vtl1,
418 Vtl2,
419}
420
421#[derive(Copy, Clone, Debug, MeshPayload)]
422pub enum UefiConsoleMode {
423 Default,
424 Com1,
425 Com2,
426 None,
427}