Files
novaOS/src/aarch64/mmu/physical_mapping.rs
Alexander Neuhäuser 34a66ff87a feat: implement first SVC mailbox instruction (#6)
* refactor: organize code

* feat: move EL0 stack to virtual space

* wip

* feat: Enable EL0 basic mailbox access via SVCs

* refactor: move irq interrupts
2026-03-22 12:25:43 +01:00

96 lines
2.6 KiB
Rust

use crate::aarch64::mmu::{PhysAddr, GRANULARITY, L2_BLOCK_BITMAP_WORDS, MAX_PAGE_COUNT};
use nova_error::NovaError;
struct PagingMap {
bitmap: [u64; MAX_PAGE_COUNT / 64],
}
static mut PAGING_BITMAP: PagingMap = PagingMap {
bitmap: [0; MAX_PAGE_COUNT / 64],
};
pub fn reserve_page() -> PhysAddr {
if let Some(address) = find_unallocated_page() {
let page = address / GRANULARITY;
let word_index = page / 64;
unsafe { PAGING_BITMAP.bitmap[word_index] |= 1 << (page % 64) };
return address;
}
panic!("Out of Memory!");
}
pub fn reserve_page_explicit(physical_address: usize) -> Result<PhysAddr, NovaError> {
let page = physical_address / GRANULARITY;
let word_index = page / 64;
if unsafe { PAGING_BITMAP.bitmap[word_index] } & (1 << (page % 64)) > 0 {
return Err(NovaError::Paging);
}
unsafe { PAGING_BITMAP.bitmap[word_index] |= 1 << (page % 64) };
Ok(physical_address)
}
pub fn reserve_block() -> usize {
if let Some(start) = find_contiguous_free_bitmap_words(L2_BLOCK_BITMAP_WORDS) {
for j in 0..L2_BLOCK_BITMAP_WORDS {
unsafe { PAGING_BITMAP.bitmap[start + j] = u64::MAX };
}
return start * 64 * GRANULARITY;
}
panic!("Out of Memory!");
}
pub fn reserve_block_explicit(physical_address: usize) -> Result<(), NovaError> {
let page = physical_address / GRANULARITY;
for i in 0..L2_BLOCK_BITMAP_WORDS {
unsafe {
if PAGING_BITMAP.bitmap[(page / 64) + i] != 0 {
return Err(NovaError::Paging);
}
};
}
for i in 0..L2_BLOCK_BITMAP_WORDS {
unsafe {
PAGING_BITMAP.bitmap[(page / 64) + i] = u64::MAX;
};
}
Ok(())
}
fn find_unallocated_page() -> Option<usize> {
for (i, entry) in unsafe { PAGING_BITMAP.bitmap }.iter().enumerate() {
if *entry != u64::MAX {
for offset in 0..64 {
if entry >> offset & 0b1 == 0 {
return Some((i * 64 + offset) * GRANULARITY);
}
}
}
}
None
}
fn find_contiguous_free_bitmap_words(required_words: usize) -> Option<usize> {
let mut run_start = 0;
let mut run_len = 0;
for (i, entry) in unsafe { PAGING_BITMAP.bitmap }.iter().enumerate() {
if *entry == 0 {
if run_len == 0 {
run_start = i;
}
run_len += 1;
if run_len == required_words {
return Some(run_start);
}
} else {
run_len = 0;
}
}
None
}