use core::{ops, slice};
#[derive(Debug)]
#[repr(C)]
#[non_exhaustive]
pub struct BootInfo {
pub version_major: u16,
pub version_minor: u16,
pub version_patch: u16,
pub pre_release: bool,
pub memory_regions: MemoryRegions,
pub framebuffer: Optional<FrameBuffer>,
pub physical_memory_offset: Optional<u64>,
pub recursive_index: Optional<u16>,
pub rsdp_addr: Optional<u64>,
pub tls_template: Optional<TlsTemplate>,
}
#[derive(Debug)]
#[repr(C)]
pub struct MemoryRegions {
pub(crate) ptr: *mut MemoryRegion,
pub(crate) len: usize,
}
impl ops::Deref for MemoryRegions {
type Target = [MemoryRegion];
fn deref(&self) -> &Self::Target {
unsafe { slice::from_raw_parts(self.ptr, self.len) }
}
}
impl ops::DerefMut for MemoryRegions {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { slice::from_raw_parts_mut(self.ptr, self.len) }
}
}
impl From<&'static mut [MemoryRegion]> for MemoryRegions {
fn from(regions: &'static mut [MemoryRegion]) -> Self {
MemoryRegions {
ptr: regions.as_mut_ptr(),
len: regions.len(),
}
}
}
impl From<MemoryRegions> for &'static mut [MemoryRegion] {
fn from(regions: MemoryRegions) -> &'static mut [MemoryRegion] {
unsafe { slice::from_raw_parts_mut(regions.ptr, regions.len) }
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(C)]
pub struct MemoryRegion {
pub start: u64,
pub end: u64,
pub kind: MemoryRegionKind,
}
impl MemoryRegion {
pub const fn empty() -> Self {
MemoryRegion {
start: 0,
end: 0,
kind: MemoryRegionKind::Bootloader,
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[non_exhaustive]
#[repr(C)]
pub enum MemoryRegionKind {
Usable,
Bootloader,
UnknownUefi(u32),
UnknownBios(u32),
}
#[derive(Debug)]
#[repr(C)]
pub struct FrameBuffer {
pub(crate) buffer_start: u64,
pub(crate) buffer_byte_len: usize,
pub(crate) info: FrameBufferInfo,
}
impl FrameBuffer {
pub fn buffer(&self) -> &[u8] {
unsafe { self.create_buffer() }
}
pub fn buffer_mut(&mut self) -> &mut [u8] {
unsafe { self.create_buffer() }
}
unsafe fn create_buffer<'a>(&self) -> &'a mut [u8] {
unsafe { slice::from_raw_parts_mut(self.buffer_start as *mut u8, self.buffer_byte_len) }
}
pub fn info(&self) -> FrameBufferInfo {
self.info
}
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FrameBufferInfo {
pub byte_len: usize,
pub horizontal_resolution: usize,
pub vertical_resolution: usize,
pub pixel_format: PixelFormat,
pub bytes_per_pixel: usize,
pub stride: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
#[repr(C)]
pub enum PixelFormat {
RGB,
BGR,
U8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)]
pub struct TlsTemplate {
pub start_addr: u64,
pub file_size: u64,
pub mem_size: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C)]
pub enum Optional<T> {
Some(T),
None,
}
impl<T> Optional<T> {
pub fn into_option(self) -> Option<T> {
self.into()
}
pub const fn as_ref(&self) -> Option<&T> {
match self {
Self::Some(x) => Some(x),
Self::None => None,
}
}
pub fn as_mut(&mut self) -> Option<&mut T> {
match self {
Self::Some(x) => Some(x),
Self::None => None,
}
}
}
impl<T> From<Option<T>> for Optional<T> {
fn from(v: Option<T>) -> Self {
match v {
Some(v) => Optional::Some(v),
None => Optional::None,
}
}
}
impl<T> From<Optional<T>> for Option<T> {
fn from(optional: Optional<T>) -> Option<T> {
match optional {
Optional::Some(v) => Some(v),
Optional::None => None,
}
}
}
extern "C" fn _assert_ffi(_boot_info: BootInfo) {}