1 use riscv::register::satp; 2 use system_error::SystemError; 3 4 use crate::mm::{ 5 allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame}, 6 page::PageFlags, 7 MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, 8 }; 9 10 pub mod bump; 11 pub(super) mod init; 12 13 pub type PageMapper = crate::mm::page::PageMapper<RiscV64MMArch, LockedFrameAllocator>; 14 15 /// 内核起始物理地址 16 pub(self) static mut KERNEL_BEGIN_PA: PhysAddr = PhysAddr::new(0); 17 /// 内核结束的物理地址 18 pub(self) static mut KERNEL_END_PA: PhysAddr = PhysAddr::new(0); 19 /// 内核起始虚拟地址 20 pub(self) static mut KERNEL_BEGIN_VA: VirtAddr = VirtAddr::new(0); 21 /// 内核结束虚拟地址 22 pub(self) static mut KERNEL_END_VA: VirtAddr = VirtAddr::new(0); 23 24 /// RiscV64的内存管理架构结构体(sv39) 25 #[derive(Debug, Clone, Copy, Hash)] 26 pub struct RiscV64MMArch; 27 28 impl RiscV64MMArch { 29 pub const ENTRY_FLAG_GLOBAL: usize = 1 << 5; 30 } 31 impl MemoryManagementArch for RiscV64MMArch { 32 const PAGE_SHIFT: usize = 12; 33 34 const PAGE_ENTRY_SHIFT: usize = 9; 35 36 /// sv39分页只有三级 37 const PAGE_LEVELS: usize = 3; 38 39 const ENTRY_ADDRESS_SHIFT: usize = 39; 40 41 const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT 42 | Self::ENTRY_FLAG_READWRITE 43 | Self::ENTRY_FLAG_DIRTY 44 | Self::ENTRY_FLAG_ACCESSED 45 | Self::ENTRY_FLAG_GLOBAL; 46 47 const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT; 48 49 const ENTRY_FLAG_PRESENT: usize = 1 << 0; 50 51 const ENTRY_FLAG_READONLY: usize = 0; 52 53 const ENTRY_FLAG_READWRITE: usize = (1 << 2) | (1 << 1); 54 55 const ENTRY_FLAG_USER: usize = (1 << 4); 56 57 const ENTRY_FLAG_WRITE_THROUGH: usize = (2 << 61); 58 59 const ENTRY_FLAG_CACHE_DISABLE: usize = (2 << 61); 60 61 const ENTRY_FLAG_NO_EXEC: usize = 0; 62 63 const ENTRY_FLAG_EXEC: usize = (1 << 3); 64 const ENTRY_FLAG_ACCESSED: usize = (1 << 6); 65 const ENTRY_FLAG_DIRTY: usize = (1 << 7); 66 67 const PHYS_OFFSET: usize = 0xffff_ffc0_0000_0000; 68 69 const USER_END_VADDR: crate::mm::VirtAddr = VirtAddr::new(0x0000_003f_ffff_ffff); 70 71 const USER_BRK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffff_ffff); 72 73 const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000); 74 75 /// 在距离sv39的顶端还有1G的位置,设置为FIXMAP的起始地址 76 const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000); 77 /// 设置1MB的fixmap空间 78 const FIXMAP_SIZE: usize = 256 * 4096; 79 80 unsafe fn init() { 81 todo!() 82 } 83 84 unsafe fn invalidate_page(address: VirtAddr) { 85 riscv::asm::sfence_vma(0, address.data()); 86 } 87 88 unsafe fn invalidate_all() { 89 riscv::asm::sfence_vma_all(); 90 } 91 92 unsafe fn table(_table_kind: PageTableKind) -> PhysAddr { 93 // phys page number 94 let ppn = riscv::register::satp::read().ppn(); 95 96 let paddr = PhysPageFrame::from_ppn(ppn).phys_address(); 97 98 return paddr; 99 } 100 101 unsafe fn set_table(_table_kind: PageTableKind, table: PhysAddr) { 102 let ppn = PhysPageFrame::new(table).ppn(); 103 riscv::asm::sfence_vma_all(); 104 satp::set(satp::Mode::Sv39, 0, ppn); 105 } 106 107 fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool { 108 virt.is_canonical() 109 } 110 111 fn initial_page_table() -> crate::mm::PhysAddr { 112 todo!() 113 } 114 115 fn setup_new_usermapper() -> Result<crate::mm::ucontext::UserMapper, SystemError> { 116 todo!() 117 } 118 119 unsafe fn phys_2_virt(phys: PhysAddr) -> Option<VirtAddr> { 120 // riscv的内核文件所占用的空间,由于重定位而导致不满足线性偏移量的关系 121 // 因此这里需要特殊处理 122 if phys >= KERNEL_BEGIN_PA && phys < KERNEL_END_PA { 123 let r = KERNEL_BEGIN_VA + (phys - KERNEL_BEGIN_PA); 124 return Some(r); 125 } 126 127 if let Some(vaddr) = phys.data().checked_add(Self::PHYS_OFFSET) { 128 return Some(VirtAddr::new(vaddr)); 129 } else { 130 return None; 131 } 132 } 133 134 unsafe fn virt_2_phys(virt: VirtAddr) -> Option<PhysAddr> { 135 if virt >= KERNEL_BEGIN_VA && virt < KERNEL_END_VA { 136 let r = KERNEL_BEGIN_PA + (virt - KERNEL_BEGIN_VA); 137 return Some(r); 138 } 139 140 if let Some(paddr) = virt.data().checked_sub(Self::PHYS_OFFSET) { 141 let r = PhysAddr::new(paddr); 142 return Some(r); 143 } else { 144 return None; 145 } 146 } 147 148 fn make_entry(paddr: PhysAddr, page_flags: usize) -> usize { 149 let ppn = PhysPageFrame::new(paddr).ppn(); 150 let r = ((ppn & ((1 << 44) - 1)) << 10) | page_flags; 151 return r; 152 } 153 } 154 155 impl VirtAddr { 156 /// 判断虚拟地址是否合法 157 #[inline(always)] 158 pub fn is_canonical(self) -> bool { 159 let x = self.data() & RiscV64MMArch::PHYS_OFFSET; 160 // 如果x为0,说明虚拟地址的高位为0,是合法的用户地址 161 // 如果x为PHYS_OFFSET,说明虚拟地址的高位全为1,是合法的内核地址 162 return x == 0 || x == RiscV64MMArch::PHYS_OFFSET; 163 } 164 } 165 166 /// 获取内核地址默认的页面标志 167 pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(virt: VirtAddr) -> PageFlags<A> { 168 unimplemented!("riscv64::kernel_page_flags") 169 } 170 171 /// 全局的页帧分配器 172 #[derive(Debug, Clone, Copy, Hash)] 173 pub struct LockedFrameAllocator; 174 175 impl FrameAllocator for LockedFrameAllocator { 176 unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> { 177 unimplemented!("RiscV64 LockedFrameAllocator::allocate") 178 } 179 180 unsafe fn free(&mut self, address: crate::mm::PhysAddr, count: PageFrameCount) { 181 assert!(count.data().is_power_of_two()); 182 unimplemented!("RiscV64 LockedFrameAllocator::free") 183 } 184 185 unsafe fn usage(&self) -> PageFrameUsage { 186 unimplemented!("RiscV64 LockedFrameAllocator::usage") 187 } 188 } 189