1*7a29d4fcSLoGin use riscv::register::satp; 291e9d4abSLoGin use system_error::SystemError; 391e9d4abSLoGin 4*7a29d4fcSLoGin use crate::{ 5*7a29d4fcSLoGin kdebug, 6*7a29d4fcSLoGin mm::{ 7*7a29d4fcSLoGin allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame}, 84fda81ceSLoGin page::PageFlags, 9*7a29d4fcSLoGin MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, 10*7a29d4fcSLoGin }, 114fda81ceSLoGin }; 124fda81ceSLoGin 134fda81ceSLoGin pub mod bump; 14666cffedSLoGin pub(super) mod init; 154fda81ceSLoGin 164fda81ceSLoGin pub type PageMapper = crate::mm::page::PageMapper<RiscV64MMArch, LockedFrameAllocator>; 174fda81ceSLoGin 18*7a29d4fcSLoGin /// 内核起始物理地址 19*7a29d4fcSLoGin pub(self) static mut KERNEL_BEGIN_PA: PhysAddr = PhysAddr::new(0); 20*7a29d4fcSLoGin /// 内核结束的物理地址 21*7a29d4fcSLoGin pub(self) static mut KERNEL_END_PA: PhysAddr = PhysAddr::new(0); 22*7a29d4fcSLoGin /// 内核起始虚拟地址 23*7a29d4fcSLoGin pub(self) static mut KERNEL_BEGIN_VA: VirtAddr = VirtAddr::new(0); 24*7a29d4fcSLoGin /// 内核结束虚拟地址 25*7a29d4fcSLoGin pub(self) static mut KERNEL_END_VA: VirtAddr = VirtAddr::new(0); 26*7a29d4fcSLoGin 2774ffde66SLoGin /// RiscV64的内存管理架构结构体(sv39) 284fda81ceSLoGin #[derive(Debug, Clone, Copy, Hash)] 294fda81ceSLoGin pub struct RiscV64MMArch; 304fda81ceSLoGin 314fda81ceSLoGin impl MemoryManagementArch for RiscV64MMArch { 324fda81ceSLoGin const PAGE_SHIFT: usize = 12; 334fda81ceSLoGin 344fda81ceSLoGin const PAGE_ENTRY_SHIFT: usize = 9; 354fda81ceSLoGin 364fda81ceSLoGin /// sv39分页只有三级 374fda81ceSLoGin const PAGE_LEVELS: usize = 3; 384fda81ceSLoGin 394fda81ceSLoGin const ENTRY_ADDRESS_SHIFT: usize = 39; 404fda81ceSLoGin 414fda81ceSLoGin const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT; 424fda81ceSLoGin 434fda81ceSLoGin const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT; 444fda81ceSLoGin 454fda81ceSLoGin const ENTRY_FLAG_PRESENT: usize = 1 << 0; 464fda81ceSLoGin 474fda81ceSLoGin const ENTRY_FLAG_READONLY: usize = 1 << 1; 484fda81ceSLoGin 494fda81ceSLoGin const ENTRY_FLAG_READWRITE: usize = (1 << 2) | (1 << 1); 504fda81ceSLoGin 514fda81ceSLoGin const ENTRY_FLAG_USER: usize = (1 << 4); 524fda81ceSLoGin 534fda81ceSLoGin const ENTRY_FLAG_WRITE_THROUGH: usize = (2 << 61); 544fda81ceSLoGin 554fda81ceSLoGin const ENTRY_FLAG_CACHE_DISABLE: usize = (2 << 61); 564fda81ceSLoGin 574fda81ceSLoGin const ENTRY_FLAG_NO_EXEC: usize = 0; 584fda81ceSLoGin 594fda81ceSLoGin const ENTRY_FLAG_EXEC: usize = (1 << 3); 604fda81ceSLoGin 614fda81ceSLoGin const PHYS_OFFSET: usize = 0xffff_ffc0_0000_0000; 624fda81ceSLoGin 634fda81ceSLoGin const USER_END_VADDR: crate::mm::VirtAddr = VirtAddr::new(0x0000_003f_ffff_ffff); 644fda81ceSLoGin 654fda81ceSLoGin const USER_BRK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffff_ffff); 664fda81ceSLoGin 674fda81ceSLoGin const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000); 684fda81ceSLoGin 6974ffde66SLoGin /// 在距离sv39的顶端还有1G的位置,设置为FIXMAP的起始地址 7074ffde66SLoGin const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000); 7174ffde66SLoGin /// 设置1MB的fixmap空间 7274ffde66SLoGin const FIXMAP_SIZE: usize = 256 * 4096; 7374ffde66SLoGin 7445626c85SLoGin unsafe fn init() { 754fda81ceSLoGin todo!() 764fda81ceSLoGin } 774fda81ceSLoGin 78*7a29d4fcSLoGin unsafe fn invalidate_page(address: VirtAddr) { 79*7a29d4fcSLoGin riscv::asm::sfence_vma(0, address.data()); 804fda81ceSLoGin } 814fda81ceSLoGin 824fda81ceSLoGin unsafe fn invalidate_all() { 83*7a29d4fcSLoGin riscv::asm::sfence_vma_all(); 844fda81ceSLoGin } 854fda81ceSLoGin 86*7a29d4fcSLoGin unsafe fn table(_table_kind: PageTableKind) -> PhysAddr { 87*7a29d4fcSLoGin // phys page number 88*7a29d4fcSLoGin let ppn = riscv::register::satp::read().ppn(); 89*7a29d4fcSLoGin 90*7a29d4fcSLoGin let paddr = PhysPageFrame::from_ppn(ppn).phys_address(); 91*7a29d4fcSLoGin 92*7a29d4fcSLoGin kdebug!("table(): {paddr:?}, ppn: {ppn}"); 93*7a29d4fcSLoGin 94*7a29d4fcSLoGin return paddr; 954fda81ceSLoGin } 964fda81ceSLoGin 97*7a29d4fcSLoGin unsafe fn set_table(_table_kind: PageTableKind, table: PhysAddr) { 98*7a29d4fcSLoGin let ppn = PhysPageFrame::new(table).ppn(); 99*7a29d4fcSLoGin kdebug!("set_table(): {table:?}, ppn:{ppn}"); 100*7a29d4fcSLoGin riscv::asm::sfence_vma_all(); 101*7a29d4fcSLoGin satp::set(satp::Mode::Sv39, 0, ppn); 1024fda81ceSLoGin } 1034fda81ceSLoGin 1044fda81ceSLoGin fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool { 105*7a29d4fcSLoGin virt.is_canonical() 1064fda81ceSLoGin } 1074fda81ceSLoGin 1084fda81ceSLoGin fn initial_page_table() -> crate::mm::PhysAddr { 1094fda81ceSLoGin todo!() 1104fda81ceSLoGin } 1114fda81ceSLoGin 11291e9d4abSLoGin fn setup_new_usermapper() -> Result<crate::mm::ucontext::UserMapper, SystemError> { 1134fda81ceSLoGin todo!() 1144fda81ceSLoGin } 115*7a29d4fcSLoGin 116*7a29d4fcSLoGin unsafe fn phys_2_virt(phys: PhysAddr) -> Option<VirtAddr> { 117*7a29d4fcSLoGin // riscv的内核文件所占用的空间,由于重定位而导致不满足线性偏移量的关系 118*7a29d4fcSLoGin // 因此这里需要特殊处理 119*7a29d4fcSLoGin if phys >= KERNEL_BEGIN_PA && phys < KERNEL_END_PA { 120*7a29d4fcSLoGin let r = KERNEL_BEGIN_VA + (phys - KERNEL_BEGIN_PA); 121*7a29d4fcSLoGin return Some(r); 122*7a29d4fcSLoGin } 123*7a29d4fcSLoGin 124*7a29d4fcSLoGin if let Some(vaddr) = phys.data().checked_add(Self::PHYS_OFFSET) { 125*7a29d4fcSLoGin return Some(VirtAddr::new(vaddr)); 126*7a29d4fcSLoGin } else { 127*7a29d4fcSLoGin return None; 128*7a29d4fcSLoGin } 129*7a29d4fcSLoGin } 130*7a29d4fcSLoGin 131*7a29d4fcSLoGin unsafe fn virt_2_phys(virt: VirtAddr) -> Option<PhysAddr> { 132*7a29d4fcSLoGin if virt >= KERNEL_BEGIN_VA && virt < KERNEL_END_VA { 133*7a29d4fcSLoGin let r = KERNEL_BEGIN_PA + (virt - KERNEL_BEGIN_VA); 134*7a29d4fcSLoGin kdebug!("virt_2_phys: kernel address: virt = {virt:?}, paddr = {r:?}"); 135*7a29d4fcSLoGin return Some(r); 136*7a29d4fcSLoGin } 137*7a29d4fcSLoGin 138*7a29d4fcSLoGin if let Some(paddr) = virt.data().checked_sub(Self::PHYS_OFFSET) { 139*7a29d4fcSLoGin let r = PhysAddr::new(paddr); 140*7a29d4fcSLoGin kdebug!("virt_2_phys: non-kernel address: virt = {virt:?}, paddr = {r:?}"); 141*7a29d4fcSLoGin return Some(r); 142*7a29d4fcSLoGin } else { 143*7a29d4fcSLoGin return None; 144*7a29d4fcSLoGin } 145*7a29d4fcSLoGin } 146*7a29d4fcSLoGin 147*7a29d4fcSLoGin fn make_entry(paddr: PhysAddr, page_flags: usize) -> usize { 148*7a29d4fcSLoGin let ppn = PhysPageFrame::new(paddr).ppn(); 149*7a29d4fcSLoGin let r = ((ppn & ((1 << 44) - 1)) << 10) | page_flags; 150*7a29d4fcSLoGin 151*7a29d4fcSLoGin kdebug!("make entry: r={r:#x}"); 152*7a29d4fcSLoGin return r; 153*7a29d4fcSLoGin } 154*7a29d4fcSLoGin } 155*7a29d4fcSLoGin 156*7a29d4fcSLoGin impl VirtAddr { 157*7a29d4fcSLoGin /// 判断虚拟地址是否合法 158*7a29d4fcSLoGin #[inline(always)] 159*7a29d4fcSLoGin pub fn is_canonical(self) -> bool { 160*7a29d4fcSLoGin let x = self.data() & RiscV64MMArch::PHYS_OFFSET; 161*7a29d4fcSLoGin // 如果x为0,说明虚拟地址的高位为0,是合法的用户地址 162*7a29d4fcSLoGin // 如果x为PHYS_OFFSET,说明虚拟地址的高位全为1,是合法的内核地址 163*7a29d4fcSLoGin return x == 0 || x == RiscV64MMArch::PHYS_OFFSET; 164*7a29d4fcSLoGin } 1654fda81ceSLoGin } 1664fda81ceSLoGin 1674fda81ceSLoGin /// 获取内核地址默认的页面标志 1684fda81ceSLoGin pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(virt: VirtAddr) -> PageFlags<A> { 1694fda81ceSLoGin unimplemented!("riscv64::kernel_page_flags") 1704fda81ceSLoGin } 1714fda81ceSLoGin 1724fda81ceSLoGin /// 全局的页帧分配器 1734fda81ceSLoGin #[derive(Debug, Clone, Copy, Hash)] 1744fda81ceSLoGin pub struct LockedFrameAllocator; 1754fda81ceSLoGin 1764fda81ceSLoGin impl FrameAllocator for LockedFrameAllocator { 1774fda81ceSLoGin unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> { 1784fda81ceSLoGin unimplemented!("RiscV64 LockedFrameAllocator::allocate") 1794fda81ceSLoGin } 1804fda81ceSLoGin 1814fda81ceSLoGin unsafe fn free(&mut self, address: crate::mm::PhysAddr, count: PageFrameCount) { 1824fda81ceSLoGin assert!(count.data().is_power_of_two()); 1834fda81ceSLoGin unimplemented!("RiscV64 LockedFrameAllocator::free") 1844fda81ceSLoGin } 1854fda81ceSLoGin 1864fda81ceSLoGin unsafe fn usage(&self) -> PageFrameUsage { 1874fda81ceSLoGin unimplemented!("RiscV64 LockedFrameAllocator::usage") 1884fda81ceSLoGin } 1894fda81ceSLoGin } 190