1#[cfg(feature = "uspace")]
4pub use crate::arch::current::asm::install_user_address_space;
5pub use crate::arch::current::asm::{
6 address_space_tag_capacity, flush_tlb, read_kernel_page_table, read_user_page_table,
7 write_kernel_page_table, write_user_page_table,
8};
9
10#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13pub struct HardwareAddressSpace {
14 root: ax_memory_addr::PhysAddr,
15 tag: u16,
16}
17
18impl HardwareAddressSpace {
19 pub const fn new(root: ax_memory_addr::PhysAddr, tag: u16) -> Self {
22 Self { root, tag }
23 }
24
25 pub const fn root(self) -> ax_memory_addr::PhysAddr {
27 self.root
28 }
29
30 pub const fn hardware_tag(self) -> u16 {
32 self.tag
33 }
34}
35
36pub fn flush_tlb_range(start: crate::VirtAddr, size: usize) {
43 flush_range_with(start, size, flush_tlb);
44}
45
46pub(crate) fn flush_range_with(
47 start: crate::VirtAddr,
48 size: usize,
49 flush_tlb: impl Fn(Option<crate::VirtAddr>),
50) {
51 if size == 0 {
52 return;
53 }
54 struct RestoreIrqs(bool);
55 impl Drop for RestoreIrqs {
56 fn drop(&mut self) {
57 if self.0 {
58 crate::interrupt::enable_irqs();
59 }
60 }
61 }
62 let _restore = RestoreIrqs(crate::interrupt::irqs_enabled());
63 crate::interrupt::disable_irqs();
64 let Some(last) = start.as_usize().checked_add(size - 1) else {
65 flush_tlb(None);
66 return;
67 };
68 const PAGE_SIZE: usize = ax_memory_addr::PAGE_SIZE_4K;
69 let first = start.as_usize() & !(PAGE_SIZE - 1);
70 let pages = (last - first) / PAGE_SIZE + 1;
71 if pages > crate::arch::current::TLB_RANGE_PAGE_LIMIT {
72 flush_tlb(None);
73 return;
74 }
75 for page in 0..pages {
78 flush_tlb(Some(crate::VirtAddr::from_usize(first + page * PAGE_SIZE)));
79 }
80}
81
82pub fn update_mmu_cache(vaddr: crate::VirtAddr) {
86 let base = vaddr.as_usize() & !(ax_memory_addr::PAGE_SIZE_4K - 1);
87 crate::arch::current::asm::update_mmu_cache(crate::VirtAddr::from_usize(base));
88}
89
90#[cfg(target_arch = "aarch64")]
91pub use El1 as Native;
92
93#[cfg(target_arch = "aarch64")]
94pub use crate::arch::current::mmu::{El1, El2};
95
96#[cfg(not(target_arch = "aarch64"))]
98pub struct Native;
99
100#[cfg(not(target_arch = "aarch64"))]
101impl Native {
102 pub fn read_kernel_page_table() -> crate::PhysAddr {
104 read_kernel_page_table()
105 }
106 pub unsafe fn write_kernel_page_table(root: crate::PhysAddr) {
112 unsafe { write_kernel_page_table(root) };
114 }
115 pub fn flush_tlb(address: Option<crate::VirtAddr>) {
117 flush_tlb(address);
118 }
119 pub fn flush_tlb_range(start: crate::VirtAddr, size: usize) {
121 flush_tlb_range(start, size);
122 }
123 pub fn address_space_tag_capacity() -> u32 {
125 address_space_tag_capacity()
126 }
127}
128
129#[cfg(target_arch = "riscv64")]
130pub use crate::arch::current::mmu::{Satp, SatpMode, install_page_table, read_satp};