Skip to main content

multiboot2_header/
information_request.rs

1use crate::{HeaderTagFlag, HeaderTagHeader};
2use crate::{HeaderTagType, MbiTagTypeId};
3use core::fmt;
4use core::fmt::{Debug, Formatter};
5#[cfg(feature = "builder")]
6use multiboot2_common::new_boxed;
7use multiboot2_common::{MaybeDynSized, Tag};
8#[cfg(feature = "builder")]
9use {alloc::boxed::Box, core::slice};
10
11/// Specifies what specific tag types the bootloader should provide
12/// inside the mbi.
13#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, ptr_meta::Pointee)]
14#[repr(C, align(8))]
15pub struct InformationRequestHeaderTag {
16    header: HeaderTagHeader,
17    requests: [MbiTagTypeId],
18}
19
20impl InformationRequestHeaderTag {
21    /// Creates a new object.
22    #[cfg(feature = "builder")]
23    #[must_use]
24    pub fn new(flags: HeaderTagFlag, requests: &[MbiTagTypeId]) -> Box<Self> {
25        let header = HeaderTagHeader::new(HeaderTagType::InformationRequest, flags, 0);
26        // SAFETY: The memory we are using is valid.
27        let requests = unsafe {
28            let ptr = &raw const *requests;
29            slice::from_raw_parts(ptr.cast::<u8>(), size_of_val(requests))
30        };
31        new_boxed(header, &[requests])
32    }
33
34    /// Returns the [`HeaderTagType`].
35    #[must_use]
36    pub const fn typ(&self) -> HeaderTagType {
37        self.header.typ()
38    }
39
40    /// Returns the [`HeaderTagFlag`]s.
41    #[must_use]
42    pub const fn flags(&self) -> HeaderTagFlag {
43        self.header.flags()
44    }
45
46    /// Returns the size.
47    #[must_use]
48    pub const fn size(&self) -> u32 {
49        self.header.size()
50    }
51
52    /// Returns the requests as array
53    #[must_use]
54    pub const fn requests(&self) -> &[MbiTagTypeId] {
55        &self.requests
56    }
57}
58
59impl Debug for InformationRequestHeaderTag {
60    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
61        f.debug_struct("InformationRequestHeaderTag")
62            .field("type", &self.typ())
63            .field("flags", &self.flags())
64            .field("size", &self.size())
65            .field("requests", &self.requests())
66            .finish()
67    }
68}
69
70impl MaybeDynSized for InformationRequestHeaderTag {
71    type Header = HeaderTagHeader;
72
73    const BASE_SIZE: usize = size_of::<HeaderTagHeader>();
74
75    fn dst_len(header: &Self::Header) -> Self::Metadata {
76        let dst_size = header.size() as usize - Self::BASE_SIZE;
77        assert_eq!(dst_size % size_of::<MbiTagTypeId>(), 0);
78        dst_size / size_of::<MbiTagTypeId>()
79    }
80}
81
82impl Tag for InformationRequestHeaderTag {
83    type IDType = HeaderTagType;
84    const ID: HeaderTagType = HeaderTagType::InformationRequest;
85}
86
87#[cfg(test)]
88#[cfg(feature = "builder")]
89mod tests {
90    use super::*;
91    use crate::MbiTagType;
92
93    #[test]
94    fn creation() {
95        // Main objective here is to satisfy Miri.
96        let _ir = InformationRequestHeaderTag::new(
97            HeaderTagFlag::Optional,
98            &[
99                MbiTagType::Cmdline.into(),
100                MbiTagType::BootLoaderName.into(),
101                MbiTagType::Module.into(),
102                MbiTagType::BasicMeminfo.into(),
103                MbiTagType::Bootdev.into(),
104                MbiTagType::Mmap.into(),
105                MbiTagType::Vbe.into(),
106                MbiTagType::Framebuffer.into(),
107                MbiTagType::ElfSections.into(),
108                MbiTagType::Apm.into(),
109                MbiTagType::Efi32.into(),
110                MbiTagType::Efi64.into(),
111                MbiTagType::Smbios.into(),
112                MbiTagType::AcpiV1.into(),
113                MbiTagType::AcpiV2.into(),
114                MbiTagType::Network.into(),
115                MbiTagType::EfiMmap.into(),
116                MbiTagType::EfiBs.into(),
117                MbiTagType::Efi32Ih.into(),
118                MbiTagType::Efi64Ih.into(),
119                MbiTagType::LoadBaseAddr.into(),
120                MbiTagType::Custom(0x1337).into(),
121            ],
122        );
123    }
124}