159 lines
4.1 KiB
Rust
Executable File
159 lines
4.1 KiB
Rust
Executable File
pub mod allocator;
|
|
pub mod pmm;
|
|
|
|
use crate::{
|
|
libs::{cell::OnceCell, sync::Mutex},
|
|
// LogLevel,
|
|
};
|
|
|
|
use self::{allocator::LinkedListAllocator, pmm::PhysicalMemoryManager};
|
|
|
|
#[used]
|
|
#[link_section = ".requests"]
|
|
static mut MEMMAP_REQUEST: limine::request::MemoryMapRequest =
|
|
limine::request::MemoryMapRequest::new();
|
|
|
|
#[used]
|
|
#[link_section = ".requests"]
|
|
static HHDM_REQUEST: limine::request::HhdmRequest = limine::request::HhdmRequest::new();
|
|
pub static HHDM_OFFSET: OnceCell<usize> = OnceCell::new();
|
|
|
|
pub static PHYSICAL_MEMORY_MANAGER: OnceCell<PhysicalMemoryManager> = OnceCell::new();
|
|
|
|
pub fn align_up(addr: usize, align: usize) -> usize {
|
|
let offset = (addr as *const u8).align_offset(align);
|
|
addr + offset
|
|
}
|
|
|
|
const HEAP_PAGES: usize = 1024; // 4 MiB heap
|
|
|
|
#[global_allocator]
|
|
pub static ALLOCATOR: Mutex<LinkedListAllocator> = Mutex::new(LinkedListAllocator::new());
|
|
|
|
// TODO: Limine-rs 0.2.0 does NOT have debug implemented for a lot of it's types, so until that is fixed, either go without Type, or hack limine-rs locally
|
|
// pub fn log_memory_map() {
|
|
// let memmap_request = unsafe { MEMMAP_REQUEST.get_response_mut() };
|
|
// if memmap_request.is_none() {
|
|
// panic!("Memory map was None!");
|
|
// }
|
|
|
|
// let memmap = memmap_request.unwrap().entries();
|
|
|
|
// crate::log!(LogLevel::Trace, "====== MEMORY MAP ======");
|
|
// for entry in memmap.iter() {
|
|
// let label = (entry.length as usize).label_bytes();
|
|
|
|
// crate::log!(
|
|
// LogLevel::Trace,
|
|
// "[ {:#018X?} ] Type: {:?} Size: {}",
|
|
// entry.base..entry.base + entry.length,
|
|
// entry.entry_type,
|
|
// label
|
|
// )
|
|
// }
|
|
// }
|
|
|
|
pub fn init_allocator() {
|
|
let mut allocator_lock = ALLOCATOR.lock();
|
|
allocator_lock.init(HEAP_PAGES);
|
|
|
|
drop(allocator_lock);
|
|
|
|
// log_memory_map();
|
|
}
|
|
|
|
pub enum ByteLabelKind {
|
|
BYTE,
|
|
KIB,
|
|
MIB,
|
|
GIB,
|
|
}
|
|
|
|
pub struct ByteLabel {
|
|
byte_label: ByteLabelKind,
|
|
count: usize,
|
|
}
|
|
|
|
impl core::fmt::Display for ByteLabel {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
let size = self.count;
|
|
|
|
match self.byte_label {
|
|
ByteLabelKind::BYTE => {
|
|
write!(f, "{size} Byte")?;
|
|
}
|
|
ByteLabelKind::KIB => {
|
|
write!(f, "{size} KiB")?;
|
|
}
|
|
ByteLabelKind::MIB => {
|
|
write!(f, "{size} MiB")?;
|
|
}
|
|
ByteLabelKind::GIB => {
|
|
write!(f, "{size} GiB")?;
|
|
}
|
|
}
|
|
|
|
if size != 1 {
|
|
write!(f, "s")?;
|
|
}
|
|
|
|
return Ok(());
|
|
}
|
|
}
|
|
pub trait LabelBytes {
|
|
fn label_bytes(&self) -> ByteLabel;
|
|
}
|
|
|
|
impl LabelBytes for usize {
|
|
fn label_bytes(&self) -> ByteLabel {
|
|
let bytes = *self;
|
|
|
|
let mut byte_label = ByteLabel {
|
|
byte_label: ByteLabelKind::BYTE,
|
|
count: bytes,
|
|
};
|
|
|
|
if bytes >> 30 > 0 {
|
|
byte_label.byte_label = ByteLabelKind::GIB;
|
|
byte_label.count = bytes >> 30;
|
|
// return Label::GIB(bytes >> 30);
|
|
} else if bytes >> 20 > 0 {
|
|
byte_label.byte_label = ByteLabelKind::MIB;
|
|
byte_label.count = bytes >> 20;
|
|
// return Label::MIB(bytes >> 20);
|
|
} else if bytes >> 10 > 0 {
|
|
byte_label.byte_label = ByteLabelKind::KIB;
|
|
byte_label.count = bytes >> 10;
|
|
// return Label::KIB(bytes >> 10);
|
|
}
|
|
|
|
return byte_label;
|
|
}
|
|
}
|
|
|
|
/// # Safety
|
|
/// This will produce undefined behavior if dst is not valid for count writes
|
|
pub unsafe fn memset32(dst: *mut u32, val: u32, count: usize) {
|
|
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
|
{
|
|
let mut buf = dst;
|
|
unsafe {
|
|
while buf < dst.add(count) {
|
|
core::ptr::write_volatile(buf, val);
|
|
buf = buf.offset(1);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
|
{
|
|
core::arch::asm!(
|
|
"rep stosd",
|
|
inout("ecx") count => _,
|
|
inout("edi") dst => _,
|
|
inout("eax") val => _
|
|
);
|
|
}
|
|
}
|