A bit more ABI work
This commit is contained in:
parent
15bb412b83
commit
bf71132cd0
80
src/abi.rs
80
src/abi.rs
|
@ -17,8 +17,8 @@ impl EFIFramebufferParams {
|
|||
pub fn from_graphics_output(graphics_output: &mut GraphicsOutput) -> Option<Self> {
|
||||
let mode = graphics_output.current_mode_info();
|
||||
let (mask_red, mask_green, mask_blue, mask_reserved) = match mode.pixel_format() {
|
||||
PixelFormat::Rgb => (0x0000_00ff, 0x0000_ff00, 0x00ff_0000, 0xff00_000),
|
||||
PixelFormat::Bgr => (0x00ff_0000, 0x0000_ff00, 0x0000_00ff, 0xff00_000),
|
||||
PixelFormat::Rgb => (0x0000_00ff, 0x0000_ff00, 0x00ff_0000, 0xff00_0000),
|
||||
PixelFormat::Bgr => (0x00ff_0000, 0x0000_ff00, 0x0000_00ff, 0xff00_0000),
|
||||
PixelFormat::Bitmask => {
|
||||
let bitmask = mode.pixel_bitmask()?;
|
||||
(bitmask.red, bitmask.green, bitmask.blue, bitmask.reserved)
|
||||
|
@ -45,34 +45,64 @@ impl EFIFramebufferParams {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(target_pointer_width = "64", repr(C, align(8)))]
|
||||
#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))]
|
||||
pub struct ModuleDirectoryElem<T> {
|
||||
ident: ModInfo,
|
||||
size: u32,
|
||||
data: T,
|
||||
/// Single TLV in the metadata buffer.
|
||||
/// In the FreeBSD kernel would be placed in `preload_metadata`
|
||||
pub enum PreloadDirectoryElem<'a> {
|
||||
/// Module name (MOD_NAME)
|
||||
Name(&'a str),
|
||||
/// 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> {
|
||||
fn copy_str(data: &str, output: &mut [u8]) -> Option<u32> {
|
||||
output[..data.len()].copy_from_slice(data.as_bytes());
|
||||
output[data.len()] = 0;
|
||||
data.len().checked_add(1)?.try_into().ok()
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FileMetadataElem<T> {
|
||||
size: usize,
|
||||
typ: FileMetadataType,
|
||||
addr: *const T,
|
||||
next: Option<*const FileMetadataElem<T>>,
|
||||
data: T,
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
pub enum ModInfo {
|
||||
End = 0,
|
||||
Name = 1,
|
||||
Type = 2,
|
||||
Addr = 3,
|
||||
Size = 4,
|
||||
Args = 6,
|
||||
pub fn copy_to_output<'b>(&'a self, output: &'b mut [u8]) -> Option<&'b mut [u8]> {
|
||||
let usize_size = core::mem::size_of::<usize>();
|
||||
|
||||
let (tag, length) = match self {
|
||||
Self::Name(name) => (1u32, Self::copy_str(name, &mut output[8..])?),
|
||||
Self::Type(typ) => (2u32, Self::copy_str(typ, &mut output[8..])?),
|
||||
Self::Args(args) => (6u32, Self::copy_str(args, &mut output[8..])?),
|
||||
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)]
|
||||
pub enum FileMetadataType {
|
||||
AoutExecHeader = 1,
|
||||
|
|
Loading…
Reference in a new issue