17a29d4fcSLoGin use riscv::register::satp; 291e9d4abSLoGin use system_error::SystemError; 391e9d4abSLoGin 4*92849878SLoGin use crate::mm::{ 57a29d4fcSLoGin allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame}, 64fda81ceSLoGin page::PageFlags, 77a29d4fcSLoGin MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, 84fda81ceSLoGin }; 94fda81ceSLoGin 104fda81ceSLoGin pub mod bump; 11666cffedSLoGin pub(super) mod init; 124fda81ceSLoGin 134fda81ceSLoGin pub type PageMapper = crate::mm::page::PageMapper<RiscV64MMArch, LockedFrameAllocator>; 144fda81ceSLoGin 157a29d4fcSLoGin /// 内核起始物理地址 167a29d4fcSLoGin pub(self) static mut KERNEL_BEGIN_PA: PhysAddr = PhysAddr::new(0); 177a29d4fcSLoGin /// 内核结束的物理地址 187a29d4fcSLoGin pub(self) static mut KERNEL_END_PA: PhysAddr = PhysAddr::new(0); 197a29d4fcSLoGin /// 内核起始虚拟地址 207a29d4fcSLoGin pub(self) static mut KERNEL_BEGIN_VA: VirtAddr = VirtAddr::new(0); 217a29d4fcSLoGin /// 内核结束虚拟地址 227a29d4fcSLoGin pub(self) static mut KERNEL_END_VA: VirtAddr = VirtAddr::new(0); 237a29d4fcSLoGin 2474ffde66SLoGin /// RiscV64的内存管理架构结构体(sv39) 254fda81ceSLoGin #[derive(Debug, Clone, Copy, Hash)] 264fda81ceSLoGin pub struct RiscV64MMArch; 274fda81ceSLoGin 28*92849878SLoGin impl RiscV64MMArch { 29*92849878SLoGin pub const ENTRY_FLAG_GLOBAL: usize = 1 << 5; 30*92849878SLoGin } 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 41*92849878SLoGin const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT 42*92849878SLoGin | Self::ENTRY_FLAG_READWRITE 43*92849878SLoGin | Self::ENTRY_FLAG_DIRTY 44*92849878SLoGin | Self::ENTRY_FLAG_ACCESSED 45*92849878SLoGin | Self::ENTRY_FLAG_GLOBAL; 464fda81ceSLoGin 474fda81ceSLoGin const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT; 484fda81ceSLoGin 494fda81ceSLoGin const ENTRY_FLAG_PRESENT: usize = 1 << 0; 504fda81ceSLoGin 51*92849878SLoGin const ENTRY_FLAG_READONLY: usize = 0; 524fda81ceSLoGin 534fda81ceSLoGin const ENTRY_FLAG_READWRITE: usize = (1 << 2) | (1 << 1); 544fda81ceSLoGin 554fda81ceSLoGin const ENTRY_FLAG_USER: usize = (1 << 4); 564fda81ceSLoGin 574fda81ceSLoGin const ENTRY_FLAG_WRITE_THROUGH: usize = (2 << 61); 584fda81ceSLoGin 594fda81ceSLoGin const ENTRY_FLAG_CACHE_DISABLE: usize = (2 << 61); 604fda81ceSLoGin 614fda81ceSLoGin const ENTRY_FLAG_NO_EXEC: usize = 0; 624fda81ceSLoGin 634fda81ceSLoGin const ENTRY_FLAG_EXEC: usize = (1 << 3); 64*92849878SLoGin const ENTRY_FLAG_ACCESSED: usize = (1 << 6); 65*92849878SLoGin const ENTRY_FLAG_DIRTY: usize = (1 << 7); 664fda81ceSLoGin 674fda81ceSLoGin const PHYS_OFFSET: usize = 0xffff_ffc0_0000_0000; 684fda81ceSLoGin 694fda81ceSLoGin const USER_END_VADDR: crate::mm::VirtAddr = VirtAddr::new(0x0000_003f_ffff_ffff); 704fda81ceSLoGin 714fda81ceSLoGin const USER_BRK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffff_ffff); 724fda81ceSLoGin 734fda81ceSLoGin const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000); 744fda81ceSLoGin 7574ffde66SLoGin /// 在距离sv39的顶端还有1G的位置,设置为FIXMAP的起始地址 7674ffde66SLoGin const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000); 7774ffde66SLoGin /// 设置1MB的fixmap空间 7874ffde66SLoGin const FIXMAP_SIZE: usize = 256 * 4096; 7974ffde66SLoGin 8045626c85SLoGin unsafe fn init() { 814fda81ceSLoGin todo!() 824fda81ceSLoGin } 834fda81ceSLoGin 847a29d4fcSLoGin unsafe fn invalidate_page(address: VirtAddr) { 857a29d4fcSLoGin riscv::asm::sfence_vma(0, address.data()); 864fda81ceSLoGin } 874fda81ceSLoGin 884fda81ceSLoGin unsafe fn invalidate_all() { 897a29d4fcSLoGin riscv::asm::sfence_vma_all(); 904fda81ceSLoGin } 914fda81ceSLoGin 927a29d4fcSLoGin unsafe fn table(_table_kind: PageTableKind) -> PhysAddr { 937a29d4fcSLoGin // phys page number 947a29d4fcSLoGin let ppn = riscv::register::satp::read().ppn(); 957a29d4fcSLoGin 967a29d4fcSLoGin let paddr = PhysPageFrame::from_ppn(ppn).phys_address(); 977a29d4fcSLoGin 987a29d4fcSLoGin return paddr; 994fda81ceSLoGin } 1004fda81ceSLoGin 1017a29d4fcSLoGin unsafe fn set_table(_table_kind: PageTableKind, table: PhysAddr) { 1027a29d4fcSLoGin let ppn = PhysPageFrame::new(table).ppn(); 1037a29d4fcSLoGin riscv::asm::sfence_vma_all(); 1047a29d4fcSLoGin satp::set(satp::Mode::Sv39, 0, ppn); 1054fda81ceSLoGin } 1064fda81ceSLoGin 1074fda81ceSLoGin fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool { 1087a29d4fcSLoGin virt.is_canonical() 1094fda81ceSLoGin } 1104fda81ceSLoGin 1114fda81ceSLoGin fn initial_page_table() -> crate::mm::PhysAddr { 1124fda81ceSLoGin todo!() 1134fda81ceSLoGin } 1144fda81ceSLoGin 11591e9d4abSLoGin fn setup_new_usermapper() -> Result<crate::mm::ucontext::UserMapper, SystemError> { 1164fda81ceSLoGin todo!() 1174fda81ceSLoGin } 1187a29d4fcSLoGin 1197a29d4fcSLoGin unsafe fn phys_2_virt(phys: PhysAddr) -> Option<VirtAddr> { 1207a29d4fcSLoGin // riscv的内核文件所占用的空间,由于重定位而导致不满足线性偏移量的关系 1217a29d4fcSLoGin // 因此这里需要特殊处理 1227a29d4fcSLoGin if phys >= KERNEL_BEGIN_PA && phys < KERNEL_END_PA { 1237a29d4fcSLoGin let r = KERNEL_BEGIN_VA + (phys - KERNEL_BEGIN_PA); 1247a29d4fcSLoGin return Some(r); 1257a29d4fcSLoGin } 1267a29d4fcSLoGin 1277a29d4fcSLoGin if let Some(vaddr) = phys.data().checked_add(Self::PHYS_OFFSET) { 1287a29d4fcSLoGin return Some(VirtAddr::new(vaddr)); 1297a29d4fcSLoGin } else { 1307a29d4fcSLoGin return None; 1317a29d4fcSLoGin } 1327a29d4fcSLoGin } 1337a29d4fcSLoGin 1347a29d4fcSLoGin unsafe fn virt_2_phys(virt: VirtAddr) -> Option<PhysAddr> { 1357a29d4fcSLoGin if virt >= KERNEL_BEGIN_VA && virt < KERNEL_END_VA { 1367a29d4fcSLoGin let r = KERNEL_BEGIN_PA + (virt - KERNEL_BEGIN_VA); 1377a29d4fcSLoGin return Some(r); 1387a29d4fcSLoGin } 1397a29d4fcSLoGin 1407a29d4fcSLoGin if let Some(paddr) = virt.data().checked_sub(Self::PHYS_OFFSET) { 1417a29d4fcSLoGin let r = PhysAddr::new(paddr); 1427a29d4fcSLoGin return Some(r); 1437a29d4fcSLoGin } else { 1447a29d4fcSLoGin return None; 1457a29d4fcSLoGin } 1467a29d4fcSLoGin } 1477a29d4fcSLoGin 1487a29d4fcSLoGin fn make_entry(paddr: PhysAddr, page_flags: usize) -> usize { 1497a29d4fcSLoGin let ppn = PhysPageFrame::new(paddr).ppn(); 1507a29d4fcSLoGin let r = ((ppn & ((1 << 44) - 1)) << 10) | page_flags; 1517a29d4fcSLoGin return r; 1527a29d4fcSLoGin } 1537a29d4fcSLoGin } 1547a29d4fcSLoGin 1557a29d4fcSLoGin impl VirtAddr { 1567a29d4fcSLoGin /// 判断虚拟地址是否合法 1577a29d4fcSLoGin #[inline(always)] 1587a29d4fcSLoGin pub fn is_canonical(self) -> bool { 1597a29d4fcSLoGin let x = self.data() & RiscV64MMArch::PHYS_OFFSET; 1607a29d4fcSLoGin // 如果x为0,说明虚拟地址的高位为0,是合法的用户地址 1617a29d4fcSLoGin // 如果x为PHYS_OFFSET,说明虚拟地址的高位全为1,是合法的内核地址 1627a29d4fcSLoGin return x == 0 || x == RiscV64MMArch::PHYS_OFFSET; 1637a29d4fcSLoGin } 1644fda81ceSLoGin } 1654fda81ceSLoGin 1664fda81ceSLoGin /// 获取内核地址默认的页面标志 1674fda81ceSLoGin pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(virt: VirtAddr) -> PageFlags<A> { 1684fda81ceSLoGin unimplemented!("riscv64::kernel_page_flags") 1694fda81ceSLoGin } 1704fda81ceSLoGin 1714fda81ceSLoGin /// 全局的页帧分配器 1724fda81ceSLoGin #[derive(Debug, Clone, Copy, Hash)] 1734fda81ceSLoGin pub struct LockedFrameAllocator; 1744fda81ceSLoGin 1754fda81ceSLoGin impl FrameAllocator for LockedFrameAllocator { 1764fda81ceSLoGin unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> { 1774fda81ceSLoGin unimplemented!("RiscV64 LockedFrameAllocator::allocate") 1784fda81ceSLoGin } 1794fda81ceSLoGin 1804fda81ceSLoGin unsafe fn free(&mut self, address: crate::mm::PhysAddr, count: PageFrameCount) { 1814fda81ceSLoGin assert!(count.data().is_power_of_two()); 1824fda81ceSLoGin unimplemented!("RiscV64 LockedFrameAllocator::free") 1834fda81ceSLoGin } 1844fda81ceSLoGin 1854fda81ceSLoGin unsafe fn usage(&self) -> PageFrameUsage { 1864fda81ceSLoGin unimplemented!("RiscV64 LockedFrameAllocator::usage") 1874fda81ceSLoGin } 1884fda81ceSLoGin } 189