1use ax_memory_addr::VirtAddr;
4use page_table_generic::TableMeta;
5
6bitflags::bitflags! {
7 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
9 pub struct MappingFlags: usize {
10 const READ = 1 << 0;
12 const WRITE = 1 << 1;
14 const EXECUTE = 1 << 2;
16 const USER = 1 << 3;
18 const DEVICE = 1 << 4;
20 const UNCACHED = 1 << 5;
22 }
23}
24
25impl From<crate::trap::PageFaultFlags> for MappingFlags {
26 fn from(fault: crate::trap::PageFaultFlags) -> Self {
27 let mut flags = Self::empty();
28 flags.set(
29 Self::READ,
30 fault.contains(crate::trap::PageFaultFlags::READ),
31 );
32 flags.set(
33 Self::WRITE,
34 fault.contains(crate::trap::PageFaultFlags::WRITE),
35 );
36 flags.set(
37 Self::EXECUTE,
38 fault.contains(crate::trap::PageFaultFlags::EXECUTE),
39 );
40 flags.set(
41 Self::USER,
42 fault.contains(crate::trap::PageFaultFlags::USER),
43 );
44 flags
45 }
46}
47
48cfg_if::cfg_if! {
49 if #[cfg(target_arch = "x86_64")] {
50 use crate::x86_64::paging::{
51 LEVEL_BITS as ARCH_LEVEL_BITS, MAX_BLOCK_LEVEL as ARCH_MAX_BLOCK_LEVEL,
52 PAGE_SIZE as ARCH_PAGE_SIZE, X64Pte as ArchPte,
53 };
54 } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] {
55 use crate::riscv::paging::{
56 LEVEL_BITS as ARCH_LEVEL_BITS, MAX_BLOCK_LEVEL as ARCH_MAX_BLOCK_LEVEL,
57 PAGE_SIZE as ARCH_PAGE_SIZE, Rv64Pte as ArchPte,
58 };
59 } else if #[cfg(target_arch = "aarch64")] {
60 use crate::aarch64::paging::{
61 A64Pte as ArchPte, LEVEL_BITS as ARCH_LEVEL_BITS,
62 MAX_BLOCK_LEVEL as ARCH_MAX_BLOCK_LEVEL, PAGE_SIZE as ARCH_PAGE_SIZE,
63 };
64 } else if #[cfg(target_arch = "loongarch64")] {
65 use crate::loongarch64::paging::{
66 LEVEL_BITS as ARCH_LEVEL_BITS, La64Pte as ArchPte,
67 MAX_BLOCK_LEVEL as ARCH_MAX_BLOCK_LEVEL, PAGE_SIZE as ARCH_PAGE_SIZE,
68 };
69 }
70}
71
72#[derive(Clone, Copy)]
74pub struct ArchPagingMeta;
75
76impl TableMeta for ArchPagingMeta {
77 type P = ArchPte;
78
79 const PAGE_SIZE: usize = ARCH_PAGE_SIZE;
80 const LEVEL_BITS: &'static [usize] = ARCH_LEVEL_BITS;
81 const MAX_BLOCK_LEVEL: usize = ARCH_MAX_BLOCK_LEVEL;
82
83 fn canonicalize_vaddr(vaddr: VirtAddr) -> VirtAddr {
84 let address_bits = ARCH_PAGE_SIZE.trailing_zeros() as usize
85 + ARCH_LEVEL_BITS.iter().copied().sum::<usize>();
86 let mask = (1usize << address_bits) - 1;
87 let address = vaddr.as_usize() & mask;
88 if address & (1usize << (address_bits - 1)) == 0 {
89 VirtAddr::from_usize(address)
90 } else {
91 VirtAddr::from_usize(address | !mask)
92 }
93 }
94
95 fn flush(vaddr: Option<VirtAddr>) {
96 crate::asm::flush_tlb(vaddr);
97 }
98}