1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! Virtual Supervisor Guest Address Translation and Protection Register.
use bit_field::BitField;
use riscv::{clear, read_csr_as, set, write_csr};
/// Virtual Supervisor Address Translation and Protection Register.
#[derive(Copy, Clone, Debug)]
pub struct Vsatp {
bits: usize,
}
impl Vsatp {
/// Returns the raw bits of the register.
#[inline]
pub fn bits(&self) -> usize {
return self.bits;
}
/// Creates a register value from raw bits.
#[inline]
pub fn from_bits(x: usize) -> Self {
return Vsatp { bits: x };
}
/// Writes the register value to the CSR.
#[inline]
pub unsafe fn write(&self) {
_write(self.bits);
}
/// Returns the guest address translation mode.
#[inline]
pub fn mode(&self) -> HgatpValues {
HgatpValues::from(self.bits.get_bits(60..64))
}
/// Sets the guest address translation mode.
#[inline]
pub fn set_mode(&mut self, val: HgatpValues) {
self.bits.set_bits(60..64, val as usize);
}
/// Returns the address space identifier.
#[inline]
pub fn asid(&self) -> usize {
self.bits.get_bits(44..60)
}
/// Sets the address space identifier.
#[inline]
pub fn set_asid(&mut self, val: usize) {
self.bits.set_bits(44..60, val);
}
/// Returns the physical page number for root page table.
#[inline]
pub fn ppn(&self) -> usize {
self.bits.get_bits(0..44)
}
/// Sets the physical page number for root page table.
#[inline]
pub fn set_ppn(&mut self, val: usize) {
self.bits.set_bits(0..44, val);
}
}
read_csr_as!(Vsatp, 0x280);
write_csr!(0x280);
set!(0x280);
clear!(0x280);
// bit ops
/// Hypervisor Guest Address Translation and Protection Register values.
#[derive(Copy, Clone, Debug)]
#[repr(usize)]
pub enum HgatpValues {
/// Bare
Bare = 0,
/// Supervisor Virtual Address Translation (SV39)
Sv39x4 = 8,
/// Supervisor Virtual Address Translation (SV48)
Sv48x4 = 9,
}
impl HgatpValues {
fn from(x: usize) -> Self {
match x {
0 => Self::Bare,
8 => Self::Sv39x4,
9 => Self::Sv48x4,
_ => unreachable!(),
}
}
}