kernel/arch/riscv64/vm/
mod.rs

1//! Virtual memory module for RISC-V architecture.
2//! 
3//! The virtual memory module is responsible for managing the virtual memory of the system.
4//! The module provides functions to initialize the virtual memory system, map physical memory to
5//! virtual memory, and switch page tables.
6//! 
7
8pub mod mmu;
9
10extern crate alloc;
11
12use mmu::PageTable;
13
14const NUM_OF_MAX_PAGE_TABLE: usize = 2048;
15static mut PAGE_TABLES: [PageTable; NUM_OF_MAX_PAGE_TABLE] = [const { PageTable::new() }; NUM_OF_MAX_PAGE_TABLE];
16static mut PAGE_TABLES_USED: [bool; NUM_OF_MAX_PAGE_TABLE] = [false; NUM_OF_MAX_PAGE_TABLE];
17
18const NUM_OF_MAX_ROOT_PAGE_TABLE: usize = 16;
19static mut ROOT_PAGE_TABLES: [usize; NUM_OF_MAX_ROOT_PAGE_TABLE] = [0; NUM_OF_MAX_ROOT_PAGE_TABLE];
20static mut ROOT_PAGE_TABLES_USED: [bool; NUM_OF_MAX_ROOT_PAGE_TABLE] = [false; NUM_OF_MAX_ROOT_PAGE_TABLE];
21
22pub fn new_page_table_idx() -> usize {
23    unsafe {
24        for i in 0..NUM_OF_MAX_PAGE_TABLE{
25            if !PAGE_TABLES_USED[i] {
26                PAGE_TABLES_USED[i] = true;
27                return i;
28            }
29        }
30        panic!("No available page table");
31    }
32}
33
34pub fn get_page_table(index: usize) -> Option<&'static mut PageTable> {
35    unsafe {
36        if PAGE_TABLES_USED[index] {
37            Some(&mut PAGE_TABLES[index])
38        } else {
39            None
40        }
41    }
42}
43
44pub fn alloc_virtual_address_space() -> usize {
45    unsafe {
46        for i in 0..NUM_OF_MAX_ROOT_PAGE_TABLE {
47            if !ROOT_PAGE_TABLES_USED[i] {
48                ROOT_PAGE_TABLES_USED[i] = true;
49                ROOT_PAGE_TABLES[i] = new_page_table_idx();
50                return i;
51            }
52        }
53        panic!("No available root page table");
54    }
55}
56
57pub fn get_root_page_table_idx(asid: usize) -> Option<usize> {
58    unsafe {
59        if ROOT_PAGE_TABLES_USED[asid] {
60            Some(ROOT_PAGE_TABLES[asid])
61        } else {
62            None
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test_case]
72    fn test_get_page_table() {
73        let idx = new_page_table_idx();
74        let page_table = get_page_table(idx);
75        assert!(page_table.is_some());
76    }
77    
78    #[test_case]
79    fn test_get_root_page_table_idx() {
80        let asid = alloc_virtual_address_space();
81        let root_page_table_idx = get_root_page_table_idx(asid);
82        assert!(root_page_table_idx.is_some());
83    }
84}