Skip to content

Commit

Permalink
refactor(riscv64): migrate to free-list crate
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Kröning <martin.kroening@eonerc.rwth-aachen.de>
  • Loading branch information
mkroening committed May 8, 2024
1 parent 25e1adb commit 0122fd6
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 31 deletions.
38 changes: 24 additions & 14 deletions src/arch/riscv64/mm/physicalmem.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use core::alloc::AllocError;
use core::convert::TryInto;
use core::sync::atomic::{AtomicUsize, Ordering};

use free_list::{AllocError, FreeList, PageLayout, PageRange};
use hermit_sync::InterruptSpinMutex;

use crate::arch::riscv64::kernel::{get_limit, get_ram_address};
use crate::arch::riscv64::mm::paging::{BasePageSize, PageSize};
use crate::arch::riscv64::mm::PhysAddr;
use crate::mm;
use crate::mm::freelist::{FreeList, FreeListEntry};

static PHYSICAL_FREE_LIST: InterruptSpinMutex<FreeList> = InterruptSpinMutex::new(FreeList::new());
static PHYSICAL_FREE_LIST: InterruptSpinMutex<FreeList<16>> =
InterruptSpinMutex::new(FreeList::new());
static TOTAL_MEMORY: AtomicUsize = AtomicUsize::new(0);

fn detect_from_limits() -> Result<(), ()> {
Expand All @@ -19,11 +19,14 @@ fn detect_from_limits() -> Result<(), ()> {
return Err(());
}

let entry = FreeListEntry::new(
let range = PageRange::new(
mm::kernel_end_address().as_usize(),
get_ram_address().as_usize() + limit,
);
PHYSICAL_FREE_LIST.lock().push(entry);
)
.unwrap();
unsafe {
PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap();
}
TOTAL_MEMORY.store(limit, Ordering::SeqCst);

Ok(())
Expand All @@ -47,10 +50,13 @@ pub fn allocate(size: usize) -> Result<PhysAddr, AllocError> {
BasePageSize::SIZE as usize
);

let layout = PageLayout::from_size(size).unwrap();

Ok(PhysAddr(
PHYSICAL_FREE_LIST
.lock()
.allocate(size, None)?
.allocate(layout)?
.start()
.try_into()
.unwrap(),
))
Expand All @@ -72,10 +78,13 @@ pub fn allocate_aligned(size: usize, align: usize) -> Result<PhysAddr, AllocErro
BasePageSize::SIZE as usize
);

let layout = PageLayout::from_size_align(size, align).unwrap();

Ok(PhysAddr(
PHYSICAL_FREE_LIST
.lock()
.allocate(size, Some(align))?
.allocate(layout)?
.start()
.try_into()
.unwrap(),
))
Expand All @@ -97,13 +106,14 @@ pub fn deallocate(physical_address: PhysAddr, size: usize) {
BasePageSize::SIZE as usize
);

PHYSICAL_FREE_LIST
.lock()
.deallocate(physical_address.as_usize(), size);
let range = PageRange::from_start_len(physical_address.as_usize(), size).unwrap();

unsafe {
PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap();
}
}

pub fn print_information() {
PHYSICAL_FREE_LIST
.lock()
.print_information(" PHYSICAL MEMORY FREE LIST ");
let free_list = PHYSICAL_FREE_LIST.lock();
info!("Physical memory free list:\n{free_list}");
}
42 changes: 26 additions & 16 deletions src/arch/riscv64/mm/virtualmem.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
use core::alloc::AllocError;
use core::convert::TryInto;

use align_address::Align;
use free_list::{AllocError, FreeList, PageLayout, PageRange};
use hermit_sync::InterruptSpinMutex;

use crate::arch::riscv64::kernel::get_ram_address;
use crate::arch::riscv64::mm::paging::{BasePageSize, HugePageSize, PageSize};
use crate::arch::riscv64::mm::{physicalmem, PhysAddr, VirtAddr};
use crate::mm;
use crate::mm::freelist::{FreeList, FreeListEntry};

static KERNEL_FREE_LIST: InterruptSpinMutex<FreeList> = InterruptSpinMutex::new(FreeList::new());
static KERNEL_FREE_LIST: InterruptSpinMutex<FreeList<16>> =
InterruptSpinMutex::new(FreeList::new());

/// End of the virtual memory address space reserved for kernel memory (256 GiB).
/// This also marks the start of the virtual memory address space reserved for the task heap.
const KERNEL_VIRTUAL_MEMORY_END: VirtAddr = VirtAddr(0x4000000000);

pub fn init() {
let entry = FreeListEntry {
start: (get_ram_address() + PhysAddr(physicalmem::total_memory_size() as u64))
let range = PageRange::new(
(get_ram_address() + PhysAddr(physicalmem::total_memory_size() as u64))
.as_usize()
.align_up(HugePageSize::SIZE as usize),
end: KERNEL_VIRTUAL_MEMORY_END.as_usize(),
};
KERNEL_FREE_LIST.lock().push(entry);
KERNEL_VIRTUAL_MEMORY_END.as_usize(),
)
.unwrap();
unsafe {
KERNEL_FREE_LIST.lock().deallocate(range).unwrap();
}
}

pub fn allocate(size: usize) -> Result<VirtAddr, AllocError> {
Expand All @@ -36,10 +39,13 @@ pub fn allocate(size: usize) -> Result<VirtAddr, AllocError> {
BasePageSize::SIZE as usize
);

let layout = PageLayout::from_size(size).unwrap();

Ok(VirtAddr(
KERNEL_FREE_LIST
.lock()
.allocate(size, None)?
.allocate(layout)?
.start()
.try_into()
.unwrap(),
))
Expand All @@ -61,10 +67,13 @@ pub fn allocate_aligned(size: usize, align: usize) -> Result<VirtAddr, AllocErro
BasePageSize::SIZE as usize
);

let layout = PageLayout::from_size_align(size, align).unwrap();

Ok(VirtAddr(
KERNEL_FREE_LIST
.lock()
.allocate(size, Some(align))?
.allocate(layout)?
.start()
.try_into()
.unwrap(),
))
Expand Down Expand Up @@ -95,9 +104,11 @@ pub fn deallocate(virtual_address: VirtAddr, size: usize) {
BasePageSize::SIZE as usize
);

KERNEL_FREE_LIST
.lock()
.deallocate(virtual_address.as_usize(), size);
let range = PageRange::from_start_len(virtual_address.as_usize(), size).unwrap();

unsafe {
KERNEL_FREE_LIST.lock().deallocate(range).unwrap();
}
}

/*pub fn reserve(virtual_address: VirtAddr, size: usize) {
Expand Down Expand Up @@ -137,7 +148,6 @@ pub fn deallocate(virtual_address: VirtAddr, size: usize) {
}*/

pub fn print_information() {
KERNEL_FREE_LIST
.lock()
.print_information(" KERNEL VIRTUAL MEMORY FREE LIST ");
let free_list = KERNEL_FREE_LIST.lock();
info!("Virtual memory free list:\n{free_list}");
}
2 changes: 2 additions & 0 deletions src/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ pub unsafe fn init() {
log::set_max_level(max_level);
}

#[cfg(any(not(target_arch = "riscv64"), feature = "pci", feature = "tcp"))]
macro_rules! infoheader {
// This should work on paper, but it's currently not supported :(
// Refer to https://github.com/rust-lang/rust/issues/46569
Expand All @@ -89,6 +90,7 @@ macro_rules! infoentry {
($str:expr, $($arg:tt)+) => (::log::info!("{:25}{}", concat!($str, ":"), format_args!($($arg)+)));
}

#[cfg(any(not(target_arch = "riscv64"), feature = "pci", feature = "tcp"))]
macro_rules! infofooter {
() => {{
::log::info!("{:=^70}", '=');
Expand Down
6 changes: 5 additions & 1 deletion src/mm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
pub mod allocator;
pub mod device_alloc;
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
#[cfg(not(any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "riscv64"
)))]
pub mod freelist;

use core::mem;
Expand Down

0 comments on commit 0122fd6

Please sign in to comment.