xref: /DragonOS/kernel/src/arch/riscv64/mm/mod.rs (revision 7a29d4fcbcd89a226289c7bf541c2c78623de3ad)
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