Skip to content

Commit 150cc13

Browse files
committed
multiboot2: add ApmTag
1 parent fd4923f commit 150cc13

File tree

4 files changed

+135
-1
lines changed

4 files changed

+135
-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

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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+
pub fn new(
26+
version: u16,
27+
cseg: u16,
28+
offset: u32,
29+
cset_16: u16,
30+
dset: u16,
31+
flags: u16,
32+
cseg_len: u16,
33+
cseg_16_len: u16,
34+
dseg_len: u16,
35+
) -> Self {
36+
Self {
37+
header: TagHeader::new(TagType::Apm, mem::size_of::<Self>() as u32),
38+
version,
39+
cseg,
40+
offset,
41+
cset_16,
42+
dseg: dset,
43+
flags,
44+
cseg_len,
45+
cseg_16_len,
46+
dseg_len,
47+
}
48+
}
49+
50+
/// The version number of the APM BIOS.
51+
pub const fn version(&self) -> u16 {
52+
self.version
53+
}
54+
55+
/// Contains the 16-bit code segment (CS) address for the APM entry point.
56+
pub const fn cseg(&self) -> u16 {
57+
self.cseg
58+
}
59+
60+
/// Represents the offset address within the code segment (`cseg`) for the
61+
/// APM entry point.
62+
pub const fn offset(&self) -> u32 {
63+
self.offset
64+
}
65+
66+
/// Contains the 16-bit code segment (CS) address used for 16-bit protected
67+
/// mode APM functions.
68+
pub const fn cset_16(&self) -> u16 {
69+
self.cset_16
70+
}
71+
72+
/// Holds the 16-bit data segment (DS) address used by the APM BIOS for
73+
/// data operations.
74+
pub const fn dseg(&self) -> u16 {
75+
self.dseg
76+
}
77+
78+
/// Indicates the status and characteristics of the APM connection, such as
79+
/// if APM is present and its capabilities.
80+
pub const fn flags(&self) -> u16 {
81+
self.flags
82+
}
83+
84+
/// Indicates the length, in bytes, of the data segment (`dseg`) used by
85+
/// the APM BIOS
86+
pub const fn cseg_len(&self) -> u16 {
87+
self.cseg_len
88+
}
89+
90+
/// Provides the length, in bytes, of the 16-bit code segment (`cseg_16`)
91+
/// used for APM functions.
92+
pub const fn cseg_16_len(&self) -> u16 {
93+
self.cseg_16_len
94+
}
95+
96+
/// Indicates the length, in bytes, of the data segment (`dseg`) used by
97+
/// the APM BIOS.
98+
pub const fn dseg_len(&self) -> u16 {
99+
self.dseg_len
100+
}
101+
}
102+
103+
impl MaybeDynSized for ApmTag {
104+
type Header = TagHeader;
105+
106+
const BASE_SIZE: usize = mem::size_of::<Self>();
107+
108+
fn dst_len(_: &TagHeader) {}
109+
}
110+
111+
impl Tag for ApmTag {
112+
type IDType = TagType;
113+
114+
const ID: TagType = TagType::Apm;
115+
}

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)