openhcl_boot/host_params/
mod.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Module used to parse the host parameters used to setup Underhill. These are
5//! provided via a device tree IGVM parameter.
6
7use crate::cmdline::BootCommandLineOptions;
8use crate::host_params::shim_params::IsolationType;
9use arrayvec::ArrayString;
10use arrayvec::ArrayVec;
11use host_fdt_parser::CpuEntry;
12use host_fdt_parser::GicInfo;
13use host_fdt_parser::MemoryAllocationMode;
14use host_fdt_parser::MemoryEntry;
15use host_fdt_parser::VmbusInfo;
16use memory_range::MemoryRange;
17use memory_range::subtract_ranges;
18
19mod dt;
20mod mmio;
21pub mod shim_params;
22
23/// Maximum supported cpu count by underhill.
24pub const MAX_CPU_COUNT: usize = 2048;
25
26/// The maximum number of supported virtual NUMA nodes. This must be at least as
27/// large as whatever the host supports.
28pub const MAX_NUMA_NODES: usize = 64;
29
30pub const COMMAND_LINE_SIZE: usize = 0x2000;
31
32/// Each ram range reported by the host for VTL2 is split per NUMA node.
33///
34/// Today, Hyper-V has a max limit of 64 NUMA nodes, so we should only ever see
35/// 64 ram ranges.
36const MAX_VTL2_RAM_RANGES: usize = 64;
37
38/// The maximum number of ram ranges that can be read from the host.
39const MAX_PARTITION_RAM_RANGES: usize = 1024;
40
41/// Maximum size of the host-provided entropy
42pub const MAX_ENTROPY_SIZE: usize = 256;
43
44/// Maximum number of supported VTL2 used ranges.
45pub const MAX_VTL2_USED_RANGES: usize = 16;
46
47/// Information about the guest partition.
48#[derive(Debug)]
49pub struct PartitionInfo {
50    /// Ram assigned to VTL2. This is either parsed from the host via IGVM
51    /// parameters, or the fixed at build value.
52    ///
53    /// This vec is guaranteed to be sorted, and non-overlapping.
54    pub vtl2_ram: ArrayVec<MemoryEntry, MAX_VTL2_RAM_RANGES>,
55    /// The parameter region.
56    pub vtl2_full_config_region: MemoryRange,
57    /// Additional ram that can be reclaimed from the parameter region. Today,
58    /// this is the whole device tree provided by the host.
59    pub vtl2_config_region_reclaim: MemoryRange,
60    /// The vtl2 reserved region, that is reserved to both the kernel and
61    /// usermode.
62    pub vtl2_reserved_region: MemoryRange,
63    /// Memory used for the VTL2 private pool.
64    pub vtl2_pool_memory: MemoryRange,
65    /// Memory ranges that are in use by the bootshim, and any other persisted
66    /// ranges, such as the VTL2 private pool.
67    ///
68    /// TODO: Refactor these different ranges and consolidate address space
69    /// management.
70    pub vtl2_used_ranges: ArrayVec<MemoryRange, MAX_VTL2_USED_RANGES>,
71    ///  The full memory map provided by the host.
72    pub partition_ram: ArrayVec<MemoryEntry, MAX_PARTITION_RAM_RANGES>,
73    /// The partiton's isolation type.
74    pub isolation: IsolationType,
75    /// The reg field in device tree for the BSP. This is either the apic_id on
76    /// x64, or mpidr on aarch64.
77    pub bsp_reg: u32,
78    /// Cpu info for enabled cpus.
79    pub cpus: ArrayVec<CpuEntry, MAX_CPU_COUNT>,
80    /// VMBUS info for VTL2.
81    pub vmbus_vtl2: VmbusInfo,
82    /// VMBUS info for VTL0.
83    pub vmbus_vtl0: VmbusInfo,
84    /// Command line to be used for the underhill kernel.
85    pub cmdline: ArrayString<COMMAND_LINE_SIZE>,
86    /// Com3 serial device is available
87    pub com3_serial_available: bool,
88    /// GIC information
89    pub gic: Option<GicInfo>,
90    /// Memory allocation mode that was performed.
91    pub memory_allocation_mode: MemoryAllocationMode,
92    /// Entropy from the host to be used by the OpenHCL kernel
93    pub entropy: Option<ArrayVec<u8, MAX_ENTROPY_SIZE>>,
94    /// The VTL0 alias map physical address.
95    pub vtl0_alias_map: Option<u64>,
96    /// Host is compatible with DMA preservation / NVMe keep-alive.
97    pub nvme_keepalive: bool,
98    /// Parsed boot command line options.
99    pub boot_options: BootCommandLineOptions,
100}
101
102impl PartitionInfo {
103    /// Create an empty [`PartitionInfo`].
104    pub const fn new() -> Self {
105        PartitionInfo {
106            vtl2_ram: ArrayVec::new_const(),
107            vtl2_full_config_region: MemoryRange::EMPTY,
108            vtl2_config_region_reclaim: MemoryRange::EMPTY,
109            vtl2_reserved_region: MemoryRange::EMPTY,
110            vtl2_pool_memory: MemoryRange::EMPTY,
111            vtl2_used_ranges: ArrayVec::new_const(),
112            partition_ram: ArrayVec::new_const(),
113            isolation: IsolationType::None,
114            bsp_reg: 0,
115            cpus: ArrayVec::new_const(),
116            vmbus_vtl2: VmbusInfo {
117                mmio: ArrayVec::new_const(),
118                connection_id: 0,
119            },
120            vmbus_vtl0: VmbusInfo {
121                mmio: ArrayVec::new_const(),
122                connection_id: 0,
123            },
124            cmdline: ArrayString::new_const(),
125            com3_serial_available: false,
126            gic: None,
127            memory_allocation_mode: MemoryAllocationMode::Host,
128            entropy: None,
129            vtl0_alias_map: None,
130            nvme_keepalive: false,
131            boot_options: BootCommandLineOptions::new(),
132        }
133    }
134
135    /// Returns the parameter regions that are not being reclaimed.
136    pub fn vtl2_config_regions(&self) -> impl Iterator<Item = MemoryRange> + use<> {
137        subtract_ranges(
138            [self.vtl2_full_config_region],
139            [self.vtl2_config_region_reclaim],
140        )
141    }
142}