multiboot2_host/bootinfo/
tag.rs1use std::io::Write;
2
3use byteorder::{WriteBytesExt, LE};
4use num_enum::IntoPrimitive;
5
6#[derive(Debug, Copy, Clone, PartialEq, Eq)]
7pub struct MemMapEntry {
8 pub base_addr: u64,
9 pub length: u64,
10 pub entry_type: u32,
11 }
13
14const MEMMAP_ENTRY_VERSION: u32 = 0;
15const MEMMAP_ENTRY_SIZE: u32 = 24;
16
17#[repr(u32)]
18#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive)]
19pub enum TagType {
20 End = 0,
21 BasicMeminfo = 4,
22 MemMap = 6,
23
24 #[cfg(feature = "hvm")]
25 HybridRuntime = 0xF00DF00D,
26}
27
28#[repr(u32)]
29#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive)]
30pub enum RegionType {
31 Available = 1,
32 AcpiReclaimable = 3,
33 NonVolatile = 4,
34 Defective = 5,
35}
36
37#[derive(Debug, Clone, PartialEq, Eq)]
38pub enum Tag {
39 BasicMeminfo {
40 mem_lower: u32,
41 mem_upper: u32,
42 },
43 MemMap {
44 entries: Vec<MemMapEntry>,
45 },
46 #[cfg(feature = "hvm")]
47 HybridRuntime {
48 total_num_apics: u32,
49 first_hrt_apic_id: u32,
50 have_hrt_ioapic: bool, first_hrt_ioapic_entry: u32,
52 cpu_freq_khz: u64,
53 hrt_flags: u64,
54 max_mem_mapped: u64,
55 first_hrt_gpa: u64,
56 boot_state_gpa: u64,
57 gva_offset: u64,
58 comm_page_gpa: u64,
59 hrt_int_vector: u8,
60 },
62 End,
63}
64
65impl Tag {
66 pub fn tag_type(&self) -> TagType {
67 match self {
68 Tag::BasicMeminfo { .. } => TagType::BasicMeminfo,
69 Tag::MemMap { .. } => TagType::MemMap,
70 #[cfg(feature = "hvm")]
71 Tag::HybridRuntime { .. } => TagType::HybridRuntime,
72 Tag::End => TagType::End,
73 }
74 }
75
76 pub fn size(&self) -> u32 {
77 let body_size = match self {
78 Tag::BasicMeminfo { .. } => 8,
79 Tag::MemMap { entries } => 8 + entries.len() as u32 * MEMMAP_ENTRY_SIZE,
80 #[cfg(feature = "hvm")]
81 Tag::HybridRuntime { .. } => 80,
82 Tag::End => 0,
83 };
84 body_size + 8
85 }
86
87 pub fn write_to<W: Write>(&self, mut w: W) -> std::io::Result<()> {
88 w.write_u32::<LE>(self.tag_type().into())?;
89 w.write_u32::<LE>(self.size())?;
90
91 match self {
92 Tag::BasicMeminfo {
93 mem_lower,
94 mem_upper,
95 } => {
96 w.write_u32::<LE>(*mem_lower)?;
97 w.write_u32::<LE>(*mem_upper)?;
98 }
99 Tag::MemMap { entries } => {
100 w.write_u32::<LE>(MEMMAP_ENTRY_SIZE)?;
101 w.write_u32::<LE>(MEMMAP_ENTRY_VERSION)?;
102 for entry in entries {
103 w.write_u64::<LE>(entry.base_addr)?;
104 w.write_u64::<LE>(entry.length)?;
105 w.write_u32::<LE>(entry.entry_type)?;
106 w.write_u32::<LE>(0)?; }
108 }
109 #[cfg(feature = "hvm")]
110 Tag::HybridRuntime {
111 total_num_apics,
112 first_hrt_apic_id,
113 have_hrt_ioapic,
114 first_hrt_ioapic_entry,
115 cpu_freq_khz,
116 hrt_flags,
117 max_mem_mapped,
118 first_hrt_gpa,
119 boot_state_gpa,
120 gva_offset,
121 comm_page_gpa,
122 hrt_int_vector,
123 } => {
124 for x in &[
125 *total_num_apics,
126 *first_hrt_apic_id,
127 *have_hrt_ioapic as u32,
128 *first_hrt_ioapic_entry,
129 ] {
130 w.write_u32::<LE>(*x)?;
131 }
132 for x in &[
133 *cpu_freq_khz,
134 *hrt_flags,
135 *max_mem_mapped,
136 *first_hrt_gpa,
137 *boot_state_gpa,
138 *gva_offset,
139 *comm_page_gpa,
140 ] {
141 w.write_u64::<LE>(*x)?;
142 }
143 w.write_u8(*hrt_int_vector)?;
144 w.write(&[0u8; 7])?;
145 }
146 Tag::End => {}
147 }
148 Ok(())
149 }
150}