Skip to content

Commit 17e48f8

Browse files
committed
multiboot2: add ApmTag
1 parent 7694432 commit 17e48f8

File tree

4 files changed

+146
-1
lines changed

4 files changed

+146
-1
lines changed

multiboot2/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
- dependency updates
66
- **Breaking:** MSRV is now 1.75
7+
- Added missing tags:
8+
- `ApmTag`
79

810
## v0.22.2 (2024-08-24)
911

multiboot2/src/apm.rs

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//! Module for [`ApmTag`].
2+
3+
use crate::{TagHeader, TagType};
4+
use core::mem;
5+
use multiboot2_common::{MaybeDynSized, Tag};
6+
7+
/// The Advanced Power Management (APM) tag.
8+
#[derive(Debug)]
9+
#[repr(C, align(8))]
10+
pub struct ApmTag {
11+
header: TagHeader,
12+
version: u16,
13+
cseg: u16,
14+
offset: u32,
15+
cset_16: u16,
16+
dseg: u16,
17+
flags: u16,
18+
cseg_len: u16,
19+
cseg_16_len: u16,
20+
dseg_len: u16,
21+
}
22+
23+
impl ApmTag {
24+
/// Creates a new tag.
25+
#[allow(clippy::too_many_arguments)]
26+
#[must_use]
27+
pub fn new(
28+
version: u16,
29+
cseg: u16,
30+
offset: u32,
31+
cset_16: u16,
32+
dset: u16,
33+
flags: u16,
34+
cseg_len: u16,
35+
cseg_16_len: u16,
36+
dseg_len: u16,
37+
) -> Self {
38+
Self {
39+
header: TagHeader::new(TagType::Apm, mem::size_of::<Self>() as u32),
40+
version,
41+
cseg,
42+
offset,
43+
cset_16,
44+
dseg: dset,
45+
flags,
46+
cseg_len,
47+
cseg_16_len,
48+
dseg_len,
49+
}
50+
}
51+
52+
/// The version number of the APM BIOS.
53+
#[must_use]
54+
pub const fn version(&self) -> u16 {
55+
self.version
56+
}
57+
58+
/// Contains the 16-bit code segment (CS) address for the APM entry point.
59+
#[must_use]
60+
pub const fn cseg(&self) -> u16 {
61+
self.cseg
62+
}
63+
64+
/// Represents the offset address within the code segment (`cseg`) for the
65+
/// APM entry point.
66+
#[must_use]
67+
pub const fn offset(&self) -> u32 {
68+
self.offset
69+
}
70+
71+
/// Contains the 16-bit code segment (CS) address used for 16-bit protected
72+
/// mode APM functions.
73+
#[must_use]
74+
pub const fn cset_16(&self) -> u16 {
75+
self.cset_16
76+
}
77+
78+
/// Holds the 16-bit data segment (DS) address used by the APM BIOS for
79+
/// data operations.
80+
#[must_use]
81+
pub const fn dseg(&self) -> u16 {
82+
self.dseg
83+
}
84+
85+
/// Indicates the status and characteristics of the APM connection, such as
86+
/// if APM is present and its capabilities.
87+
#[must_use]
88+
pub const fn flags(&self) -> u16 {
89+
self.flags
90+
}
91+
92+
/// Indicates the length, in bytes, of the data segment (`dseg`) used by
93+
/// the APM BIOS
94+
#[must_use]
95+
pub const fn cseg_len(&self) -> u16 {
96+
self.cseg_len
97+
}
98+
99+
/// Provides the length, in bytes, of the 16-bit code segment (`cseg_16`)
100+
/// used for APM functions.
101+
#[must_use]
102+
pub const fn cseg_16_len(&self) -> u16 {
103+
self.cseg_16_len
104+
}
105+
106+
/// Indicates the length, in bytes, of the data segment (`dseg`) used by
107+
/// the APM BIOS.
108+
#[must_use]
109+
pub const fn dseg_len(&self) -> u16 {
110+
self.dseg_len
111+
}
112+
}
113+
114+
impl MaybeDynSized for ApmTag {
115+
type Header = TagHeader;
116+
117+
const BASE_SIZE: usize = mem::size_of::<Self>();
118+
119+
fn dst_len(_: &TagHeader) {}
120+
}
121+
122+
impl Tag for ApmTag {
123+
type IDType = TagType;
124+
125+
const ID: TagType = TagType::Apm;
126+
}

multiboot2/src/builder.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Module for [`Builder`].
22
3+
use crate::apm::ApmTag;
34
use crate::{
45
BasicMemoryInfoTag, BootInformationHeader, BootLoaderNameTag, CommandLineTag,
56
EFIBootServicesNotExitedTag, EFIImageHandle32Tag, EFIImageHandle64Tag, EFIMemoryMapTag,
@@ -23,7 +24,7 @@ pub struct Builder {
2324
vbe: Option<VBEInfoTag>,
2425
framebuffer: Option<Box<FramebufferTag>>,
2526
elf_sections: Option<Box<ElfSectionsTag>>,
26-
// missing apm:
27+
apm: Option<ApmTag>,
2728
efi32: Option<EFISdt32Tag>,
2829
efi64: Option<EFISdt64Tag>,
2930
smbios: Vec<Box<SmbiosTag>>,
@@ -57,6 +58,7 @@ impl Builder {
5758
vbe: None,
5859
framebuffer: None,
5960
elf_sections: None,
61+
apm: None,
6062
efi32: None,
6163
efi64: None,
6264
smbios: vec![],
@@ -127,6 +129,13 @@ impl Builder {
127129
self
128130
}
129131

132+
/// Sets the [`ApmTag`] tag.
133+
#[must_use]
134+
pub fn apm(mut self, apm: ApmTag) -> Self {
135+
self.apm = Some(apm);
136+
self
137+
}
138+
130139
/// Sets the [`EFISdt32Tag`] tag.
131140
#[must_use]
132141
pub const fn efi32(mut self, efi32: EFISdt32Tag) -> Self {
@@ -214,6 +223,9 @@ impl Builder {
214223
pub fn build(self) -> Box<DynSizedStructure<BootInformationHeader>> {
215224
let header = BootInformationHeader::new(0);
216225
let mut byte_refs = Vec::new();
226+
if let Some(tag) = self.apm.as_ref() {
227+
byte_refs.push(tag.as_bytes().as_ref());
228+
}
217229
if let Some(tag) = self.cmdline.as_ref() {
218230
byte_refs.push(tag.as_bytes().as_ref());
219231
}
@@ -238,6 +250,9 @@ impl Builder {
238250
if let Some(tag) = self.elf_sections.as_ref() {
239251
byte_refs.push(tag.as_bytes().as_ref());
240252
}
253+
if let Some(tag) = self.apm.as_ref() {
254+
byte_refs.push(tag.as_bytes().as_ref());
255+
}
241256
if let Some(tag) = self.efi32.as_ref() {
242257
byte_refs.push(tag.as_bytes().as_ref());
243258
}

multiboot2/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub type TagIter<'a> = multiboot2_common::TagIter<'a, TagHeader>;
6666
#[cfg(test)]
6767
pub type GenericInfoTag = multiboot2_common::DynSizedStructure<TagHeader>;
6868

69+
mod apm;
6970
mod boot_information;
7071
mod boot_loader_name;
7172
mod command_line;
@@ -85,6 +86,7 @@ mod vbe_info;
8586

8687
pub use multiboot2_common::{DynSizedStructure, MaybeDynSized, Tag};
8788

89+
pub use apm::ApmTag;
8890
pub use boot_information::{BootInformation, BootInformationHeader, LoadError};
8991
pub use boot_loader_name::BootLoaderNameTag;
9092
#[cfg(feature = "builder")]

0 commit comments

Comments
 (0)