use crate::mm::{Paddr, paddr_to_vaddr};
macro_rules! efi_guid {
($a:expr, $b:expr, $c:expr, $d:expr) => {{
let a = ($a as u32).to_le_bytes(); let b = ($b as u16).to_le_bytes(); let c = ($c as u16).to_le_bytes(); let d = $d;
EfiGuid {
b: [
a[0], a[1], a[2], a[3], b[0], b[1], c[0], c[1], d[0], d[1], d[2], d[3], d[4], d[5],
d[6], d[7],
],
}
}};
}
const LINUX_EFI_INITRD_MEDIA_GUID: EfiGuid = efi_guid!(
0x5568e427,
0x68fc,
0x4f3d,
[0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68]
);
const DEVICE_TREE_GUID: EfiGuid = efi_guid!(
0xb1b621d5,
0xf19c,
0x41a5,
[0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0]
);
#[repr(C)]
#[derive(Debug, Eq, PartialEq)]
struct EfiGuid {
b: [u8; 16],
}
#[repr(C)]
struct EfiTableHeader {
signature: u64,
revision: u32,
headersize: u32,
crc32: u32,
reserved: u32,
}
#[repr(C)]
struct EfiConfigurationTable {
guid: EfiGuid,
table: *const core::ffi::c_void,
}
#[repr(C)]
pub(super) struct EfiSystemTable {
hdr: EfiTableHeader,
fw_vendor: u64, fw_revision: u32,
con_in_handle: u64,
con_in: *const u64,
con_out_handle: u64,
con_out: *const u64,
stderr_handle: u64,
stderr_placeholder: u64,
runtime: *const u64,
boottime: *const u64,
nr_tables: u64,
tables: *const EfiConfigurationTable,
}
unsafe impl Sync for EfiSystemTable {}
impl EfiSystemTable {
fn table(&self, guid: &EfiGuid) -> Option<&EfiConfigurationTable> {
for i in 0..self.nr_tables as usize {
let table = unsafe {
&*(paddr_to_vaddr(self.tables.add(i) as _) as *const EfiConfigurationTable)
};
if table.guid == *guid {
return Some(table);
}
}
None
}
pub(super) fn initrd(&self) -> Option<&EfiInitrd> {
let table = self.table(&LINUX_EFI_INITRD_MEDIA_GUID)?;
Some(unsafe { &*(paddr_to_vaddr(table.table as _) as *const EfiInitrd) })
}
pub(super) fn device_tree(&self) -> Option<Paddr> {
let table = self.table(&DEVICE_TREE_GUID)?;
Some(table.table as _)
}
}
#[repr(C)]
pub(super) struct EfiInitrd {
base: u64,
size: u64,
}
impl EfiInitrd {
pub(super) fn range(&self) -> Option<(usize, usize)> {
if self.size == 0 {
None
} else {
Some((self.base as _, (self.base + self.size) as _))
}
}
}