A bit more ABI work

This commit is contained in:
Artemis Tosini 2024-07-29 22:54:36 +00:00
parent 15bb412b83
commit bf71132cd0
Signed by: artemist
GPG key ID: EE5227935FE3FF18

View file

@ -17,8 +17,8 @@ impl EFIFramebufferParams {
pub fn from_graphics_output(graphics_output: &mut GraphicsOutput) -> Option<Self> { pub fn from_graphics_output(graphics_output: &mut GraphicsOutput) -> Option<Self> {
let mode = graphics_output.current_mode_info(); let mode = graphics_output.current_mode_info();
let (mask_red, mask_green, mask_blue, mask_reserved) = match mode.pixel_format() { let (mask_red, mask_green, mask_blue, mask_reserved) = match mode.pixel_format() {
PixelFormat::Rgb => (0x0000_00ff, 0x0000_ff00, 0x00ff_0000, 0xff00_000), PixelFormat::Rgb => (0x0000_00ff, 0x0000_ff00, 0x00ff_0000, 0xff00_0000),
PixelFormat::Bgr => (0x00ff_0000, 0x0000_ff00, 0x0000_00ff, 0xff00_000), PixelFormat::Bgr => (0x00ff_0000, 0x0000_ff00, 0x0000_00ff, 0xff00_0000),
PixelFormat::Bitmask => { PixelFormat::Bitmask => {
let bitmask = mode.pixel_bitmask()?; let bitmask = mode.pixel_bitmask()?;
(bitmask.red, bitmask.green, bitmask.blue, bitmask.reserved) (bitmask.red, bitmask.green, bitmask.blue, bitmask.reserved)
@ -45,34 +45,64 @@ impl EFIFramebufferParams {
} }
} }
#[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] /// Single TLV in the metadata buffer.
#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] /// In the FreeBSD kernel would be placed in `preload_metadata`
pub struct ModuleDirectoryElem<T> { pub enum PreloadDirectoryElem<'a> {
ident: ModInfo, /// Module name (MOD_NAME)
size: u32, Name(&'a str),
data: T, /// Module type (MOD_TYPE)
Type(&'a str),
/// Module parameters (MOD_ARGS)
Args(&'a str),
// TODO: figure out how to make this pointer safer
/// Module address (MOD_ADDR)
LoadAddress(*const u8),
/// Module size (MOD_SIZE)
Size(usize),
/// Type-speicfic metadata (MOD_METADATA)
Metadata(FileMetadataType, &'a [u8]),
End,
} }
impl<'a> PreloadDirectoryElem<'a> {
#[repr(C)] fn copy_str(data: &str, output: &mut [u8]) -> Option<u32> {
pub struct FileMetadataElem<T> { output[..data.len()].copy_from_slice(data.as_bytes());
size: usize, output[data.len()] = 0;
typ: FileMetadataType, data.len().checked_add(1)?.try_into().ok()
addr: *const T,
next: Option<*const FileMetadataElem<T>>,
data: T,
} }
#[repr(u32)] pub fn copy_to_output<'b>(&'a self, output: &'b mut [u8]) -> Option<&'b mut [u8]> {
pub enum ModInfo { let usize_size = core::mem::size_of::<usize>();
End = 0,
Name = 1, let (tag, length) = match self {
Type = 2, Self::Name(name) => (1u32, Self::copy_str(name, &mut output[8..])?),
Addr = 3, Self::Type(typ) => (2u32, Self::copy_str(typ, &mut output[8..])?),
Size = 4, Self::Args(args) => (6u32, Self::copy_str(args, &mut output[8..])?),
Args = 6, Self::LoadAddress(addr) => {
output[8..(8 + usize_size)].copy_from_slice(&(*addr as usize).to_ne_bytes());
(3u32, usize_size as u32)
}
Self::Size(size) => {
output[8..(8 + usize_size)].copy_from_slice(&size.to_ne_bytes());
(4u32, usize_size as u32)
}
Self::Metadata(typ, metadata) => {
output[8..(8 + metadata.len())].copy_from_slice(metadata);
(0x8000 | (*typ as u32), metadata.len() as u32)
}
Self::End => (0u32, 0u32),
};
output[..4].copy_from_slice(&tag.to_ne_bytes());
output[4..8].copy_from_slice(&length.to_ne_bytes());
let aligned_length = ((length as usize + usize_size - 1) / usize_size) * usize_size;
Some(&mut output[(aligned_length + 8)..])
}
} }
#[derive(Debug, Copy, Clone)]
#[repr(u16)] #[repr(u16)]
pub enum FileMetadataType { pub enum FileMetadataType {
AoutExecHeader = 1, AoutExecHeader = 1,