Skip to content

Commit e72afef

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

File tree

4 files changed

+105
-2
lines changed

4 files changed

+105
-2
lines changed

src/mm/mod.rs

Lines changed: 4 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,9 @@ 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;
58+
pub use self::physicalmem::FrameAlloc;
59+
pub use self::virtualmem::PageAlloc;
5660
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
5761
use crate::arch::mm::paging::HugePageSize;
5862
pub use crate::arch::mm::paging::virtual_to_physical;

src/mm/page_range_alloc.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
unsafe fn init();
8+
9+
/// Attempts to allocate a range of memory in page granularity.
10+
fn allocate(layout: PageLayout) -> Result<PageRange, AllocError>;
11+
12+
/// Attempts to allocate the pages described by `range`.
13+
fn allocate_at(range: PageRange) -> Result<(), AllocError>;
14+
15+
/// Deallocates the pages described by `range`.
16+
///
17+
/// # Safety
18+
///
19+
/// - `range` must described a range of pages _currently allocated_ via this allocator.
20+
unsafe fn deallocate(range: PageRange);
21+
}

src/mm/physicalmem.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,58 @@
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, PageRangeError};
6+
use free_list::{FreeList, PageLayout, PageRange, PageRangeError};
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+
pub struct FrameAlloc;
22+
23+
impl PageRangeAllocator for FrameAlloc {
24+
unsafe fn init() {
25+
init();
26+
}
27+
28+
fn allocate(layout: PageLayout) -> Result<PageRange, AllocError> {
29+
PHYSICAL_FREE_LIST
30+
.lock()
31+
.allocate(layout)
32+
.map_err(|_| AllocError)
33+
}
34+
35+
fn allocate_at(range: PageRange) -> Result<(), AllocError> {
36+
PHYSICAL_FREE_LIST
37+
.lock()
38+
.allocate_at(range)
39+
.map_err(|_| AllocError)
40+
}
41+
42+
unsafe fn deallocate(range: PageRange) {
43+
unsafe {
44+
PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap();
45+
}
46+
}
47+
}
48+
49+
impl fmt::Display for FrameAlloc {
50+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51+
let free_list = PHYSICAL_FREE_LIST.lock();
52+
write!(f, "FrameAlloc free list:\n{free_list}")
53+
}
54+
}
55+
1856
pub fn total_memory_size() -> usize {
1957
TOTAL_MEMORY.load(Ordering::Relaxed)
2058
}

src/mm/virtualmem.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,50 @@
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+
pub struct PageAlloc;
14+
15+
impl PageRangeAllocator for PageAlloc {
16+
unsafe fn init() {
17+
init();
18+
}
19+
20+
fn allocate(layout: PageLayout) -> Result<PageRange, AllocError> {
21+
KERNEL_FREE_LIST
22+
.lock()
23+
.allocate(layout)
24+
.map_err(|_| AllocError)
25+
}
26+
27+
fn allocate_at(range: PageRange) -> Result<(), AllocError> {
28+
KERNEL_FREE_LIST
29+
.lock()
30+
.allocate_at(range)
31+
.map_err(|_| AllocError)
32+
}
33+
34+
unsafe fn deallocate(range: PageRange) {
35+
unsafe {
36+
KERNEL_FREE_LIST.lock().deallocate(range).unwrap();
37+
}
38+
}
39+
}
40+
41+
impl fmt::Display for PageAlloc {
42+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43+
let free_list = KERNEL_FREE_LIST.lock();
44+
write!(f, "PageAlloc free list:\n{free_list}")
45+
}
46+
}
47+
848
pub fn init() {
949
let range = PageRange::new(
1050
kernel_heap_end().as_usize().div_ceil(2),

0 commit comments

Comments
 (0)