mirror of
https://github.com/iceHtwoO/novaOS.git
synced 2026-04-16 20:22:26 +00:00
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
This commit is contained in:
committed by
GitHub
parent
f78388ee2c
commit
34a66ff87a
95
src/aarch64/mmu/physical_mapping.rs
Normal file
95
src/aarch64/mmu/physical_mapping.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user