Skip to content

Commit 79646bb

Browse files
committed
multiboot2: Allow setting the RSDP tags
1 parent 888dd27 commit 79646bb

File tree

2 files changed

+93
-3
lines changed

2 files changed

+93
-3
lines changed

multiboot2/src/builder/information.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
use crate::builder::traits::StructAsBytes;
33
use crate::{
44
BasicMemoryInfoTag, BootInformationInner, BootLoaderNameTag, CommandLineTag, EFISdt32,
5-
EFISdt64, ElfSectionsTag, EndTag, FramebufferTag, MemoryMapTag, ModuleTag, SmbiosTag,
5+
EFISdt64, ElfSectionsTag, EndTag, FramebufferTag, MemoryMapTag, ModuleTag, RsdpV1Tag,
6+
RsdpV2Tag, SmbiosTag,
67
};
78

89
use alloc::boxed::Box;
@@ -23,6 +24,8 @@ pub struct Multiboot2InformationBuilder {
2324
module_tags: Vec<Box<ModuleTag>>,
2425
efisdt32: Option<EFISdt32>,
2526
efisdt64: Option<EFISdt64>,
27+
rsdp_v1_tag: Option<RsdpV1Tag>,
28+
rsdp_v2_tag: Option<RsdpV2Tag>,
2629
smbios_tags: Vec<Box<SmbiosTag>>,
2730
}
2831

@@ -38,6 +41,8 @@ impl Multiboot2InformationBuilder {
3841
framebuffer_tag: None,
3942
memory_map_tag: None,
4043
module_tags: Vec::new(),
44+
rsdp_v1_tag: None,
45+
rsdp_v2_tag: None,
4146
smbios_tags: Vec::new(),
4247
}
4348
}
@@ -90,6 +95,12 @@ impl Multiboot2InformationBuilder {
9095
for tag in &self.module_tags {
9196
len += Self::size_or_up_aligned(tag.byte_size())
9297
}
98+
if let Some(tag) = &self.rsdp_v1_tag {
99+
len += Self::size_or_up_aligned(tag.byte_size())
100+
}
101+
if let Some(tag) = &self.rsdp_v2_tag {
102+
len += Self::size_or_up_aligned(tag.byte_size())
103+
}
93104
for tag in &self.smbios_tags {
94105
len += Self::size_or_up_aligned(tag.byte_size())
95106
}
@@ -150,6 +161,12 @@ impl Multiboot2InformationBuilder {
150161
for tag in self.module_tags {
151162
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
152163
}
164+
if let Some(tag) = self.rsdp_v1_tag.as_ref() {
165+
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
166+
}
167+
if let Some(tag) = self.rsdp_v2_tag.as_ref() {
168+
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
169+
}
153170
for tag in self.smbios_tags {
154171
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
155172
}
@@ -195,6 +212,14 @@ impl Multiboot2InformationBuilder {
195212
self.module_tags.push(module_tag);
196213
}
197214

215+
pub fn rsdp_v1_tag(&mut self, rsdp_v1_tag: RsdpV1Tag) {
216+
self.rsdp_v1_tag = Some(rsdp_v1_tag);
217+
}
218+
219+
pub fn rsdp_v2_tag(&mut self, rsdp_v2_tag: RsdpV2Tag) {
220+
self.rsdp_v2_tag = Some(rsdp_v2_tag);
221+
}
222+
198223
pub fn add_smbios_tag(&mut self, smbios_tag: Box<SmbiosTag>) {
199224
self.smbios_tags.push(smbios_tag);
200225
}

multiboot2/src/rsdp.rs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
//!
99
//! Even though the bootloader should give the address of the real RSDP/XSDT, the checksum and
1010
//! signature should be manually verified.
11-
use crate::TagTypeId;
11+
#[cfg(feature = "builder")]
12+
use crate::builder::traits::StructAsBytes;
13+
use crate::tag_type::{TagType, TagTypeId};
14+
15+
use core::convert::TryInto;
16+
use core::mem::size_of;
1217
use core::slice;
1318
use core::str;
1419
use core::str::Utf8Error;
@@ -29,6 +34,25 @@ pub struct RsdpV1Tag {
2934
}
3035

3136
impl RsdpV1Tag {
37+
#[cfg(feature = "builder")]
38+
pub fn new(
39+
signature: [u8; 8],
40+
checksum: u8,
41+
oem_id: [u8; 6],
42+
revision: u8,
43+
rsdt_address: u32,
44+
) -> Self {
45+
Self {
46+
typ: TagType::AcpiV1.into(),
47+
size: size_of::<Self>().try_into().unwrap(),
48+
signature,
49+
checksum,
50+
oem_id,
51+
revision,
52+
rsdt_address,
53+
}
54+
}
55+
3256
/// The "RSD PTR " marker signature.
3357
///
3458
/// This is originally a 8-byte C string (not null terminated!) that must contain "RSD PTR "
@@ -62,6 +86,13 @@ impl RsdpV1Tag {
6286
}
6387
}
6488

89+
#[cfg(feature = "builder")]
90+
impl StructAsBytes for RsdpV1Tag {
91+
fn byte_size(&self) -> usize {
92+
size_of::<Self>()
93+
}
94+
}
95+
6596
/// This tag contains a copy of RSDP as defined per ACPI 2.0 or later specification.
6697
#[derive(Clone, Copy, Debug)]
6798
#[repr(C, packed)]
@@ -72,14 +103,41 @@ pub struct RsdpV2Tag {
72103
checksum: u8,
73104
oem_id: [u8; 6],
74105
revision: u8,
75-
_rsdt_address: u32,
106+
rsdt_address: u32,
76107
length: u32,
77108
xsdt_address: u64, // This is the PHYSICAL address of the XSDT
78109
ext_checksum: u8,
79110
_reserved: [u8; 3],
80111
}
81112

82113
impl RsdpV2Tag {
114+
#[cfg(feature = "builder")]
115+
#[allow(clippy::too_many_arguments)]
116+
pub fn new(
117+
signature: [u8; 8],
118+
checksum: u8,
119+
oem_id: [u8; 6],
120+
revision: u8,
121+
rsdt_address: u32,
122+
length: u32,
123+
xsdt_address: u64,
124+
ext_checksum: u8,
125+
) -> Self {
126+
Self {
127+
typ: TagType::AcpiV2.into(),
128+
size: size_of::<Self>().try_into().unwrap(),
129+
signature,
130+
checksum,
131+
oem_id,
132+
revision,
133+
rsdt_address,
134+
length,
135+
xsdt_address,
136+
ext_checksum,
137+
_reserved: [0; 3],
138+
}
139+
}
140+
83141
/// The "RSD PTR " marker signature.
84142
///
85143
/// This is originally a 8-byte C string (not null terminated!) that must contain "RSD PTR ".
@@ -120,3 +178,10 @@ impl RsdpV2Tag {
120178
self.ext_checksum
121179
}
122180
}
181+
182+
#[cfg(feature = "builder")]
183+
impl StructAsBytes for RsdpV2Tag {
184+
fn byte_size(&self) -> usize {
185+
size_of::<Self>()
186+
}
187+
}

0 commit comments

Comments
 (0)