1pub use page_table_generic::{PageTableEntry, TableMeta};
4#[cfg(target_arch = "x86_64")]
5pub use x86_64::structures::paging::{PageOffset, PageTableIndex, page_table::PageTableLevel};
6
7use crate::VirtAddr;
8
9bitflags::bitflags! {
10 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
12 pub struct MappingFlags: usize {
13 const READ = 1 << 0;
15 const WRITE = 1 << 1;
17 const EXECUTE = 1 << 2;
19 const USER = 1 << 3;
21 const DEVICE = 1 << 4;
23 const UNCACHED = 1 << 5;
25 }
26}
27
28impl From<crate::trap::PageFaultFlags> for MappingFlags {
29 fn from(fault: crate::trap::PageFaultFlags) -> Self {
30 let mut flags = Self::empty();
31 flags.set(
32 Self::READ,
33 fault.contains(crate::trap::PageFaultFlags::READ),
34 );
35 flags.set(
36 Self::WRITE,
37 fault.contains(crate::trap::PageFaultFlags::WRITE),
38 );
39 flags.set(
40 Self::EXECUTE,
41 fault.contains(crate::trap::PageFaultFlags::EXECUTE),
42 );
43 flags.set(
44 Self::USER,
45 fault.contains(crate::trap::PageFaultFlags::USER),
46 );
47 flags
48 }
49}
50
51pub use crate::arch::current::paging::{DescriptorFlags, Pte};
52#[cfg(target_arch = "aarch64")]
53pub use crate::arch::current::paging::{
54 El1Pte, El2PagingMeta, El2Pte, Stage1Pte, Stage1Regime, Stage2Pte,
55};
56#[cfg(target_arch = "x86_64")]
57pub use crate::arch::current::paging::{EptEntry, EptFlags, EptMemoryType, NptEntry};
58use crate::arch::current::paging::{
59 LEVEL_BITS as ARCH_LEVEL_BITS, MAX_BLOCK_LEVEL as ARCH_MAX_BLOCK_LEVEL,
60 PAGE_SIZE as ARCH_PAGE_SIZE,
61};
62
63#[derive(Clone, Copy)]
65pub struct ArchPagingMeta;
66
67impl TableMeta for ArchPagingMeta {
68 type P = Pte;
69
70 const PAGE_SIZE: usize = ARCH_PAGE_SIZE;
71 const LEVEL_BITS: &'static [usize] = ARCH_LEVEL_BITS;
72 const MAX_BLOCK_LEVEL: usize = ARCH_MAX_BLOCK_LEVEL;
73
74 fn canonicalize_vaddr(vaddr: VirtAddr) -> VirtAddr {
75 let address_bits = ARCH_PAGE_SIZE.trailing_zeros() as usize
76 + ARCH_LEVEL_BITS.iter().copied().sum::<usize>();
77 let mask = (1usize << address_bits) - 1;
78 let address = vaddr.as_usize() & mask;
79 if address & (1usize << (address_bits - 1)) == 0 {
80 VirtAddr::from_usize(address)
81 } else {
82 VirtAddr::from_usize(address | !mask)
83 }
84 }
85
86 fn flush(vaddr: Option<VirtAddr>) {
87 crate::asm::flush_tlb(vaddr);
88 }
89}