libarch/riscv64/
paging.rs1use bitrs::{bitfield_repr, layout};
6use regio::riscv64::{Csr, encoding};
7
8pub const SATP: Csr<encoding::satp, SupervisorAddressTranslationAndProtection> = Csr::new();
10
11#[bitfield_repr(u8)]
12#[derive(Clone, Copy)]
13pub enum TranslationMode {
14 Bare = 0, Sv39 = 8,
17 Sv48 = 9,
18 Sv57 = 10,
19 Sv64 = 11,
20 }
23
24layout!({
25 pub struct SupervisorAddressTranslationAndProtection(u64);
27 {
28 let mode @ 63..60: TranslationMode;
29 let asid @ 59..44;
30 let ppn @ 43..0;
31 }
32});
33
34impl SupervisorAddressTranslationAndProtection {
35 pub fn root_address(&self) -> u64 {
37 self.ppn() << 12
38 }
39
40 pub fn set_root_address(&mut self, addr: u64) -> &mut Self {
42 assert!(addr & 0xfff == 0, "root address must be 4KiB-aligned");
43 self.set_ppn(addr >> 12)
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn satp() {
53 let mut satp = SupervisorAddressTranslationAndProtection::new();
54 satp.set_mode(TranslationMode::Sv39).set_asid(0x12).set_root_address(0x8000_0000);
55 assert_eq!(satp.mode(), TranslationMode::Sv39);
56 assert_eq!(satp.asid(), 0x12);
57 assert_eq!(satp.root_address(), 0x8000_0000);
58 assert_eq!(satp.ppn(), 0x8_0000);
59 }
60}