Skip to content

Commit 374c53b

Browse files
feat(mm): add PageAlloc, FrameAlloc
Co-authored-by: m-mueller678 <[email protected]>
1 parent c98578c commit 374c53b

File tree

4 files changed

+95
-2
lines changed

4 files changed

+95
-2
lines changed

src/mm/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
//! ```
4242
4343
pub(crate) mod device_alloc;
44+
mod page_range_alloc;
4445
pub(crate) mod physicalmem;
4546
pub(crate) mod virtualmem;
4647

@@ -53,6 +54,7 @@ use hermit_sync::{Lazy, RawInterruptTicketMutex};
5354
pub use memory_addresses::{PhysAddr, VirtAddr};
5455
use talc::{ErrOnOom, Span, Talc, Talck};
5556

57+
pub use self::page_range_alloc::PageRangeAllocator;
5658
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
5759
use crate::arch::mm::paging::HugePageSize;
5860
pub use crate::arch::mm::paging::virtual_to_physical;

src/mm/page_range_alloc.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use core::alloc::AllocError;
2+
3+
use free_list::{PageLayout, PageRange};
4+
5+
/// An allocator that allocates memory in page granularity.
6+
pub trait PageRangeAllocator {
7+
/// Attempts to allocate a range of memory in page granularity.
8+
fn allocate(layout: PageLayout) -> Result<PageRange, AllocError>;
9+
10+
/// Attempts to allocate the pages described by `range`.
11+
fn allocate_at(range: PageRange) -> Result<(), AllocError>;
12+
13+
/// Deallocates the pages described by `range`.
14+
///
15+
/// # Safety
16+
///
17+
/// - `range` must described a range of pages _currently allocated_ via this allocator.
18+
unsafe fn deallocate(range: PageRange);
19+
}

src/mm/physicalmem.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,55 @@
1+
use core::alloc::AllocError;
2+
use core::fmt;
13
use core::sync::atomic::{AtomicUsize, Ordering};
24

35
use align_address::Align;
4-
use free_list::{FreeList, PageRange};
6+
use free_list::{FreeList, PageLayout, PageRange};
57
use hermit_sync::InterruptTicketMutex;
68
use memory_addresses::{PhysAddr, VirtAddr};
79

810
#[cfg(target_arch = "x86_64")]
911
use crate::arch::mm::paging::PageTableEntryFlagsExt;
1012
use crate::arch::mm::paging::{self, HugePageSize, PageSize, PageTableEntryFlags};
1113
use crate::env;
14+
use crate::mm::PageRangeAllocator;
1215
use crate::mm::device_alloc::DeviceAlloc;
1316

1417
pub static PHYSICAL_FREE_LIST: InterruptTicketMutex<FreeList<16>> =
1518
InterruptTicketMutex::new(FreeList::new());
1619
pub static TOTAL_MEMORY: AtomicUsize = AtomicUsize::new(0);
1720

21+
#[expect(dead_code)]
22+
pub struct FrameAlloc;
23+
24+
impl PageRangeAllocator for FrameAlloc {
25+
fn allocate(layout: PageLayout) -> Result<PageRange, AllocError> {
26+
PHYSICAL_FREE_LIST
27+
.lock()
28+
.allocate(layout)
29+
.map_err(|_| AllocError)
30+
}
31+
32+
fn allocate_at(range: PageRange) -> Result<(), AllocError> {
33+
PHYSICAL_FREE_LIST
34+
.lock()
35+
.allocate_at(range)
36+
.map_err(|_| AllocError)
37+
}
38+
39+
unsafe fn deallocate(range: PageRange) {
40+
unsafe {
41+
PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap();
42+
}
43+
}
44+
}
45+
46+
impl fmt::Display for FrameAlloc {
47+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48+
let free_list = PHYSICAL_FREE_LIST.lock();
49+
write!(f, "FrameAlloc free list:\n{free_list}")
50+
}
51+
}
52+
1853
pub fn total_memory_size() -> usize {
1954
TOTAL_MEMORY.load(Ordering::Relaxed)
2055
}

src/mm/virtualmem.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,47 @@
1-
use free_list::{FreeList, PageRange};
1+
use core::alloc::AllocError;
2+
use core::fmt;
3+
4+
use free_list::{FreeList, PageLayout, PageRange};
25
use hermit_sync::InterruptTicketMutex;
36
use memory_addresses::VirtAddr;
47

8+
use crate::mm::PageRangeAllocator;
9+
510
pub static KERNEL_FREE_LIST: InterruptTicketMutex<FreeList<16>> =
611
InterruptTicketMutex::new(FreeList::new());
712

13+
#[expect(dead_code)]
14+
pub struct PageAlloc;
15+
16+
impl PageRangeAllocator for PageAlloc {
17+
fn allocate(layout: PageLayout) -> Result<PageRange, AllocError> {
18+
KERNEL_FREE_LIST
19+
.lock()
20+
.allocate(layout)
21+
.map_err(|_| AllocError)
22+
}
23+
24+
fn allocate_at(range: PageRange) -> Result<(), AllocError> {
25+
KERNEL_FREE_LIST
26+
.lock()
27+
.allocate_at(range)
28+
.map_err(|_| AllocError)
29+
}
30+
31+
unsafe fn deallocate(range: PageRange) {
32+
unsafe {
33+
KERNEL_FREE_LIST.lock().deallocate(range).unwrap();
34+
}
35+
}
36+
}
37+
38+
impl fmt::Display for PageAlloc {
39+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40+
let free_list = KERNEL_FREE_LIST.lock();
41+
write!(f, "PageAlloc free list:\n{free_list}")
42+
}
43+
}
44+
845
pub fn init() {
946
let range = PageRange::new(
1047
kernel_heap_end().as_usize().div_ceil(2),

0 commit comments

Comments
 (0)