17a29d4fcSLoGin use riscv::register::satp;
270f159a3SLoGin use sbi_rt::{HartMask, SbiRet};
391e9d4abSLoGin use system_error::SystemError;
491e9d4abSLoGin
5453452ccSLoGin use crate::{
6453452ccSLoGin arch::MMArch,
723ef2b33SLoGin driver::open_firmware::fdt::open_firmware_fdt_driver,
8453452ccSLoGin libs::spinlock::SpinLock,
9453452ccSLoGin mm::{
10453452ccSLoGin allocator::{
11453452ccSLoGin buddy::BuddyAllocator,
12453452ccSLoGin page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame},
13453452ccSLoGin },
1470f159a3SLoGin kernel_mapper::KernelMapper,
15*cf7f801eSMemoryShore page::{EntryFlags, PageEntry, PAGE_1G_SHIFT},
1670f159a3SLoGin ucontext::UserMapper,
17*cf7f801eSMemoryShore MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, VmFlags,
18453452ccSLoGin },
1970f159a3SLoGin smp::cpu::ProcessorId,
204fda81ceSLoGin };
214fda81ceSLoGin
22f75cb0f8SLoGin use self::init::{riscv_mm_init, INITIAL_PGTABLE_VALUE};
23453452ccSLoGin
244fda81ceSLoGin pub mod bump;
25666cffedSLoGin pub(super) mod init;
264fda81ceSLoGin
274fda81ceSLoGin pub type PageMapper = crate::mm::page::PageMapper<RiscV64MMArch, LockedFrameAllocator>;
284fda81ceSLoGin
297a29d4fcSLoGin /// 内核起始物理地址
307a29d4fcSLoGin pub(self) static mut KERNEL_BEGIN_PA: PhysAddr = PhysAddr::new(0);
317a29d4fcSLoGin /// 内核结束的物理地址
327a29d4fcSLoGin pub(self) static mut KERNEL_END_PA: PhysAddr = PhysAddr::new(0);
337a29d4fcSLoGin /// 内核起始虚拟地址
347a29d4fcSLoGin pub(self) static mut KERNEL_BEGIN_VA: VirtAddr = VirtAddr::new(0);
357a29d4fcSLoGin /// 内核结束虚拟地址
367a29d4fcSLoGin pub(self) static mut KERNEL_END_VA: VirtAddr = VirtAddr::new(0);
377a29d4fcSLoGin
38453452ccSLoGin pub(self) static INNER_ALLOCATOR: SpinLock<Option<BuddyAllocator<MMArch>>> = SpinLock::new(None);
39453452ccSLoGin
4074ffde66SLoGin /// RiscV64的内存管理架构结构体(sv39)
414fda81ceSLoGin #[derive(Debug, Clone, Copy, Hash)]
424fda81ceSLoGin pub struct RiscV64MMArch;
434fda81ceSLoGin
4492849878SLoGin impl RiscV64MMArch {
4570f159a3SLoGin /// 使远程cpu的TLB中,指定地址范围的页失效
460102d69fSLoGin #[allow(dead_code)]
remote_invalidate_page( cpu: ProcessorId, address: VirtAddr, size: usize, ) -> Result<(), SbiRet>4770f159a3SLoGin pub fn remote_invalidate_page(
4870f159a3SLoGin cpu: ProcessorId,
4970f159a3SLoGin address: VirtAddr,
5070f159a3SLoGin size: usize,
5170f159a3SLoGin ) -> Result<(), SbiRet> {
5270f159a3SLoGin let r = sbi_rt::remote_sfence_vma(Into::into(cpu), address.data(), size);
5370f159a3SLoGin if r.is_ok() {
5470f159a3SLoGin return Ok(());
5570f159a3SLoGin } else {
5670f159a3SLoGin return Err(r);
5792849878SLoGin }
5870f159a3SLoGin }
5970f159a3SLoGin
6070f159a3SLoGin /// 使指定远程cpu的TLB中,所有范围的页失效
610102d69fSLoGin #[allow(dead_code)]
remote_invalidate_all(cpu: ProcessorId) -> Result<(), SbiRet>6270f159a3SLoGin pub fn remote_invalidate_all(cpu: ProcessorId) -> Result<(), SbiRet> {
6370f159a3SLoGin let r = Self::remote_invalidate_page(
6470f159a3SLoGin cpu,
6570f159a3SLoGin VirtAddr::new(0),
6670f159a3SLoGin 1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT,
6770f159a3SLoGin );
6870f159a3SLoGin
6970f159a3SLoGin return r;
7070f159a3SLoGin }
7170f159a3SLoGin
remote_invalidate_all_with_mask(mask: HartMask) -> Result<(), SbiRet>7270f159a3SLoGin pub fn remote_invalidate_all_with_mask(mask: HartMask) -> Result<(), SbiRet> {
7370f159a3SLoGin let r = sbi_rt::remote_sfence_vma(mask, 0, 1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT);
7470f159a3SLoGin if r.is_ok() {
7570f159a3SLoGin return Ok(());
7670f159a3SLoGin } else {
7770f159a3SLoGin return Err(r);
7870f159a3SLoGin }
7970f159a3SLoGin }
8070f159a3SLoGin }
8170f159a3SLoGin
8270f159a3SLoGin /// 内核空间起始地址在顶层页表中的索引
8370f159a3SLoGin const KERNEL_TOP_PAGE_ENTRY_NO: usize = (RiscV64MMArch::PHYS_OFFSET
8470f159a3SLoGin & ((1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT) - 1))
8570f159a3SLoGin >> (RiscV64MMArch::ENTRY_ADDRESS_SHIFT - RiscV64MMArch::PAGE_ENTRY_SHIFT);
8670f159a3SLoGin
874fda81ceSLoGin impl MemoryManagementArch for RiscV64MMArch {
88a17651b1SMemoryShore /// riscv64暂不支持缺页中断
89a17651b1SMemoryShore const PAGE_FAULT_ENABLED: bool = false;
90a17651b1SMemoryShore
914fda81ceSLoGin const PAGE_SHIFT: usize = 12;
924fda81ceSLoGin
934fda81ceSLoGin const PAGE_ENTRY_SHIFT: usize = 9;
944fda81ceSLoGin
954fda81ceSLoGin /// sv39分页只有三级
964fda81ceSLoGin const PAGE_LEVELS: usize = 3;
974fda81ceSLoGin
984fda81ceSLoGin const ENTRY_ADDRESS_SHIFT: usize = 39;
994fda81ceSLoGin
10092849878SLoGin const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT
10192849878SLoGin | Self::ENTRY_FLAG_READWRITE
10292849878SLoGin | Self::ENTRY_FLAG_DIRTY
10392849878SLoGin | Self::ENTRY_FLAG_ACCESSED
10492849878SLoGin | Self::ENTRY_FLAG_GLOBAL;
1054fda81ceSLoGin
1064fda81ceSLoGin const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT;
1074fda81ceSLoGin
1084fda81ceSLoGin const ENTRY_FLAG_PRESENT: usize = 1 << 0;
1094fda81ceSLoGin
110471d65cfSLoGin const ENTRY_FLAG_READONLY: usize = (1 << 1);
111471d65cfSLoGin
112471d65cfSLoGin const ENTRY_FLAG_WRITEABLE: usize = (1 << 2);
1134fda81ceSLoGin
1144fda81ceSLoGin const ENTRY_FLAG_READWRITE: usize = (1 << 2) | (1 << 1);
1154fda81ceSLoGin
1164fda81ceSLoGin const ENTRY_FLAG_USER: usize = (1 << 4);
117731bc2b3SLoGin const ENTRY_ADDRESS_MASK: usize = Self::ENTRY_ADDRESS_SIZE - (1 << 10);
1184fda81ceSLoGin const ENTRY_FLAG_WRITE_THROUGH: usize = (2 << 61);
1194fda81ceSLoGin
1204fda81ceSLoGin const ENTRY_FLAG_CACHE_DISABLE: usize = (2 << 61);
1214fda81ceSLoGin
1224fda81ceSLoGin const ENTRY_FLAG_NO_EXEC: usize = 0;
1234fda81ceSLoGin
1244fda81ceSLoGin const ENTRY_FLAG_EXEC: usize = (1 << 3);
12592849878SLoGin const ENTRY_FLAG_ACCESSED: usize = (1 << 6);
12692849878SLoGin const ENTRY_FLAG_DIRTY: usize = (1 << 7);
127a17651b1SMemoryShore const ENTRY_FLAG_GLOBAL: usize = (1 << 5);
1284fda81ceSLoGin
1294fda81ceSLoGin const PHYS_OFFSET: usize = 0xffff_ffc0_0000_0000;
130453452ccSLoGin const KERNEL_LINK_OFFSET: usize = 0x1000000;
1314fda81ceSLoGin
1324fda81ceSLoGin const USER_END_VADDR: crate::mm::VirtAddr = VirtAddr::new(0x0000_003f_ffff_ffff);
1334fda81ceSLoGin
1344fda81ceSLoGin const USER_BRK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffff_ffff);
1354fda81ceSLoGin
1364fda81ceSLoGin const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000);
1374fda81ceSLoGin
13823ef2b33SLoGin /// 在距离sv39的顶端还有64M的位置,设置为FIXMAP的起始地址
13923ef2b33SLoGin const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_fc00_0000);
14074ffde66SLoGin /// 设置1MB的fixmap空间
14174ffde66SLoGin const FIXMAP_SIZE: usize = 256 * 4096;
14274ffde66SLoGin
14323ef2b33SLoGin /// 在距离sv39的顶端还有2G的位置,设置为MMIO空间的起始地址
14423ef2b33SLoGin const MMIO_BASE: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000);
14523ef2b33SLoGin /// 设置1g的MMIO空间
14623ef2b33SLoGin const MMIO_SIZE: usize = 1 << PAGE_1G_SHIFT;
14723ef2b33SLoGin
148a17651b1SMemoryShore const ENTRY_FLAG_HUGE_PAGE: usize = Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READWRITE;
149a17651b1SMemoryShore
150453452ccSLoGin #[inline(never)]
init()15145626c85SLoGin unsafe fn init() {
152453452ccSLoGin riscv_mm_init().expect("init kernel memory management architecture failed");
1534fda81ceSLoGin }
1544fda81ceSLoGin
arch_post_init()15523ef2b33SLoGin unsafe fn arch_post_init() {
15623ef2b33SLoGin // 映射fdt
15723ef2b33SLoGin open_firmware_fdt_driver()
15823ef2b33SLoGin .map_fdt()
15923ef2b33SLoGin .expect("openfirmware map fdt failed");
16023ef2b33SLoGin }
16123ef2b33SLoGin
invalidate_page(address: VirtAddr)1627a29d4fcSLoGin unsafe fn invalidate_page(address: VirtAddr) {
1637a29d4fcSLoGin riscv::asm::sfence_vma(0, address.data());
1644fda81ceSLoGin }
1654fda81ceSLoGin
invalidate_all()1664fda81ceSLoGin unsafe fn invalidate_all() {
1677a29d4fcSLoGin riscv::asm::sfence_vma_all();
1684fda81ceSLoGin }
1694fda81ceSLoGin
table(_table_kind: PageTableKind) -> PhysAddr1707a29d4fcSLoGin unsafe fn table(_table_kind: PageTableKind) -> PhysAddr {
1717a29d4fcSLoGin // phys page number
1727a29d4fcSLoGin let ppn = riscv::register::satp::read().ppn();
1737a29d4fcSLoGin
1747a29d4fcSLoGin let paddr = PhysPageFrame::from_ppn(ppn).phys_address();
1757a29d4fcSLoGin
1767a29d4fcSLoGin return paddr;
1774fda81ceSLoGin }
1784fda81ceSLoGin
set_table(_table_kind: PageTableKind, table: PhysAddr)1797a29d4fcSLoGin unsafe fn set_table(_table_kind: PageTableKind, table: PhysAddr) {
1807a29d4fcSLoGin let ppn = PhysPageFrame::new(table).ppn();
1817a29d4fcSLoGin riscv::asm::sfence_vma_all();
1827a29d4fcSLoGin satp::set(satp::Mode::Sv39, 0, ppn);
1834fda81ceSLoGin }
1844fda81ceSLoGin
virt_is_valid(virt: VirtAddr) -> bool18570f159a3SLoGin fn virt_is_valid(virt: VirtAddr) -> bool {
1867a29d4fcSLoGin virt.is_canonical()
1874fda81ceSLoGin }
1884fda81ceSLoGin
initial_page_table() -> PhysAddr18970f159a3SLoGin fn initial_page_table() -> PhysAddr {
190f75cb0f8SLoGin unsafe { INITIAL_PGTABLE_VALUE }
1914fda81ceSLoGin }
1924fda81ceSLoGin
setup_new_usermapper() -> Result<UserMapper, SystemError>19370f159a3SLoGin fn setup_new_usermapper() -> Result<UserMapper, SystemError> {
19470f159a3SLoGin let new_umapper: crate::mm::page::PageMapper<MMArch, LockedFrameAllocator> = unsafe {
19570f159a3SLoGin PageMapper::create(PageTableKind::User, LockedFrameAllocator)
19670f159a3SLoGin .ok_or(SystemError::ENOMEM)?
19770f159a3SLoGin };
19870f159a3SLoGin
19970f159a3SLoGin let current_ktable: KernelMapper = KernelMapper::lock();
20070f159a3SLoGin let copy_mapping = |pml4_entry_no| unsafe {
20170f159a3SLoGin let entry: PageEntry<RiscV64MMArch> = current_ktable
20270f159a3SLoGin .table()
20370f159a3SLoGin .entry(pml4_entry_no)
20470f159a3SLoGin .unwrap_or_else(|| panic!("entry {} not found", pml4_entry_no));
20570f159a3SLoGin new_umapper.table().set_entry(pml4_entry_no, entry)
20670f159a3SLoGin };
20770f159a3SLoGin
20870f159a3SLoGin // 复制内核的映射
20970f159a3SLoGin for pml4_entry_no in KERNEL_TOP_PAGE_ENTRY_NO..512 {
21070f159a3SLoGin copy_mapping(pml4_entry_no);
21170f159a3SLoGin }
21270f159a3SLoGin
21370f159a3SLoGin return Ok(crate::mm::ucontext::UserMapper::new(new_umapper));
2144fda81ceSLoGin }
2157a29d4fcSLoGin
phys_2_virt(phys: PhysAddr) -> Option<VirtAddr>2167a29d4fcSLoGin unsafe fn phys_2_virt(phys: PhysAddr) -> Option<VirtAddr> {
2177a29d4fcSLoGin // riscv的内核文件所占用的空间,由于重定位而导致不满足线性偏移量的关系
2187a29d4fcSLoGin // 因此这里需要特殊处理
2197a29d4fcSLoGin if phys >= KERNEL_BEGIN_PA && phys < KERNEL_END_PA {
2207a29d4fcSLoGin let r = KERNEL_BEGIN_VA + (phys - KERNEL_BEGIN_PA);
2217a29d4fcSLoGin return Some(r);
2227a29d4fcSLoGin }
2237a29d4fcSLoGin
2247a29d4fcSLoGin if let Some(vaddr) = phys.data().checked_add(Self::PHYS_OFFSET) {
2257a29d4fcSLoGin return Some(VirtAddr::new(vaddr));
2267a29d4fcSLoGin } else {
2277a29d4fcSLoGin return None;
2287a29d4fcSLoGin }
2297a29d4fcSLoGin }
2307a29d4fcSLoGin
virt_2_phys(virt: VirtAddr) -> Option<PhysAddr>2317a29d4fcSLoGin unsafe fn virt_2_phys(virt: VirtAddr) -> Option<PhysAddr> {
2327a29d4fcSLoGin if virt >= KERNEL_BEGIN_VA && virt < KERNEL_END_VA {
2337a29d4fcSLoGin let r = KERNEL_BEGIN_PA + (virt - KERNEL_BEGIN_VA);
2347a29d4fcSLoGin return Some(r);
2357a29d4fcSLoGin }
2367a29d4fcSLoGin
2377a29d4fcSLoGin if let Some(paddr) = virt.data().checked_sub(Self::PHYS_OFFSET) {
2387a29d4fcSLoGin let r = PhysAddr::new(paddr);
2397a29d4fcSLoGin return Some(r);
2407a29d4fcSLoGin } else {
2417a29d4fcSLoGin return None;
2427a29d4fcSLoGin }
2437a29d4fcSLoGin }
2447a29d4fcSLoGin
make_entry(paddr: PhysAddr, page_flags: usize) -> usize2457a29d4fcSLoGin fn make_entry(paddr: PhysAddr, page_flags: usize) -> usize {
2467a29d4fcSLoGin let ppn = PhysPageFrame::new(paddr).ppn();
247453452ccSLoGin let r = ((ppn & ((1 << 54) - 1)) << 10) | page_flags;
2487a29d4fcSLoGin return r;
2497a29d4fcSLoGin }
250a17651b1SMemoryShore
vma_access_permitted( _vma: alloc::sync::Arc<crate::mm::ucontext::LockedVMA>, _write: bool, _execute: bool, _foreign: bool, ) -> bool251a17651b1SMemoryShore fn vma_access_permitted(
252a17651b1SMemoryShore _vma: alloc::sync::Arc<crate::mm::ucontext::LockedVMA>,
253a17651b1SMemoryShore _write: bool,
254a17651b1SMemoryShore _execute: bool,
255a17651b1SMemoryShore _foreign: bool,
256a17651b1SMemoryShore ) -> bool {
257a17651b1SMemoryShore true
258a17651b1SMemoryShore }
259*cf7f801eSMemoryShore
260*cf7f801eSMemoryShore const PAGE_NONE: usize = Self::ENTRY_FLAG_GLOBAL | Self::ENTRY_FLAG_READONLY;
261*cf7f801eSMemoryShore
262*cf7f801eSMemoryShore const PAGE_READ: usize = PAGE_ENTRY_BASE | Self::ENTRY_FLAG_READONLY;
263*cf7f801eSMemoryShore
264*cf7f801eSMemoryShore const PAGE_WRITE: usize =
265*cf7f801eSMemoryShore PAGE_ENTRY_BASE | Self::ENTRY_FLAG_READONLY | Self::ENTRY_FLAG_WRITEABLE;
266*cf7f801eSMemoryShore
267*cf7f801eSMemoryShore const PAGE_EXEC: usize = PAGE_ENTRY_BASE | Self::ENTRY_FLAG_EXEC;
268*cf7f801eSMemoryShore
269*cf7f801eSMemoryShore const PAGE_READ_EXEC: usize =
270*cf7f801eSMemoryShore PAGE_ENTRY_BASE | Self::ENTRY_FLAG_READONLY | Self::ENTRY_FLAG_EXEC;
271*cf7f801eSMemoryShore
272*cf7f801eSMemoryShore const PAGE_WRITE_EXEC: usize = PAGE_ENTRY_BASE
273*cf7f801eSMemoryShore | Self::ENTRY_FLAG_READONLY
274*cf7f801eSMemoryShore | Self::ENTRY_FLAG_EXEC
275*cf7f801eSMemoryShore | Self::ENTRY_FLAG_WRITEABLE;
276*cf7f801eSMemoryShore
277*cf7f801eSMemoryShore const PAGE_COPY: usize = Self::PAGE_READ;
278*cf7f801eSMemoryShore const PAGE_COPY_EXEC: usize = Self::PAGE_READ_EXEC;
279*cf7f801eSMemoryShore const PAGE_SHARED: usize = Self::PAGE_WRITE;
280*cf7f801eSMemoryShore const PAGE_SHARED_EXEC: usize = Self::PAGE_WRITE_EXEC;
281*cf7f801eSMemoryShore
282*cf7f801eSMemoryShore const PAGE_COPY_NOEXEC: usize = 0;
283*cf7f801eSMemoryShore const PAGE_READONLY: usize = 0;
284*cf7f801eSMemoryShore const PAGE_READONLY_EXEC: usize = 0;
285*cf7f801eSMemoryShore
286*cf7f801eSMemoryShore const PROTECTION_MAP: [EntryFlags<MMArch>; 16] = protection_map();
2877a29d4fcSLoGin }
2887a29d4fcSLoGin
protection_map() -> [EntryFlags<MMArch>; 16]289*cf7f801eSMemoryShore const fn protection_map() -> [EntryFlags<MMArch>; 16] {
290*cf7f801eSMemoryShore let mut map = [0; 16];
291*cf7f801eSMemoryShore map[VmFlags::VM_NONE.bits()] = MMArch::PAGE_NONE;
292*cf7f801eSMemoryShore map[VmFlags::VM_READ.bits()] = MMArch::PAGE_READONLY;
293*cf7f801eSMemoryShore map[VmFlags::VM_WRITE.bits()] = MMArch::PAGE_COPY;
294*cf7f801eSMemoryShore map[VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] = MMArch::PAGE_COPY;
295*cf7f801eSMemoryShore map[VmFlags::VM_EXEC.bits()] = MMArch::PAGE_READONLY_EXEC;
296*cf7f801eSMemoryShore map[VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] = MMArch::PAGE_READONLY_EXEC;
297*cf7f801eSMemoryShore map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] = MMArch::PAGE_COPY_EXEC;
298*cf7f801eSMemoryShore map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
299*cf7f801eSMemoryShore MMArch::PAGE_COPY_EXEC;
300*cf7f801eSMemoryShore map[VmFlags::VM_SHARED.bits()] = MMArch::PAGE_NONE;
301*cf7f801eSMemoryShore map[VmFlags::VM_SHARED.bits() | VmFlags::VM_READ.bits()] = MMArch::PAGE_READONLY;
302*cf7f801eSMemoryShore map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits()] = MMArch::PAGE_SHARED;
303*cf7f801eSMemoryShore map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
304*cf7f801eSMemoryShore MMArch::PAGE_SHARED;
305*cf7f801eSMemoryShore map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits()] = MMArch::PAGE_READONLY_EXEC;
306*cf7f801eSMemoryShore map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] =
307*cf7f801eSMemoryShore MMArch::PAGE_READONLY_EXEC;
308*cf7f801eSMemoryShore map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] =
309*cf7f801eSMemoryShore MMArch::PAGE_SHARED_EXEC;
310*cf7f801eSMemoryShore map[VmFlags::VM_SHARED.bits()
311*cf7f801eSMemoryShore | VmFlags::VM_EXEC.bits()
312*cf7f801eSMemoryShore | VmFlags::VM_WRITE.bits()
313*cf7f801eSMemoryShore | VmFlags::VM_READ.bits()] = MMArch::PAGE_SHARED_EXEC;
314*cf7f801eSMemoryShore let mut ret = [unsafe { EntryFlags::from_data(0) }; 16];
315*cf7f801eSMemoryShore let mut index = 0;
316*cf7f801eSMemoryShore while index < 16 {
317*cf7f801eSMemoryShore ret[index] = unsafe { EntryFlags::from_data(map[index]) };
318*cf7f801eSMemoryShore index += 1;
319*cf7f801eSMemoryShore }
320*cf7f801eSMemoryShore ret
321*cf7f801eSMemoryShore }
322*cf7f801eSMemoryShore
323*cf7f801eSMemoryShore const PAGE_ENTRY_BASE: usize = RiscV64MMArch::ENTRY_FLAG_PRESENT
324*cf7f801eSMemoryShore | RiscV64MMArch::ENTRY_FLAG_ACCESSED
325*cf7f801eSMemoryShore | RiscV64MMArch::ENTRY_FLAG_USER;
326*cf7f801eSMemoryShore
3277a29d4fcSLoGin impl VirtAddr {
3287a29d4fcSLoGin /// 判断虚拟地址是否合法
3297a29d4fcSLoGin #[inline(always)]
is_canonical(self) -> bool3307a29d4fcSLoGin pub fn is_canonical(self) -> bool {
3317a29d4fcSLoGin let x = self.data() & RiscV64MMArch::PHYS_OFFSET;
3327a29d4fcSLoGin // 如果x为0,说明虚拟地址的高位为0,是合法的用户地址
3337a29d4fcSLoGin // 如果x为PHYS_OFFSET,说明虚拟地址的高位全为1,是合法的内核地址
3347a29d4fcSLoGin return x == 0 || x == RiscV64MMArch::PHYS_OFFSET;
3357a29d4fcSLoGin }
3364fda81ceSLoGin }
3374fda81ceSLoGin
3384fda81ceSLoGin /// 获取内核地址默认的页面标志
kernel_page_flags<A: MemoryManagementArch>(_virt: VirtAddr) -> EntryFlags<A>339*cf7f801eSMemoryShore pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(_virt: VirtAddr) -> EntryFlags<A> {
340*cf7f801eSMemoryShore EntryFlags::from_data(RiscV64MMArch::ENTRY_FLAG_DEFAULT_PAGE)
341453452ccSLoGin .set_user(false)
342453452ccSLoGin .set_execute(true)
3434fda81ceSLoGin }
3444fda81ceSLoGin
3454fda81ceSLoGin /// 全局的页帧分配器
3464fda81ceSLoGin #[derive(Debug, Clone, Copy, Hash)]
3474fda81ceSLoGin pub struct LockedFrameAllocator;
3484fda81ceSLoGin
3494fda81ceSLoGin impl FrameAllocator for LockedFrameAllocator {
allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)>3504fda81ceSLoGin unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
351453452ccSLoGin if let Some(ref mut allocator) = *INNER_ALLOCATOR.lock_irqsave() {
352453452ccSLoGin return allocator.allocate(count);
353453452ccSLoGin } else {
354453452ccSLoGin return None;
355453452ccSLoGin }
3564fda81ceSLoGin }
3574fda81ceSLoGin
free(&mut self, address: crate::mm::PhysAddr, count: PageFrameCount)3584fda81ceSLoGin unsafe fn free(&mut self, address: crate::mm::PhysAddr, count: PageFrameCount) {
3594fda81ceSLoGin assert!(count.data().is_power_of_two());
360453452ccSLoGin if let Some(ref mut allocator) = *INNER_ALLOCATOR.lock_irqsave() {
361453452ccSLoGin return allocator.free(address, count);
362453452ccSLoGin }
3634fda81ceSLoGin }
3644fda81ceSLoGin
usage(&self) -> PageFrameUsage3654fda81ceSLoGin unsafe fn usage(&self) -> PageFrameUsage {
366453452ccSLoGin if let Some(ref mut allocator) = *INNER_ALLOCATOR.lock_irqsave() {
367453452ccSLoGin return allocator.usage();
368453452ccSLoGin } else {
369453452ccSLoGin panic!("usage error");
370453452ccSLoGin }
3714fda81ceSLoGin }
3724fda81ceSLoGin }
373