Skip to main content

openvmm_defs/
config.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Configuration for the VM worker.
5
6use guid::Guid;
7use input_core::InputData;
8use memory_range::MemoryRange;
9use mesh::MeshPayload;
10use mesh::payload::Protobuf;
11use net_backend_resources::mac_address::MacAddress;
12use openvmm_pcat_locator::RomFileLocation;
13use std::fs::File;
14use vm_resource::Resource;
15use vm_resource::kind::PciDeviceHandleKind;
16use vm_resource::kind::VirtioDeviceHandle;
17use vm_resource::kind::VmbusDeviceHandleKind;
18use vmgs_resources::VmgsResource;
19use vmotherboard::ChipsetDeviceHandle;
20use vmotherboard::LegacyPciChipsetDeviceHandle;
21use vmotherboard::options::BaseChipsetManifest;
22use vmotherboard::options::VmChipsetCapabilities;
23
24#[derive(MeshPayload, Debug)]
25pub struct Config {
26    pub load_mode: LoadMode,
27    pub floppy_disks: Vec<floppy_resources::FloppyDiskConfig>,
28    pub ide_disks: Vec<ide_resources::IdeDeviceConfig>,
29    pub pcie_root_complexes: Vec<PcieRootComplexConfig>,
30    pub pcie_devices: Vec<PcieDeviceConfig>,
31    pub pcie_switches: Vec<PcieSwitchConfig>,
32    pub pcie_generic_initiators: Vec<PcieGenericInitiatorConfig>,
33    pub vpci_devices: Vec<VpciDeviceConfig>,
34    pub numa: NumaTopology,
35    pub processor_topology: ProcessorTopologyConfig,
36    pub hypervisor: HypervisorConfig,
37    pub chipset: BaseChipsetManifest,
38    pub vmbus: Option<VmbusConfig>,
39    pub vtl2_vmbus: Option<VmbusConfig>,
40    #[cfg(windows)]
41    pub kernel_vmnics: Vec<KernelVmNicConfig>,
42    pub input: mesh::Receiver<InputData>,
43    pub framebuffer: Option<framebuffer::Framebuffer>,
44    pub vga_firmware: Option<RomFileLocation>,
45    pub vtl2_gfx: bool,
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    // TODO: move FirmwareEvent somewhere not GED-specific.
53    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 pci_chipset_devices: Vec<LegacyPciChipsetDeviceHandle>,
58    pub isa_dma_controller: Option<Resource<vm_resource::kind::IsaDmaControllerHandleKind>>,
59    pub chipset_capabilities: VmChipsetCapabilities,
60    /// Memory layout sizing for the layout engine. Determines chipset MMIO
61    /// range sizes; addresses are allocated dynamically by the resolver.
62    pub layout: vmm_core_defs::LayoutConfig,
63    // This is used for testing. TODO: resourcify, and also store this in VMGS.
64    pub rtc_delta_milliseconds: i64,
65    /// allow the guest to reset without notifying the client
66    pub automatic_guest_reset: bool,
67    pub efi_diagnostics_log_level: EfiDiagnosticsLogLevelType,
68}
69
70pub const DEFAULT_GIC_DISTRIBUTOR_BASE: u64 = 0xFFFF_0000;
71// The KVM in-kernel vGICv3 requires the distributor and redistributor bases be 64KiB aligned.
72pub const DEFAULT_GIC_REDISTRIBUTORS_BASE: u64 = if cfg!(target_os = "linux") {
73    0xEFFF_0000
74} else {
75    0xEFFE_E000
76};
77
78/// Base address of the guest-visible GIC v2m MSI frame (exposed via the MADT
79/// and used by the software v2m SETSPI decoder for emulated devices). This is
80/// OpenVMM-emulated MMIO (one 4 KiB page), not shadowed by the hypervisor, so
81/// it stays at the conventional address.
82pub const DEFAULT_GIC_V2M_MSI_FRAME_BASE: u64 = 0xEFFE_8000;
83/// Size of the v2m MSI frame (one 4KB page is the architectural minimum).
84pub const GIC_V2M_MSI_FRAME_SIZE: u64 = 0x1000;
85
86/// Base address of the GIC v2m MSI doorbell used for passthrough on the
87/// MSHV root/arm64 backend. Registered with the hypervisor as
88/// GITS_TRANSLATER_BASE_ADDRESS.
89/// The hypervisor shadows a ~64 KiB region at this base,
90/// so it uses the Hyper-V convention address 0xEFF6_8000.
91pub const DEFAULT_GIC_V2M_DOORBELL_BASE: u64 = 0xEFF6_8000;
92
93/// Base address of the GICv3 ITS MMIO region. Must be 64 KiB aligned,
94/// below the v2m frame address, and not overlap other devices.
95/// The region extends from this base to base + GIC_ITS_SIZE (128 KiB).
96pub const DEFAULT_GIC_ITS_BASE: u64 = 0xEFFC_0000;
97/// Size of the ITS MMIO region (control frame + translation frame, 2×64 KiB).
98pub const GIC_ITS_SIZE: u64 = 0x2_0000;
99
100/// Default virtual timer PPI (GIC INTID). PPI 4 = INTID 16 + 4 = 20.
101/// This is the EL1 virtual timer interrupt used across Hyper-V, KVM, and HVF.
102pub const DEFAULT_VIRT_TIMER_PPI: u32 = 20;
103
104/// Default total number of GIC interrupts (SGIs + PPIs + SPIs).
105/// Must satisfy KVM constraints: 64 <= n <= 1023, multiple of 32.
106/// 992 = 31 × 32 is the largest valid value.
107pub const DEFAULT_GIC_NR_IRQS: u32 = 992;
108
109/// Default VMBus PPI (GIC INTID). PPI 2 = INTID 16 + 2 = 18.
110pub const DEFAULT_VMBUS_PPI: u32 = 18;
111
112/// How firmware tables are presented to the guest in Linux direct boot.
113///
114/// On x86, `DeviceTree` is not supported and will be rejected. On aarch64,
115/// this selects between a full device tree or an ACPI boot path.
116#[derive(MeshPayload, Debug, Clone, Copy, PartialEq, Eq)]
117pub enum LinuxDirectBootMode {
118    /// Full device tree with all devices described in DT nodes (aarch64 only).
119    DeviceTree,
120    /// ACPI tables for device discovery. On aarch64, this also synthesizes
121    /// an EFI system table so the kernel enters its ACPI code path. On x86,
122    /// ACPI tables are always provided via the zero page.
123    Acpi,
124}
125
126#[derive(MeshPayload, Debug)]
127pub enum LoadMode {
128    Linux {
129        kernel: File,
130        initrd: Option<File>,
131        cmdline: String,
132        enable_serial: bool,
133        custom_dsdt: Option<Vec<u8>>,
134        boot_mode: LinuxDirectBootMode,
135    },
136    Uefi {
137        firmware: File,
138        enable_debugging: bool,
139        enable_memory_protections: bool,
140        disable_frontpage: bool,
141        enable_tpm: bool,
142        enable_battery: bool,
143        enable_serial: bool,
144        enable_vpci_boot: bool,
145        uefi_console_mode: Option<UefiConsoleMode>,
146        default_boot_always_attempt: bool,
147        bios_guid: Guid,
148        enable_vmbus: bool,
149        force_dma_bounce: bool,
150    },
151    Pcat {
152        firmware: RomFileLocation,
153        boot_order: [PcatBootDevice; 4],
154    },
155    Igvm {
156        file: File,
157        cmdline: String,
158        vtl2_base_address: Vtl2BaseAddressType,
159        com_serial: Option<SerialInformation>,
160    },
161    None,
162}
163
164#[derive(Debug, Clone, Copy, MeshPayload)]
165pub struct SerialInformation {
166    pub io_port: u16,
167    pub irq: u32,
168}
169
170/// Different types to specify the base address for the VTL2 region of the IGVM
171/// file.
172#[derive(Debug, Clone, Copy, MeshPayload)]
173pub enum Vtl2BaseAddressType {
174    /// Use the addresses specified in the file. The IGVM file does not need to
175    /// support relocations.
176    File,
177    /// Put VTL2 at the specified address. The IGVM file must support
178    /// relocations.
179    Absolute(u64),
180    /// Use the specified range in the supplied MemoryLayout, as the caller has
181    /// created a specific range for VTL2. The IGVM file must support
182    /// relocations.
183    ///
184    /// An optional size may be specified to override the size describing VTL2
185    /// provided in the IGVM file. It must be larger than the IGVM file provided
186    /// size.
187    MemoryLayout { size: Option<u64> },
188    /// Tell VTL2 to allocate out it's own memory. This will load the file at
189    /// the base address specified in the file, and the host will tell VTL2 the
190    /// size of memory to allocate for itself.
191    ///
192    /// An optional size may be specified to override the size describing VTL2
193    /// provided in the IGVM file. It must be larger than the IGVM file provided
194    /// size.
195    Vtl2Allocate { size: Option<u64> },
196}
197
198/// Specifies a PCIe MMIO BAR window, either by size (the resolver allocates) or
199/// by a fixed location. Fixed locations exist for assigned-device, IOMMU, and
200/// physical-topology compatibility.
201#[derive(Debug, MeshPayload)]
202pub enum PcieMmioRangeConfig {
203    /// Dynamically allocate a range of the given size.
204    Dynamic {
205        /// Size of the range in bytes.
206        size: u64,
207    },
208    /// Use the specified fixed memory range.
209    Fixed(MemoryRange),
210}
211
212#[derive(Debug, MeshPayload)]
213pub struct RootComplexCxlConfig {
214    /// HDM window size in bytes for this CXL root complex.
215    pub hdm_size: u64,
216    /// CFMWS HDM window restrictions bitmask.
217    pub hdm_window_restrictions: u16,
218}
219
220#[derive(Debug, MeshPayload)]
221pub struct PcieRootComplexConfig {
222    pub index: u32,
223    pub name: String,
224    pub segment: u16,
225    pub start_bus: u8,
226    pub end_bus: u8,
227    pub low_mmio: PcieMmioRangeConfig,
228    pub high_mmio: PcieMmioRangeConfig,
229    pub ports: Vec<PciePortConfig>,
230    /// Optional CXL configuration for root-complex CXL mode.
231    pub cxl: Option<RootComplexCxlConfig>,
232    /// Optional IOMMU for this root complex.
233    pub iommu: Option<PcieIommuConfig>,
234    /// NUMA node affinity for this root complex. Used to generate `_PXM` in
235    /// the ACPI SSDT so the guest OS sees correct NUMA locality for devices
236    /// under this root complex.
237    pub vnode: Option<u32>,
238    /// When true, treat non-zero BAR values found during probing as pinned
239    /// addresses. Used for P2P DMA with GPA = HPA.
240    pub preserve_bars: bool,
241}
242
243/// Configuration for a single PCIe port — either a root-complex root port or a
244/// switch downstream port.
245#[derive(Debug, MeshPayload)]
246pub struct PciePortConfig {
247    /// Port name used for topology wiring and lookup.
248    pub name: String,
249    /// The device/function (`device << 3 | function`) to place this port at on
250    /// its bus.
251    ///
252    /// When `None`, the port is assigned the lowest available devfn. Ports are
253    /// assigned in order, so an explicit devfn that collides with a
254    /// previously-assigned port (including one assigned automatically) is an
255    /// error. Honored for both root-complex root ports and switch downstream
256    /// ports.
257    pub devfn: Option<u8>,
258    /// Enables PCIe hotplug capabilities for this port.
259    pub hotplug: bool,
260    /// Optional ACS capability bitmask to expose on this port.
261    pub acs_capabilities_supported: Option<u16>,
262    /// Marks this port as CXL-capable.
263    ///
264    /// Runtime port construction derives required BAR/subregion layout from
265    /// this flag (currently CXL component registers for BAR0).
266    pub cxl: bool,
267}
268
269#[derive(Debug, MeshPayload)]
270pub struct PcieSwitchConfig {
271    pub name: String,
272    pub parent_port: String,
273    /// The downstream ports of this switch.
274    pub ports: Vec<PciePortConfig>,
275}
276
277/// Declares that the device directly behind a named PCIe port (a root port or
278/// a switch downstream port) is a generic initiator (GI) for the given NUMA
279/// node. Used to generate an SRAT Generic Initiator Affinity structure so the
280/// guest attaches the device's memory to that (typically CPU-less) proximity
281/// domain.
282///
283/// The port is resolved against the live topology by port name after switch
284/// downstream ports have been enumerated, so it can target devices that sit
285/// behind a switch.
286#[derive(Debug, MeshPayload)]
287pub struct PcieGenericInitiatorConfig {
288    /// Name of the PCIe port (root port or switch downstream port) behind
289    /// which the generic-initiator device resides.
290    pub port_name: String,
291    /// NUMA node the device is a generic initiator for.
292    pub node: u32,
293}
294
295#[derive(Debug, MeshPayload)]
296pub struct PcieDeviceConfig {
297    pub port_name: String,
298    pub resource: Resource<PciDeviceHandleKind>,
299}
300
301#[derive(Debug, MeshPayload)]
302pub struct VpciDeviceConfig {
303    pub vtl: DeviceVtl,
304    /// The ID of the device. Vpci devices are identified by a portion of `data2` and `data3` of the
305    /// instance ID, which is used to generate the guest-visible device ID.
306    pub instance_id: Guid,
307    pub resource: Resource<PciDeviceHandleKind>,
308    /// NUMA node affinity for this VPCI device.
309    pub vnode: Option<u32>,
310}
311
312#[derive(Debug, Protobuf)]
313pub struct ProcessorTopologyConfig {
314    pub proc_count: u32,
315    pub vps_per_socket: Option<u32>,
316    pub enable_smt: Option<bool>,
317    pub arch: Option<ArchTopologyConfig>,
318}
319
320#[derive(Debug, Protobuf, Default, Clone)]
321pub struct X86TopologyConfig {
322    pub apic_id_offset: u32,
323    pub x2apic: X2ApicConfig,
324}
325
326#[derive(Debug, Default, Copy, Clone, Protobuf)]
327pub enum X2ApicConfig {
328    #[default]
329    /// Support the X2APIC if recommended by the hypervisor or if needed by the
330    /// topology configuration.
331    Auto,
332    /// Support the X2APIC, and automatically enable it if needed to address all
333    /// processors.
334    Supported,
335    /// Do not support the X2APIC.
336    Unsupported,
337    /// Support and enable the X2APIC.
338    Enabled,
339}
340
341#[derive(Debug, Protobuf, Default, Clone)]
342pub enum PmuGsivConfig {
343    #[default]
344    /// Use the hypervisor's platform GSIV value for the PMU.
345    Platform,
346    /// Use the specified GSIV value for the PMU.
347    Gsiv(u32),
348    /// Disable the PMU.
349    Disabled,
350}
351
352/// MSI controller selection for aarch64 PCIe interrupt delivery.
353#[derive(Debug, Protobuf, Default, Clone)]
354pub enum GicMsiConfig {
355    /// Automatically select the best available MSI controller:
356    /// ITS when the hypervisor supports it, otherwise GICv2m.
357    #[default]
358    Auto,
359    /// Force GICv3 ITS for MSI delivery via LPIs.
360    Its,
361    /// Force GICv2m for MSI delivery via SPIs.
362    V2m {
363        /// Number of SPIs to reserve for PCIe MSIs. Defaults to a
364        /// platform-specific value when `None`.
365        spi_count: Option<u32>,
366    },
367}
368
369/// IOMMU configuration for a single PCIe root complex.
370#[derive(Debug, MeshPayload, Clone)]
371pub enum PcieIommuConfig {
372    /// AMD IOMMU (AMD-Vi) for x86_64 guests.
373    AmdVi,
374    /// Arm SMMUv3 for aarch64 guests.
375    Smmu,
376    /// Intel VT-d for x86_64 guests.
377    IntelVtd,
378}
379
380#[derive(Debug, Protobuf, Default, Clone)]
381pub struct Aarch64TopologyConfig {
382    pub gic_config: Option<GicConfig>,
383    pub pmu_gsiv: PmuGsivConfig,
384    pub gic_msi: GicMsiConfig,
385}
386
387/// GIC configuration for the virtual machine.
388///
389/// The variant selects the GIC version. `None` inner config means use
390/// defaults for that version's addresses.
391#[derive(Debug, Protobuf, Clone)]
392pub enum GicConfig {
393    /// GICv2 with optional address overrides.
394    V2(Option<GicV2Config>),
395    /// GICv3 with optional address overrides.
396    V3(Option<GicV3Config>),
397}
398
399/// GICv2-specific address configuration.
400#[derive(Debug, Protobuf, Clone)]
401pub struct GicV2Config {
402    pub gic_distributor_base: u64,
403    pub cpu_interface_base: u64,
404}
405
406/// GICv3-specific address configuration.
407#[derive(Debug, Protobuf, Clone)]
408pub struct GicV3Config {
409    pub gic_distributor_base: u64,
410    pub gic_redistributors_base: u64,
411}
412
413#[derive(Debug, Protobuf, Clone)]
414pub enum ArchTopologyConfig {
415    X86(X86TopologyConfig),
416    Aarch64(Aarch64TopologyConfig),
417}
418
419/// Per-node memory allocation configuration.
420#[derive(Debug, Clone, Copy, MeshPayload)]
421pub struct MemoryConfig {
422    pub mem_size: u64,
423    pub prefetch_memory: bool,
424    pub private_memory: bool,
425    pub transparent_hugepages: bool,
426    pub hugepages: bool,
427    pub hugepage_size: Option<u64>,
428    /// Host physical NUMA node to bind this allocation to (Linux:
429    /// `mbind(MPOL_BIND)`). `None` means OS default placement.
430    pub host_numa_node: Option<u32>,
431}
432
433/// Virtual NUMA topology for the VM.
434#[derive(Debug, MeshPayload)]
435pub struct NumaTopology {
436    /// NUMA nodes. The vnode ID is the index into this vector.
437    pub nodes: Vec<NumaNode>,
438    /// Inter-node distances for the SLIT. If empty, defaults are used
439    /// (10 for self, 20 for cross-node).
440    pub distances: Vec<NumaDistance>,
441}
442
443/// A single virtual NUMA node.
444#[derive(Debug, MeshPayload)]
445pub struct NumaNode {
446    /// Memory allocation for this node. `None` means a CPU-only or
447    /// device-only node.
448    pub mem: Option<MemoryConfig>,
449    /// VP assignment for this node.
450    pub vps: VpAssignment,
451}
452
453/// How VPs are assigned to a NUMA node.
454#[derive(Debug, MeshPayload)]
455pub enum VpAssignment {
456    /// Assign VPs to nodes by round-robining sockets over the CPU-bearing
457    /// nodes only: a VP with socket ID `vp_index / vps_per_socket` belongs to
458    /// the `(vp_index / vps_per_socket) % num_cpu_nodes`-th `FromTopology`
459    /// node. `vps_per_socket` comes from `ProcessorTopologyConfig`;
460    /// `num_cpu_nodes` is the number of `FromTopology` nodes, so `Empty`
461    /// (CPU-less) nodes are skipped and do not affect the distribution.
462    FromTopology,
463    /// Explicit VP indices assigned to this node.
464    Explicit(Vec<u32>),
465    /// A CPU-less node: no VPs are assigned to it. Unlike `Explicit`, this
466    /// may be combined with `FromTopology` nodes, so a memory- or
467    /// device-only node can be declared without forcing every other node to
468    /// spell out its VP set.
469    Empty,
470}
471
472/// An inter-node distance entry for the ACPI SLIT.
473#[derive(Debug, MeshPayload)]
474pub struct NumaDistance {
475    /// Source node index.
476    pub src: u32,
477    /// Destination node index.
478    pub dst: u32,
479    /// Distance value (10 = local, 20 = default cross-node, 255 = unreachable).
480    pub distance: u8,
481}
482
483#[derive(Debug, MeshPayload, Default)]
484pub struct VmbusConfig {
485    pub vsock_listener: Option<unix_socket::UnixListener>,
486    pub vsock_path: Option<String>,
487    pub vmbus_max_version: Option<u32>,
488    #[cfg(windows)]
489    pub vmbusproxy_handle: Option<vmbus_proxy::ProxyHandle>,
490    pub vtl2_redirect: bool,
491}
492
493#[derive(Debug, MeshPayload, Default)]
494pub struct HypervisorConfig {
495    pub with_hv: bool,
496    pub with_vtl2: Option<Vtl2Config>,
497    pub with_isolation: Option<IsolationType>,
498    /// Expose hardware virtualization (VMX/SVM) to the guest so that it can run
499    /// its own hypervisor. A backend that does not recognize this request
500    /// rejects it rather than silently ignoring it (see
501    /// `virt::Hypervisor::recognizes_nested_virt`).
502    pub nested_virt: bool,
503}
504
505#[derive(Debug, MeshPayload)]
506pub struct KernelVmNicConfig {
507    pub instance_id: Guid,
508    pub mac_address: MacAddress,
509    pub switch_port_id: SwitchPortId,
510}
511
512#[derive(Clone, Debug, MeshPayload)]
513pub struct SwitchPortId {
514    pub switch: Guid,
515    pub port: Guid,
516}
517
518pub const DEFAULT_PCAT_BOOT_ORDER: [PcatBootDevice; 4] = [
519    PcatBootDevice::Optical,
520    PcatBootDevice::HardDrive,
521    PcatBootDevice::Network,
522    PcatBootDevice::Floppy,
523];
524
525#[derive(MeshPayload, Debug, Clone, Copy, PartialEq)]
526pub enum PcatBootDevice {
527    Floppy,
528    HardDrive,
529    Optical,
530    Network,
531}
532
533#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
534pub enum VirtioBus {
535    Mmio,
536    Pci,
537}
538
539/// Policy for the partition when mapping VTL0 memory late.
540#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
541pub enum LateMapVtl0MemoryPolicy {
542    /// Halt execution of the VP if VTL0 memory is accessed.
543    Halt,
544    /// Log the error but emulate the access with the instruction emulator.
545    Log,
546    /// Inject an exception into the guest.
547    InjectException,
548}
549
550impl From<LateMapVtl0MemoryPolicy> for virt::LateMapVtl0MemoryPolicy {
551    fn from(value: LateMapVtl0MemoryPolicy) -> Self {
552        match value {
553            LateMapVtl0MemoryPolicy::Halt => virt::LateMapVtl0MemoryPolicy::Halt,
554            LateMapVtl0MemoryPolicy::Log => virt::LateMapVtl0MemoryPolicy::Log,
555            LateMapVtl0MemoryPolicy::InjectException => {
556                virt::LateMapVtl0MemoryPolicy::InjectException
557            }
558        }
559    }
560}
561
562/// Configuration for VTL2.
563///
564/// NOTE: This is distinct from `virt::Vtl2Config` to keep an abstraction
565/// between the virt crate and this crate. Users should not be specifying
566/// virt crate configuration directly.
567#[derive(Debug, Clone, MeshPayload)]
568pub struct Vtl2Config {
569    /// Enable the VTL0 alias map. This maps VTL0's view of memory in VTL2 at
570    /// the highest legal physical address bit.
571    pub vtl0_alias_map: bool,
572    /// If set, map VTL0 memory late after VTL2 has started. The current
573    /// heuristic is to defer mapping VTL0 memory until the first
574    /// `HvModifyVtlProtectionMask` hypercall is made.
575    pub late_map_vtl0_memory: Option<LateMapVtl0MemoryPolicy>,
576}
577
578// Isolation type for a partition.
579#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
580pub enum IsolationType {
581    Vbs,
582    Snp,
583    Cca,
584}
585
586impl From<IsolationType> for virt::IsolationType {
587    fn from(value: IsolationType) -> Self {
588        match value {
589            IsolationType::Vbs => Self::Vbs,
590            IsolationType::Snp => Self::Snp,
591            IsolationType::Cca => Self::Cca,
592        }
593    }
594}
595
596/// Which VTL to assign a particular device to.
597#[derive(Copy, Clone, Debug, PartialEq, Eq, MeshPayload)]
598pub enum DeviceVtl {
599    Vtl0,
600    Vtl1,
601    Vtl2,
602}
603
604#[derive(Copy, Clone, Debug, MeshPayload)]
605pub enum UefiConsoleMode {
606    Default,
607    Com1,
608    Com2,
609    None,
610}
611
612#[derive(Copy, Clone, Debug, MeshPayload, Default)]
613pub enum EfiDiagnosticsLogLevelType {
614    /// Default log level
615    #[default]
616    Default,
617    /// Include INFO logs
618    Info,
619    /// All logs
620    Full,
621}