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 pcie_devices: Vec<PcieDeviceConfig>,
30 pub pcie_switches: Vec<PcieSwitchConfig>,
31 pub vpci_devices: Vec<VpciDeviceConfig>,
32 pub memory: MemoryConfig,
33 pub processor_topology: ProcessorTopologyConfig,
34 pub hypervisor: HypervisorConfig,
35 pub chipset: BaseChipsetManifest,
36 pub vmbus: Option<VmbusConfig>,
37 pub vtl2_vmbus: Option<VmbusConfig>,
38 #[cfg(windows)]
39 pub kernel_vmnics: Vec<KernelVmNicConfig>,
40 pub input: mesh::Receiver<InputData>,
41 pub framebuffer: Option<framebuffer::Framebuffer>,
42 pub vga_firmware: Option<RomFileLocation>,
43 pub vtl2_gfx: bool,
44 pub virtio_console_pci: bool,
45 pub virtio_serial: Option<SerialPipes>,
46 pub virtio_devices: Vec<(VirtioBus, Resource<VirtioDeviceHandle>)>,
47 #[cfg(windows)]
48 pub vpci_resources: Vec<virt_whp::device::DeviceHandle>,
49 pub vmgs: Option<VmgsResource>,
50 pub secure_boot_enabled: bool,
51 pub custom_uefi_vars: firmware_uefi_custom_vars::CustomVars,
52 pub firmware_event_send: Option<mesh::Sender<get_resources::ged::FirmwareEvent>>,
54 pub debugger_rpc: Option<mesh::Receiver<vmm_core_defs::debug_rpc::DebugRequest>>,
55 pub vmbus_devices: Vec<(DeviceVtl, Resource<VmbusDeviceHandleKind>)>,
56 pub chipset_devices: Vec<ChipsetDeviceHandle>,
57 pub generation_id_recv: Option<mesh::Receiver<[u8; 16]>>,
58 pub rtc_delta_milliseconds: i64,
60 pub automatic_guest_reset: bool,
62 pub efi_diagnostics_log_level: EfiDiagnosticsLogLevelType,
63}
64
65const DEFAULT_LOW_MMAP_GAP_SIZE_X86: u64 = 1024 * 1024 * 128;
67const DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64: u64 = 1024 * 1024 * 512;
68
69pub const DEFAULT_MMIO_GAPS_X86: [MemoryRange; 2] = [
71 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_X86..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x10_0000_0000), ];
74
75pub const DEFAULT_MMIO_GAPS_X86_WITH_VTL2: [MemoryRange; 3] = [
77 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), ];
81
82pub const DEFAULT_MMIO_GAPS_AARCH64: [MemoryRange; 2] = [
84 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x10_0000_0000), ];
87
88pub const DEFAULT_MMIO_GAPS_AARCH64_WITH_VTL2: [MemoryRange; 3] = [
90 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), ];
94
95pub const DEFAULT_GIC_DISTRIBUTOR_BASE: u64 = 0xFFFF_0000;
96pub const DEFAULT_GIC_REDISTRIBUTORS_BASE: u64 = if cfg!(target_os = "linux") {
98 0xEFFF_0000
99} else {
100 0xEFFE_E000
101};
102
103pub const DEFAULT_PCIE_ECAM_BASE: u64 = 0x8_0000_0000; #[derive(MeshPayload, Debug)]
106pub enum LoadMode {
107 Linux {
108 kernel: File,
109 initrd: Option<File>,
110 cmdline: String,
111 enable_serial: bool,
112 custom_dsdt: Option<Vec<u8>>,
113 },
114 Uefi {
115 firmware: File,
116 enable_debugging: bool,
117 enable_memory_protections: bool,
118 disable_frontpage: bool,
119 enable_tpm: bool,
120 enable_battery: bool,
121 enable_serial: bool,
122 enable_vpci_boot: bool,
123 uefi_console_mode: Option<UefiConsoleMode>,
124 default_boot_always_attempt: bool,
125 bios_guid: Guid,
126 },
127 Pcat {
128 firmware: RomFileLocation,
129 boot_order: [PcatBootDevice; 4],
130 },
131 Igvm {
132 file: File,
133 cmdline: String,
134 vtl2_base_address: Vtl2BaseAddressType,
135 com_serial: Option<SerialInformation>,
136 },
137 None,
138}
139
140#[derive(Debug, Clone, Copy, MeshPayload)]
141pub struct SerialInformation {
142 pub io_port: u16,
143 pub irq: u32,
144}
145
146#[derive(Debug, Clone, Copy, MeshPayload)]
149pub enum Vtl2BaseAddressType {
150 File,
153 Absolute(u64),
156 MemoryLayout { size: Option<u64> },
164 Vtl2Allocate { size: Option<u64> },
172}
173
174#[derive(Debug, MeshPayload)]
175pub struct PcieRootComplexConfig {
176 pub index: u32,
177 pub name: String,
178 pub segment: u16,
179 pub start_bus: u8,
180 pub end_bus: u8,
181 pub low_mmio_size: u32,
182 pub high_mmio_size: u64,
183 pub ports: Vec<PcieRootPortConfig>,
184}
185
186#[derive(Debug, MeshPayload)]
187pub struct PcieRootPortConfig {
188 pub name: String,
189}
190
191#[derive(Debug, MeshPayload)]
192pub struct PcieSwitchConfig {
193 pub name: String,
194 pub num_downstream_ports: u8,
195 pub parent_port: String,
196}
197
198#[derive(Debug, MeshPayload)]
199pub struct PcieDeviceConfig {
200 pub port_name: String,
201 pub resource: Resource<PciDeviceHandleKind>,
202}
203
204#[derive(Debug, MeshPayload)]
205pub struct VpciDeviceConfig {
206 pub vtl: DeviceVtl,
207 pub instance_id: Guid,
210 pub resource: Resource<PciDeviceHandleKind>,
211}
212
213#[derive(Debug, Protobuf)]
214pub struct ProcessorTopologyConfig {
215 pub proc_count: u32,
216 pub vps_per_socket: Option<u32>,
217 pub enable_smt: Option<bool>,
218 pub arch: Option<ArchTopologyConfig>,
219}
220
221#[derive(Debug, Protobuf, Default, Clone)]
222pub struct X86TopologyConfig {
223 pub apic_id_offset: u32,
224 pub x2apic: X2ApicConfig,
225}
226
227#[derive(Debug, Default, Copy, Clone, Protobuf)]
228pub enum X2ApicConfig {
229 #[default]
230 Auto,
233 Supported,
236 Unsupported,
238 Enabled,
240}
241
242#[derive(Debug, Protobuf, Default, Clone)]
243pub enum PmuGsivConfig {
244 #[default]
245 Platform,
247 Gsiv(u32),
249}
250
251#[derive(Debug, Protobuf, Default, Clone)]
252pub struct Aarch64TopologyConfig {
253 pub gic_config: Option<GicConfig>,
254 pub pmu_gsiv: PmuGsivConfig,
255}
256
257#[derive(Debug, Protobuf, Clone)]
258pub struct GicConfig {
259 pub gic_distributor_base: u64,
260 pub gic_redistributors_base: u64,
261}
262
263#[derive(Debug, Protobuf, Clone)]
264pub enum ArchTopologyConfig {
265 X86(X86TopologyConfig),
266 Aarch64(Aarch64TopologyConfig),
267}
268
269#[derive(Debug, MeshPayload)]
270pub struct MemoryConfig {
271 pub mem_size: u64,
272 pub mmio_gaps: Vec<MemoryRange>,
273 pub prefetch_memory: bool,
274 pub pcie_ecam_base: u64,
275}
276
277#[derive(Debug, MeshPayload, Default)]
278pub struct VmbusConfig {
279 pub vsock_listener: Option<unix_socket::UnixListener>,
280 pub vsock_path: Option<String>,
281 pub vmbus_max_version: Option<u32>,
282 #[cfg(windows)]
283 pub vmbusproxy_handle: Option<vmbus_proxy::ProxyHandle>,
284 pub vtl2_redirect: bool,
285}
286
287#[derive(Debug, MeshPayload, Default)]
288pub struct HypervisorConfig {
289 pub with_hv: bool,
290 pub user_mode_hv_enlightenments: bool,
291 pub user_mode_apic: bool,
292 pub with_vtl2: Option<Vtl2Config>,
293 pub with_isolation: Option<IsolationType>,
294}
295
296#[derive(Debug, Copy, Clone, MeshPayload)]
297pub enum Hypervisor {
298 Kvm,
299 MsHv,
300 Whp,
301 Hvf,
302}
303
304impl fmt::Display for Hypervisor {
305 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
306 f.pad(match self {
307 Self::Kvm => "kvm",
308 Self::MsHv => "mshv",
309 Self::Whp => "whp",
310 Self::Hvf => "hvf",
311 })
312 }
313}
314
315#[derive(Debug, MeshPayload)]
317pub struct SerialPipes {
318 pub input: Option<File>,
324 pub output: Option<File>,
332}
333
334impl SerialPipes {
335 pub fn try_clone(&self) -> std::io::Result<Self> {
336 Ok(Self {
337 input: self.input.as_ref().map(File::try_clone).transpose()?,
338 output: self.output.as_ref().map(File::try_clone).transpose()?,
339 })
340 }
341}
342
343#[derive(Debug, MeshPayload)]
344pub struct KernelVmNicConfig {
345 pub instance_id: Guid,
346 pub mac_address: MacAddress,
347 pub switch_port_id: SwitchPortId,
348}
349
350#[derive(Clone, Debug, MeshPayload)]
351pub struct SwitchPortId {
352 pub switch: Guid,
353 pub port: Guid,
354}
355
356pub const DEFAULT_PCAT_BOOT_ORDER: [PcatBootDevice; 4] = [
357 PcatBootDevice::Optical,
358 PcatBootDevice::HardDrive,
359 PcatBootDevice::Network,
360 PcatBootDevice::Floppy,
361];
362
363#[derive(MeshPayload, Debug, Clone, Copy, PartialEq)]
364pub enum PcatBootDevice {
365 Floppy,
366 HardDrive,
367 Optical,
368 Network,
369}
370
371#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
372pub enum VirtioBus {
373 Mmio,
374 Pci,
375}
376
377#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
379pub enum LateMapVtl0MemoryPolicy {
380 Halt,
382 Log,
384 InjectException,
386}
387
388impl From<LateMapVtl0MemoryPolicy> for virt::LateMapVtl0MemoryPolicy {
389 fn from(value: LateMapVtl0MemoryPolicy) -> Self {
390 match value {
391 LateMapVtl0MemoryPolicy::Halt => virt::LateMapVtl0MemoryPolicy::Halt,
392 LateMapVtl0MemoryPolicy::Log => virt::LateMapVtl0MemoryPolicy::Log,
393 LateMapVtl0MemoryPolicy::InjectException => {
394 virt::LateMapVtl0MemoryPolicy::InjectException
395 }
396 }
397 }
398}
399
400#[derive(Debug, Clone, MeshPayload)]
406pub struct Vtl2Config {
407 pub vtl0_alias_map: bool,
410 pub late_map_vtl0_memory: Option<LateMapVtl0MemoryPolicy>,
414}
415
416#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
418pub enum IsolationType {
419 Vbs,
420}
421
422impl From<IsolationType> for virt::IsolationType {
423 fn from(value: IsolationType) -> Self {
424 match value {
425 IsolationType::Vbs => Self::Vbs,
426 }
427 }
428}
429
430#[derive(Copy, Clone, Debug, PartialEq, Eq, MeshPayload)]
432pub enum DeviceVtl {
433 Vtl0,
434 Vtl1,
435 Vtl2,
436}
437
438#[derive(Copy, Clone, Debug, MeshPayload)]
439pub enum UefiConsoleMode {
440 Default,
441 Com1,
442 Com2,
443 None,
444}
445
446#[derive(Copy, Clone, Debug, MeshPayload, Default)]
447pub enum EfiDiagnosticsLogLevelType {
448 #[default]
450 Default,
451 Info,
453 Full,
455}