use crate::TagType;
use crate::tag::TagHeader;
use core::mem::size_of;
use multiboot2_common::{MaybeDynSized, Tag};
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C, align(8))]
pub struct EFISdt32Tag {
header: TagHeader,
pointer: u32,
}
impl EFISdt32Tag {
const BASE_SIZE: usize = size_of::<TagHeader>() + size_of::<u32>();
#[must_use]
pub fn new(pointer: u32) -> Self {
Self {
header: TagHeader::new(Self::ID, Self::BASE_SIZE as u32),
pointer,
}
}
#[must_use]
pub const fn sdt_address(&self) -> usize {
self.pointer as usize
}
}
impl MaybeDynSized for EFISdt32Tag {
type Header = TagHeader;
const BASE_SIZE: usize = size_of::<Self>();
fn dst_len(_: &TagHeader) {}
}
impl Tag for EFISdt32Tag {
type IDType = TagType;
const ID: TagType = TagType::Efi32;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C, align(8))]
pub struct EFISdt64Tag {
header: TagHeader,
pointer: u64,
}
impl EFISdt64Tag {
#[must_use]
pub fn new(pointer: u64) -> Self {
Self {
header: TagHeader::new(Self::ID, size_of::<Self>().try_into().unwrap()),
pointer,
}
}
#[must_use]
pub const fn sdt_address(&self) -> usize {
self.pointer as usize
}
}
impl MaybeDynSized for EFISdt64Tag {
type Header = TagHeader;
const BASE_SIZE: usize = size_of::<Self>();
fn dst_len(_: &TagHeader) {}
}
impl Tag for EFISdt64Tag {
type IDType = TagType;
const ID: TagType = TagType::Efi64;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C, align(8))]
pub struct EFIImageHandle32Tag {
header: TagHeader,
pointer: u32,
}
impl EFIImageHandle32Tag {
const BASE_SIZE: usize = size_of::<TagHeader>() + size_of::<u32>();
#[must_use]
pub fn new(pointer: u32) -> Self {
Self {
header: TagHeader::new(Self::ID, Self::BASE_SIZE as u32),
pointer,
}
}
#[must_use]
pub const fn image_handle(&self) -> usize {
self.pointer as usize
}
}
impl MaybeDynSized for EFIImageHandle32Tag {
type Header = TagHeader;
const BASE_SIZE: usize = size_of::<Self>();
fn dst_len(_: &TagHeader) {}
}
impl Tag for EFIImageHandle32Tag {
type IDType = TagType;
const ID: TagType = TagType::Efi32Ih;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C, align(8))]
pub struct EFIImageHandle64Tag {
header: TagHeader,
pointer: u64,
}
impl EFIImageHandle64Tag {
#[must_use]
pub fn new(pointer: u64) -> Self {
Self {
header: TagHeader::new(Self::ID, size_of::<Self>().try_into().unwrap()),
pointer,
}
}
#[must_use]
pub const fn image_handle(&self) -> usize {
self.pointer as usize
}
}
impl MaybeDynSized for EFIImageHandle64Tag {
type Header = TagHeader;
const BASE_SIZE: usize = size_of::<Self>();
fn dst_len(_: &TagHeader) {}
}
impl Tag for EFIImageHandle64Tag {
type IDType = TagType;
const ID: TagType = TagType::Efi64Ih;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C, align(8))]
pub struct EFIBootServicesNotExitedTag {
header: TagHeader,
}
impl EFIBootServicesNotExitedTag {
#[must_use]
pub fn new() -> Self {
Self::default()
}
}
impl Default for EFIBootServicesNotExitedTag {
fn default() -> Self {
Self {
header: TagHeader::new(Self::ID, size_of::<Self>().try_into().unwrap()),
}
}
}
impl MaybeDynSized for EFIBootServicesNotExitedTag {
type Header = TagHeader;
const BASE_SIZE: usize = size_of::<Self>();
fn dst_len(_: &TagHeader) {}
}
impl Tag for EFIBootServicesNotExitedTag {
type IDType = TagType;
const ID: TagType = TagType::EfiBs;
}
#[cfg(all(test, feature = "builder"))]
mod tests {
use super::{EFIImageHandle32Tag, EFIImageHandle64Tag, EFISdt32Tag, EFISdt64Tag};
use crate::{EFIMemoryDesc, EFIMemoryMapTag};
use uefi_raw::table::boot::{MemoryAttribute, MemoryType};
const ADDR: usize = 0xABCDEF;
#[test]
fn test_build_eftsdt32() {
let tag = EFISdt32Tag::new(ADDR.try_into().unwrap());
assert_eq!(tag.sdt_address(), ADDR);
}
#[test]
fn test_build_eftsdt64() {
let tag = EFISdt64Tag::new(ADDR.try_into().unwrap());
assert_eq!(tag.sdt_address(), ADDR);
}
#[test]
fn test_build_eftih32() {
let tag = EFIImageHandle32Tag::new(ADDR.try_into().unwrap());
assert_eq!(tag.image_handle(), ADDR);
}
#[test]
fn test_build_eftih64() {
let tag = EFIImageHandle64Tag::new(ADDR.try_into().unwrap());
assert_eq!(tag.image_handle(), ADDR);
}
#[test]
fn test_construct_efi_mmap_tag() {
let tag = EFIMemoryMapTag::new_from_descs(&[
EFIMemoryDesc {
ty: MemoryType::BOOT_SERVICES_CODE,
phys_start: 0x1000,
virt_start: 0x1000,
page_count: 1,
att: MemoryAttribute::WRITE_COMBINE,
},
EFIMemoryDesc {
ty: MemoryType::LOADER_DATA,
phys_start: 0x2000,
virt_start: 0x2000,
page_count: 2,
att: MemoryAttribute::NON_VOLATILE,
},
]);
dbg!(tag);
}
}