mirror of
https://github.com/iceHtwoO/novaOS.git
synced 2026-04-16 20:22:26 +00:00
docs: add code documentation
This commit is contained in:
@@ -13,9 +13,12 @@ const BLOCK: u64 = 0b01;
|
||||
const TABLE: u64 = 0b11;
|
||||
const PAGE: u64 = 0b11;
|
||||
|
||||
/// Allow EL0 to access this section
|
||||
pub const EL0_ACCESSIBLE: u64 = 1 << 6;
|
||||
|
||||
/// Allow a page or block to be written.
|
||||
pub const WRITABLE: u64 = 0 << 7;
|
||||
/// Disallow a page or block to be written.
|
||||
pub const READ_ONLY: u64 = 1 << 7;
|
||||
|
||||
const ACCESS_FLAG: u64 = 1 << 10;
|
||||
@@ -47,6 +50,7 @@ pub static mut TRANSLATIONTABLE_TTBR0: PageTable = PageTable([0; 512]);
|
||||
|
||||
static mut PAGING_BITMAP: [u64; MAX_PAGE_COUNT / 64] = [0; MAX_PAGE_COUNT / 64];
|
||||
|
||||
/// Allocate a memory block of `size` starting at `virtual_address`.
|
||||
pub fn allocate_memory(
|
||||
mut virtual_address: usize,
|
||||
mut size: usize,
|
||||
@@ -93,6 +97,10 @@ pub fn allocate_memory(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Allocate a memory block of `size` starting at `virtual_address`,
|
||||
/// with explicit `physical_address``.
|
||||
///
|
||||
/// Note: This can be used when mapping predefined regions.
|
||||
pub fn allocate_memory_explicit(
|
||||
mut virtual_address: usize,
|
||||
mut size: usize,
|
||||
@@ -169,6 +177,7 @@ pub fn allocate_memory_explicit(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Allocate a singe page.
|
||||
pub fn alloc_page(
|
||||
virtual_address: usize,
|
||||
base_table: &mut PageTable,
|
||||
@@ -182,6 +191,7 @@ pub fn alloc_page(
|
||||
)
|
||||
}
|
||||
|
||||
/// Allocate a single page at an explicit `physical_address`.
|
||||
pub fn alloc_page_explicit(
|
||||
virtual_address: usize,
|
||||
physical_address: usize,
|
||||
@@ -218,6 +228,7 @@ fn map_page(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Allocate a level 2 block.
|
||||
pub fn alloc_block_l2(
|
||||
virtual_addr: usize,
|
||||
base_table: &mut PageTable,
|
||||
@@ -226,6 +237,7 @@ pub fn alloc_block_l2(
|
||||
map_l2_block(virtual_addr, reserve_block(), base_table, additional_flags)
|
||||
}
|
||||
|
||||
/// Allocate a level 2 block, at a explicit `physical_address`.
|
||||
pub fn alloc_block_l2_explicit(
|
||||
virtual_addr: usize,
|
||||
physical_address: usize,
|
||||
@@ -240,13 +252,17 @@ pub fn alloc_block_l2_explicit(
|
||||
map_l2_block(virtual_addr, physical_address, base_table, additional_flags)
|
||||
}
|
||||
|
||||
/// Map a `virtual_address` to a `physical_address`, **WITHOUT** reserving the physical addresses.
|
||||
///
|
||||
/// # NOTE
|
||||
/// Use [`alloc_block_l2_explicit`] instead, **OR** reserve the memory with [`reserve_block_explicit`]
|
||||
pub fn map_l2_block(
|
||||
virtual_addr: usize,
|
||||
virtual_address: usize,
|
||||
physical_address: usize,
|
||||
base_table: &mut PageTable,
|
||||
additional_flags: u64,
|
||||
) -> Result<(), NovaError> {
|
||||
let (l1_off, l2_off, _) = virtual_address_to_table_offset(virtual_addr);
|
||||
let (l1_off, l2_off, _) = virtual_address_to_table_offset(virtual_address);
|
||||
let offsets = [l1_off];
|
||||
let table = navigate_table(base_table, &offsets)?;
|
||||
|
||||
@@ -261,6 +277,8 @@ pub fn map_l2_block(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Reserve a physical address range.
|
||||
pub fn reserve_range_explicit(
|
||||
start_physical_address: usize,
|
||||
end_physical_address: usize,
|
||||
@@ -327,7 +345,8 @@ fn reserve_block() -> usize {
|
||||
panic!("Out of Memory!");
|
||||
}
|
||||
|
||||
fn reserve_block_explicit(physical_address: usize) -> Result<(), NovaError> {
|
||||
/// Reserve a level 2 block physical address range.
|
||||
pub fn reserve_block_explicit(physical_address: usize) -> Result<(), NovaError> {
|
||||
let page = physical_address / GRANULARITY;
|
||||
for i in 0..L2_BLOCK_BITMAP_WORDS {
|
||||
unsafe {
|
||||
@@ -372,16 +391,19 @@ fn virtual_address_to_table_offset(virtual_addr: usize) -> (usize, usize, usize)
|
||||
(l1_off, l2_off, l3_off)
|
||||
}
|
||||
|
||||
/// Debugging function to navigate the translation tables.
|
||||
pub fn sim_l3_access(addr: usize) {
|
||||
unsafe {
|
||||
let entry1 = TRANSLATIONTABLE_TTBR0.0[addr / LEVEL1_BLOCK_SIZE];
|
||||
let table2 = &mut *(get_table_entry_address(entry1) as *mut PageTable);
|
||||
let table2 = &mut *(entry_phys(entry1) as *mut PageTable);
|
||||
let entry2 = table2.0[(addr % LEVEL1_BLOCK_SIZE) / LEVEL2_BLOCK_SIZE];
|
||||
let table3 = &mut *(get_table_entry_address(entry2) as *mut PageTable);
|
||||
let table3 = &mut *(entry_phys(entry2) as *mut PageTable);
|
||||
let entry3 = table3.0[(addr % LEVEL2_BLOCK_SIZE) / GRANULARITY];
|
||||
}
|
||||
}
|
||||
|
||||
/// Navigate the table tree, by following given offsets. This function
|
||||
/// allocates new tables if required.
|
||||
fn navigate_table<'a>(
|
||||
initial_table: &'a mut PageTable,
|
||||
offsets: &'a [usize],
|
||||
@@ -394,6 +416,9 @@ fn navigate_table<'a>(
|
||||
Ok(table)
|
||||
}
|
||||
|
||||
/// Get the next table one level down.
|
||||
///
|
||||
/// If table doesn't exit a page will be allocated for it.
|
||||
fn next_table(
|
||||
table: &mut PageTable,
|
||||
offset: usize,
|
||||
@@ -412,10 +437,10 @@ fn next_table(
|
||||
NORMAL_MEM | WRITABLE | PXN | UXN,
|
||||
)?;
|
||||
|
||||
Ok(unsafe { &mut *(get_table_entry_address(table.0[offset]) as *mut PageTable) })
|
||||
Ok(unsafe { &mut *(entry_phys(table.0[offset]) as *mut PageTable) })
|
||||
}
|
||||
1 => return Err(NovaError::Paging),
|
||||
3 => Ok(unsafe { &mut *(get_table_entry_address(table.0[offset]) as *mut PageTable) }),
|
||||
3 => Ok(unsafe { &mut *(entry_phys(table.0[offset]) as *mut PageTable) }),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -455,7 +480,8 @@ fn find_contiguous_free_bitmap_words(required_words: usize) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Extracts the physical address out of an table entry.
|
||||
#[inline]
|
||||
fn get_table_entry_address(entry: u64) -> u64 {
|
||||
fn entry_phys(entry: u64) -> u64 {
|
||||
entry & 0x0000_FFFF_FFFF_F000
|
||||
}
|
||||
|
||||
@@ -13,8 +13,7 @@ extern crate alloc;
|
||||
use nova::{
|
||||
aarch64::{
|
||||
mmu::{
|
||||
allocate_memory_explicit, sim_l3_access, EL0_ACCESSIBLE, NORMAL_MEM,
|
||||
PXN, UXN, WRITABLE,
|
||||
allocate_memory_explicit, sim_l3_access, EL0_ACCESSIBLE, NORMAL_MEM, PXN, UXN, WRITABLE,
|
||||
},
|
||||
registers::{daif, read_id_aa64mmfr0_el1},
|
||||
},
|
||||
@@ -74,7 +73,6 @@ pub extern "C" fn main() -> ! {
|
||||
initialize_mmu_translation_tables();
|
||||
// Frame Buffer memory range
|
||||
// TODO: this is just temporary
|
||||
// TODO: Investigate why the size is off
|
||||
allocate_memory_explicit(
|
||||
0x3c100000,
|
||||
1080 * 1920 * 4,
|
||||
|
||||
Reference in New Issue
Block a user