17a29d4fcSLoGin use riscv::register::satp; 291e9d4abSLoGin use system_error::SystemError; 391e9d4abSLoGin 4*453452ccSLoGin use crate::{ 5*453452ccSLoGin arch::MMArch, 6*453452ccSLoGin libs::spinlock::SpinLock, 7*453452ccSLoGin mm::{ 8*453452ccSLoGin allocator::{ 9*453452ccSLoGin buddy::BuddyAllocator, 10*453452ccSLoGin page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame}, 11*453452ccSLoGin }, 124fda81ceSLoGin page::PageFlags, 137a29d4fcSLoGin MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, 14*453452ccSLoGin }, 154fda81ceSLoGin }; 164fda81ceSLoGin 17*453452ccSLoGin use self::init::riscv_mm_init; 18*453452ccSLoGin 194fda81ceSLoGin pub mod bump; 20666cffedSLoGin pub(super) mod init; 214fda81ceSLoGin 224fda81ceSLoGin pub type PageMapper = crate::mm::page::PageMapper<RiscV64MMArch, LockedFrameAllocator>; 234fda81ceSLoGin 247a29d4fcSLoGin /// 内核起始物理地址 257a29d4fcSLoGin pub(self) static mut KERNEL_BEGIN_PA: PhysAddr = PhysAddr::new(0); 267a29d4fcSLoGin /// 内核结束的物理地址 277a29d4fcSLoGin pub(self) static mut KERNEL_END_PA: PhysAddr = PhysAddr::new(0); 287a29d4fcSLoGin /// 内核起始虚拟地址 297a29d4fcSLoGin pub(self) static mut KERNEL_BEGIN_VA: VirtAddr = VirtAddr::new(0); 307a29d4fcSLoGin /// 内核结束虚拟地址 317a29d4fcSLoGin pub(self) static mut KERNEL_END_VA: VirtAddr = VirtAddr::new(0); 327a29d4fcSLoGin 33*453452ccSLoGin pub(self) static INNER_ALLOCATOR: SpinLock<Option<BuddyAllocator<MMArch>>> = SpinLock::new(None); 34*453452ccSLoGin 3574ffde66SLoGin /// RiscV64的内存管理架构结构体(sv39) 364fda81ceSLoGin #[derive(Debug, Clone, Copy, Hash)] 374fda81ceSLoGin pub struct RiscV64MMArch; 384fda81ceSLoGin 3992849878SLoGin impl RiscV64MMArch { 4092849878SLoGin pub const ENTRY_FLAG_GLOBAL: usize = 1 << 5; 4192849878SLoGin } 424fda81ceSLoGin impl MemoryManagementArch for RiscV64MMArch { 434fda81ceSLoGin const PAGE_SHIFT: usize = 12; 444fda81ceSLoGin 454fda81ceSLoGin const PAGE_ENTRY_SHIFT: usize = 9; 464fda81ceSLoGin 474fda81ceSLoGin /// sv39分页只有三级 484fda81ceSLoGin const PAGE_LEVELS: usize = 3; 494fda81ceSLoGin 504fda81ceSLoGin const ENTRY_ADDRESS_SHIFT: usize = 39; 514fda81ceSLoGin 5292849878SLoGin const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT 5392849878SLoGin | Self::ENTRY_FLAG_READWRITE 5492849878SLoGin | Self::ENTRY_FLAG_DIRTY 5592849878SLoGin | Self::ENTRY_FLAG_ACCESSED 5692849878SLoGin | Self::ENTRY_FLAG_GLOBAL; 574fda81ceSLoGin 584fda81ceSLoGin const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT; 594fda81ceSLoGin 604fda81ceSLoGin const ENTRY_FLAG_PRESENT: usize = 1 << 0; 614fda81ceSLoGin 6292849878SLoGin const ENTRY_FLAG_READONLY: usize = 0; 634fda81ceSLoGin 644fda81ceSLoGin const ENTRY_FLAG_READWRITE: usize = (1 << 2) | (1 << 1); 654fda81ceSLoGin 664fda81ceSLoGin const ENTRY_FLAG_USER: usize = (1 << 4); 674fda81ceSLoGin 684fda81ceSLoGin const ENTRY_FLAG_WRITE_THROUGH: usize = (2 << 61); 694fda81ceSLoGin 704fda81ceSLoGin const ENTRY_FLAG_CACHE_DISABLE: usize = (2 << 61); 714fda81ceSLoGin 724fda81ceSLoGin const ENTRY_FLAG_NO_EXEC: usize = 0; 734fda81ceSLoGin 744fda81ceSLoGin const ENTRY_FLAG_EXEC: usize = (1 << 3); 7592849878SLoGin const ENTRY_FLAG_ACCESSED: usize = (1 << 6); 7692849878SLoGin const ENTRY_FLAG_DIRTY: usize = (1 << 7); 774fda81ceSLoGin 784fda81ceSLoGin const PHYS_OFFSET: usize = 0xffff_ffc0_0000_0000; 79*453452ccSLoGin const KERNEL_LINK_OFFSET: usize = 0x1000000; 804fda81ceSLoGin 814fda81ceSLoGin const USER_END_VADDR: crate::mm::VirtAddr = VirtAddr::new(0x0000_003f_ffff_ffff); 824fda81ceSLoGin 834fda81ceSLoGin const USER_BRK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffff_ffff); 844fda81ceSLoGin 854fda81ceSLoGin const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000); 864fda81ceSLoGin 8774ffde66SLoGin /// 在距离sv39的顶端还有1G的位置,设置为FIXMAP的起始地址 8874ffde66SLoGin const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000); 8974ffde66SLoGin /// 设置1MB的fixmap空间 9074ffde66SLoGin const FIXMAP_SIZE: usize = 256 * 4096; 9174ffde66SLoGin 92*453452ccSLoGin #[inline(never)] 9345626c85SLoGin unsafe fn init() { 94*453452ccSLoGin riscv_mm_init().expect("init kernel memory management architecture failed"); 954fda81ceSLoGin } 964fda81ceSLoGin 977a29d4fcSLoGin unsafe fn invalidate_page(address: VirtAddr) { 987a29d4fcSLoGin riscv::asm::sfence_vma(0, address.data()); 994fda81ceSLoGin } 1004fda81ceSLoGin 1014fda81ceSLoGin unsafe fn invalidate_all() { 1027a29d4fcSLoGin riscv::asm::sfence_vma_all(); 1034fda81ceSLoGin } 1044fda81ceSLoGin 1057a29d4fcSLoGin unsafe fn table(_table_kind: PageTableKind) -> PhysAddr { 1067a29d4fcSLoGin // phys page number 1077a29d4fcSLoGin let ppn = riscv::register::satp::read().ppn(); 1087a29d4fcSLoGin 1097a29d4fcSLoGin let paddr = PhysPageFrame::from_ppn(ppn).phys_address(); 1107a29d4fcSLoGin 1117a29d4fcSLoGin return paddr; 1124fda81ceSLoGin } 1134fda81ceSLoGin 1147a29d4fcSLoGin unsafe fn set_table(_table_kind: PageTableKind, table: PhysAddr) { 1157a29d4fcSLoGin let ppn = PhysPageFrame::new(table).ppn(); 1167a29d4fcSLoGin riscv::asm::sfence_vma_all(); 1177a29d4fcSLoGin satp::set(satp::Mode::Sv39, 0, ppn); 1184fda81ceSLoGin } 1194fda81ceSLoGin 1204fda81ceSLoGin fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool { 1217a29d4fcSLoGin virt.is_canonical() 1224fda81ceSLoGin } 1234fda81ceSLoGin 1244fda81ceSLoGin fn initial_page_table() -> crate::mm::PhysAddr { 1254fda81ceSLoGin todo!() 1264fda81ceSLoGin } 1274fda81ceSLoGin 12891e9d4abSLoGin fn setup_new_usermapper() -> Result<crate::mm::ucontext::UserMapper, SystemError> { 1294fda81ceSLoGin todo!() 1304fda81ceSLoGin } 1317a29d4fcSLoGin 1327a29d4fcSLoGin unsafe fn phys_2_virt(phys: PhysAddr) -> Option<VirtAddr> { 1337a29d4fcSLoGin // riscv的内核文件所占用的空间,由于重定位而导致不满足线性偏移量的关系 1347a29d4fcSLoGin // 因此这里需要特殊处理 1357a29d4fcSLoGin if phys >= KERNEL_BEGIN_PA && phys < KERNEL_END_PA { 1367a29d4fcSLoGin let r = KERNEL_BEGIN_VA + (phys - KERNEL_BEGIN_PA); 1377a29d4fcSLoGin return Some(r); 1387a29d4fcSLoGin } 1397a29d4fcSLoGin 1407a29d4fcSLoGin if let Some(vaddr) = phys.data().checked_add(Self::PHYS_OFFSET) { 1417a29d4fcSLoGin return Some(VirtAddr::new(vaddr)); 1427a29d4fcSLoGin } else { 1437a29d4fcSLoGin return None; 1447a29d4fcSLoGin } 1457a29d4fcSLoGin } 1467a29d4fcSLoGin 1477a29d4fcSLoGin unsafe fn virt_2_phys(virt: VirtAddr) -> Option<PhysAddr> { 1487a29d4fcSLoGin if virt >= KERNEL_BEGIN_VA && virt < KERNEL_END_VA { 1497a29d4fcSLoGin let r = KERNEL_BEGIN_PA + (virt - KERNEL_BEGIN_VA); 1507a29d4fcSLoGin return Some(r); 1517a29d4fcSLoGin } 1527a29d4fcSLoGin 1537a29d4fcSLoGin if let Some(paddr) = virt.data().checked_sub(Self::PHYS_OFFSET) { 1547a29d4fcSLoGin let r = PhysAddr::new(paddr); 1557a29d4fcSLoGin return Some(r); 1567a29d4fcSLoGin } else { 1577a29d4fcSLoGin return None; 1587a29d4fcSLoGin } 1597a29d4fcSLoGin } 1607a29d4fcSLoGin 1617a29d4fcSLoGin fn make_entry(paddr: PhysAddr, page_flags: usize) -> usize { 1627a29d4fcSLoGin let ppn = PhysPageFrame::new(paddr).ppn(); 163*453452ccSLoGin let r = ((ppn & ((1 << 54) - 1)) << 10) | page_flags; 1647a29d4fcSLoGin return r; 1657a29d4fcSLoGin } 1667a29d4fcSLoGin } 1677a29d4fcSLoGin 1687a29d4fcSLoGin impl VirtAddr { 1697a29d4fcSLoGin /// 判断虚拟地址是否合法 1707a29d4fcSLoGin #[inline(always)] 1717a29d4fcSLoGin pub fn is_canonical(self) -> bool { 1727a29d4fcSLoGin let x = self.data() & RiscV64MMArch::PHYS_OFFSET; 1737a29d4fcSLoGin // 如果x为0,说明虚拟地址的高位为0,是合法的用户地址 1747a29d4fcSLoGin // 如果x为PHYS_OFFSET,说明虚拟地址的高位全为1,是合法的内核地址 1757a29d4fcSLoGin return x == 0 || x == RiscV64MMArch::PHYS_OFFSET; 1767a29d4fcSLoGin } 1774fda81ceSLoGin } 1784fda81ceSLoGin 1794fda81ceSLoGin /// 获取内核地址默认的页面标志 180*453452ccSLoGin pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(_virt: VirtAddr) -> PageFlags<A> { 181*453452ccSLoGin PageFlags::from_data(RiscV64MMArch::ENTRY_FLAG_DEFAULT_PAGE) 182*453452ccSLoGin .set_user(false) 183*453452ccSLoGin .set_execute(true) 1844fda81ceSLoGin } 1854fda81ceSLoGin 1864fda81ceSLoGin /// 全局的页帧分配器 1874fda81ceSLoGin #[derive(Debug, Clone, Copy, Hash)] 1884fda81ceSLoGin pub struct LockedFrameAllocator; 1894fda81ceSLoGin 1904fda81ceSLoGin impl FrameAllocator for LockedFrameAllocator { 1914fda81ceSLoGin unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> { 192*453452ccSLoGin if let Some(ref mut allocator) = *INNER_ALLOCATOR.lock_irqsave() { 193*453452ccSLoGin return allocator.allocate(count); 194*453452ccSLoGin } else { 195*453452ccSLoGin return None; 196*453452ccSLoGin } 1974fda81ceSLoGin } 1984fda81ceSLoGin 1994fda81ceSLoGin unsafe fn free(&mut self, address: crate::mm::PhysAddr, count: PageFrameCount) { 2004fda81ceSLoGin assert!(count.data().is_power_of_two()); 201*453452ccSLoGin if let Some(ref mut allocator) = *INNER_ALLOCATOR.lock_irqsave() { 202*453452ccSLoGin return allocator.free(address, count); 203*453452ccSLoGin } 2044fda81ceSLoGin } 2054fda81ceSLoGin 2064fda81ceSLoGin unsafe fn usage(&self) -> PageFrameUsage { 207*453452ccSLoGin if let Some(ref mut allocator) = *INNER_ALLOCATOR.lock_irqsave() { 208*453452ccSLoGin return allocator.usage(); 209*453452ccSLoGin } else { 210*453452ccSLoGin panic!("usage error"); 211*453452ccSLoGin } 2124fda81ceSLoGin } 2134fda81ceSLoGin } 214