kernel/arch/riscv64/vm/
mod.rs1pub 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}