Skip to content

Commit 403087f

Browse files
committed
multiboot2: Allow setting the RSDP tags
1 parent 3c4ee32 commit 403087f

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

multiboot2/src/builder/information.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::builder::traits::StructAsBytes;
33
use crate::{
44
BasicMemoryInfoTag, BootInformationInner, BootLoaderNameTag, CommandLineTag,
55
EFISdt32, EFISdt64, ElfSectionsTag, EndTag, FramebufferTag, MemoryMapTag,
6-
ModuleTag, SmbiosTag,
6+
ModuleTag, RsdpV1Tag, RsdpV2Tag, SmbiosTag,
77
};
88

99
use alloc::boxed::Box;
@@ -24,6 +24,8 @@ pub struct Multiboot2InformationBuilder {
2424
module_tags: Vec<Box<ModuleTag>>,
2525
efisdt32: Option<EFISdt32>,
2626
efisdt64: Option<EFISdt64>,
27+
rsdp_v1_tag: Option<RsdpV1Tag>,
28+
rsdp_v2_tag: Option<RsdpV2Tag>,
2729
smbios_tags: Vec<Box<SmbiosTag>>,
2830
}
2931

@@ -39,6 +41,8 @@ impl Multiboot2InformationBuilder {
3941
framebuffer_tag: None,
4042
memory_map_tag: None,
4143
module_tags: Vec::new(),
44+
rsdp_v1_tag: None,
45+
rsdp_v2_tag: None,
4246
smbios_tags: Vec::new(),
4347
}
4448
}
@@ -91,6 +95,12 @@ impl Multiboot2InformationBuilder {
9195
for tag in &self.module_tags {
9296
len += Self::size_or_up_aligned(tag.byte_size())
9397
}
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+
}
94104
for tag in &self.smbios_tags {
95105
len += Self::size_or_up_aligned(tag.byte_size())
96106
}
@@ -153,6 +163,12 @@ impl Multiboot2InformationBuilder {
153163
for tag in self.module_tags {
154164
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
155165
}
166+
if let Some(tag) = self.rsdp_v1_tag.as_ref() {
167+
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
168+
}
169+
if let Some(tag) = self.rsdp_v2_tag.as_ref() {
170+
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
171+
}
156172
for tag in self.smbios_tags {
157173
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
158174
}
@@ -198,6 +214,14 @@ impl Multiboot2InformationBuilder {
198214
self.module_tags.push(module_tag);
199215
}
200216

217+
pub fn rsdp_v1_tag(&mut self, rsdp_v1_tag: RsdpV1Tag) {
218+
self.rsdp_v1_tag = Some(rsdp_v1_tag);
219+
}
220+
221+
pub fn rsdp_v2_tag(&mut self, rsdp_v2_tag: RsdpV2Tag) {
222+
self.rsdp_v2_tag = Some(rsdp_v2_tag);
223+
}
224+
201225
pub fn add_smbios_tag(&mut self, smbios_tag: Box<SmbiosTag>) {
202226
self.smbios_tags.push(smbios_tag);
203227
}

multiboot2/src/rsdp.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
//! Even though the bootloader should give the address of the real RSDP/XSDT, the checksum and
1010
//! signature should be manually verified.
1111
use crate::TagType;
12+
#[cfg(feature = "builder")]
13+
use crate::builder::traits::StructAsBytes;
14+
use core::convert::TryInto;
15+
use core::mem::size_of;
1216
use core::slice;
1317
use core::str;
1418
use core::str::Utf8Error;
@@ -29,6 +33,17 @@ pub struct RsdpV1Tag {
2933
}
3034

3135
impl RsdpV1Tag {
36+
#[cfg(feature = "builder")]
37+
pub fn new(
38+
signature: [u8; 8], checksum: u8, oem_id: [u8; 6], revision: u8,
39+
rsdt_address: u32,
40+
) -> Self {
41+
Self {
42+
typ: TagType::AcpiV1, size: size_of::<Self>().try_into().unwrap(),
43+
signature, checksum, oem_id, revision, rsdt_address,
44+
}
45+
}
46+
3247
/// The "RSD PTR " marker singature.
3348
///
3449
/// This is originally a 8-byte C string (not null terminated!) that must contain "RSD PTR "
@@ -62,6 +77,13 @@ impl RsdpV1Tag {
6277
}
6378
}
6479

80+
#[cfg(feature = "builder")]
81+
impl StructAsBytes for RsdpV1Tag {
82+
fn byte_size(&self) -> usize {
83+
size_of::<Self>()
84+
}
85+
}
86+
6587
/// This tag contains a copy of RSDP as defined per ACPI 2.0 or later specification.
6688
#[derive(Clone, Copy, Debug)]
6789
#[repr(C, packed)]
@@ -72,14 +94,26 @@ pub struct RsdpV2Tag {
7294
checksum: u8,
7395
oem_id: [u8; 6],
7496
revision: u8,
75-
_rsdt_address: u32,
97+
rsdt_address: u32,
7698
length: u32,
7799
xsdt_address: u64, // This is the PHYSICAL address of the XSDT
78100
ext_checksum: u8,
79101
_reserved: [u8; 3],
80102
}
81103

82104
impl RsdpV2Tag {
105+
#[cfg(feature = "builder")]
106+
pub fn new(
107+
signature: [u8; 8], checksum: u8, oem_id: [u8; 6], revision: u8,
108+
rsdt_address: u32, length: u32, xsdt_address: u64, ext_checksum: u8,
109+
) -> Self {
110+
Self {
111+
typ: TagType::AcpiV2, size: size_of::<Self>().try_into().unwrap(),
112+
signature, checksum, oem_id, revision, rsdt_address, length,
113+
xsdt_address, ext_checksum, _reserved: [0; 3],
114+
}
115+
}
116+
83117
/// The "RSD PTR " marker signature.
84118
///
85119
/// This is originally a 8-byte C string (not null terminated!) that must contain "RSD PTR ".
@@ -120,3 +154,10 @@ impl RsdpV2Tag {
120154
self.ext_checksum
121155
}
122156
}
157+
158+
#[cfg(feature = "builder")]
159+
impl StructAsBytes for RsdpV2Tag {
160+
fn byte_size(&self) -> usize {
161+
size_of::<Self>()
162+
}
163+
}

0 commit comments

Comments
 (0)