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 TABLE: u64 = 0b11;
|
||||||
const PAGE: u64 = 0b11;
|
const PAGE: u64 = 0b11;
|
||||||
|
|
||||||
|
/// Allow EL0 to access this section
|
||||||
pub const EL0_ACCESSIBLE: u64 = 1 << 6;
|
pub const EL0_ACCESSIBLE: u64 = 1 << 6;
|
||||||
|
|
||||||
|
/// Allow a page or block to be written.
|
||||||
pub const WRITABLE: u64 = 0 << 7;
|
pub const WRITABLE: u64 = 0 << 7;
|
||||||
|
/// Disallow a page or block to be written.
|
||||||
pub const READ_ONLY: u64 = 1 << 7;
|
pub const READ_ONLY: u64 = 1 << 7;
|
||||||
|
|
||||||
const ACCESS_FLAG: u64 = 1 << 10;
|
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];
|
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(
|
pub fn allocate_memory(
|
||||||
mut virtual_address: usize,
|
mut virtual_address: usize,
|
||||||
mut size: usize,
|
mut size: usize,
|
||||||
@@ -93,6 +97,10 @@ pub fn allocate_memory(
|
|||||||
Ok(())
|
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(
|
pub fn allocate_memory_explicit(
|
||||||
mut virtual_address: usize,
|
mut virtual_address: usize,
|
||||||
mut size: usize,
|
mut size: usize,
|
||||||
@@ -169,6 +177,7 @@ pub fn allocate_memory_explicit(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocate a singe page.
|
||||||
pub fn alloc_page(
|
pub fn alloc_page(
|
||||||
virtual_address: usize,
|
virtual_address: usize,
|
||||||
base_table: &mut PageTable,
|
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(
|
pub fn alloc_page_explicit(
|
||||||
virtual_address: usize,
|
virtual_address: usize,
|
||||||
physical_address: usize,
|
physical_address: usize,
|
||||||
@@ -218,6 +228,7 @@ fn map_page(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocate a level 2 block.
|
||||||
pub fn alloc_block_l2(
|
pub fn alloc_block_l2(
|
||||||
virtual_addr: usize,
|
virtual_addr: usize,
|
||||||
base_table: &mut PageTable,
|
base_table: &mut PageTable,
|
||||||
@@ -226,6 +237,7 @@ pub fn alloc_block_l2(
|
|||||||
map_l2_block(virtual_addr, reserve_block(), base_table, additional_flags)
|
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(
|
pub fn alloc_block_l2_explicit(
|
||||||
virtual_addr: usize,
|
virtual_addr: usize,
|
||||||
physical_address: 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_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(
|
pub fn map_l2_block(
|
||||||
virtual_addr: usize,
|
virtual_address: usize,
|
||||||
physical_address: usize,
|
physical_address: usize,
|
||||||
base_table: &mut PageTable,
|
base_table: &mut PageTable,
|
||||||
additional_flags: u64,
|
additional_flags: u64,
|
||||||
) -> Result<(), NovaError> {
|
) -> 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 offsets = [l1_off];
|
||||||
let table = navigate_table(base_table, &offsets)?;
|
let table = navigate_table(base_table, &offsets)?;
|
||||||
|
|
||||||
@@ -261,6 +277,8 @@ pub fn map_l2_block(
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reserve a physical address range.
|
||||||
pub fn reserve_range_explicit(
|
pub fn reserve_range_explicit(
|
||||||
start_physical_address: usize,
|
start_physical_address: usize,
|
||||||
end_physical_address: usize,
|
end_physical_address: usize,
|
||||||
@@ -327,7 +345,8 @@ fn reserve_block() -> usize {
|
|||||||
panic!("Out of Memory!");
|
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;
|
let page = physical_address / GRANULARITY;
|
||||||
for i in 0..L2_BLOCK_BITMAP_WORDS {
|
for i in 0..L2_BLOCK_BITMAP_WORDS {
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -372,16 +391,19 @@ fn virtual_address_to_table_offset(virtual_addr: usize) -> (usize, usize, usize)
|
|||||||
(l1_off, l2_off, l3_off)
|
(l1_off, l2_off, l3_off)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Debugging function to navigate the translation tables.
|
||||||
pub fn sim_l3_access(addr: usize) {
|
pub fn sim_l3_access(addr: usize) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let entry1 = TRANSLATIONTABLE_TTBR0.0[addr / LEVEL1_BLOCK_SIZE];
|
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 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];
|
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>(
|
fn navigate_table<'a>(
|
||||||
initial_table: &'a mut PageTable,
|
initial_table: &'a mut PageTable,
|
||||||
offsets: &'a [usize],
|
offsets: &'a [usize],
|
||||||
@@ -394,6 +416,9 @@ fn navigate_table<'a>(
|
|||||||
Ok(table)
|
Ok(table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the next table one level down.
|
||||||
|
///
|
||||||
|
/// If table doesn't exit a page will be allocated for it.
|
||||||
fn next_table(
|
fn next_table(
|
||||||
table: &mut PageTable,
|
table: &mut PageTable,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
@@ -412,10 +437,10 @@ fn next_table(
|
|||||||
NORMAL_MEM | WRITABLE | PXN | UXN,
|
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),
|
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!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,7 +480,8 @@ fn find_contiguous_free_bitmap_words(required_words: usize) -> Option<usize> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extracts the physical address out of an table entry.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_table_entry_address(entry: u64) -> u64 {
|
fn entry_phys(entry: u64) -> u64 {
|
||||||
entry & 0x0000_FFFF_FFFF_F000
|
entry & 0x0000_FFFF_FFFF_F000
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ extern crate alloc;
|
|||||||
use nova::{
|
use nova::{
|
||||||
aarch64::{
|
aarch64::{
|
||||||
mmu::{
|
mmu::{
|
||||||
allocate_memory_explicit, sim_l3_access, EL0_ACCESSIBLE, NORMAL_MEM,
|
allocate_memory_explicit, sim_l3_access, EL0_ACCESSIBLE, NORMAL_MEM, PXN, UXN, WRITABLE,
|
||||||
PXN, UXN, WRITABLE,
|
|
||||||
},
|
},
|
||||||
registers::{daif, read_id_aa64mmfr0_el1},
|
registers::{daif, read_id_aa64mmfr0_el1},
|
||||||
},
|
},
|
||||||
@@ -74,7 +73,6 @@ pub extern "C" fn main() -> ! {
|
|||||||
initialize_mmu_translation_tables();
|
initialize_mmu_translation_tables();
|
||||||
// Frame Buffer memory range
|
// Frame Buffer memory range
|
||||||
// TODO: this is just temporary
|
// TODO: this is just temporary
|
||||||
// TODO: Investigate why the size is off
|
|
||||||
allocate_memory_explicit(
|
allocate_memory_explicit(
|
||||||
0x3c100000,
|
0x3c100000,
|
||||||
1080 * 1920 * 4,
|
1080 * 1920 * 4,
|
||||||
|
|||||||
Reference in New Issue
Block a user