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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use bit_field::BitField;
#[derive(Clone, Copy, Debug)]
pub struct Satp {
bits: usize,
}
impl Satp {
#[inline]
pub fn bits(&self) -> usize {
self.bits
}
#[inline]
#[cfg(target_pointer_width = "32")]
pub fn mode(&self) -> Mode {
match self.bits.get_bit(31) {
false => Mode::Bare,
true => Mode::Sv32,
}
}
#[inline]
#[cfg(target_pointer_width = "64")]
pub fn mode(&self) -> Mode {
match self.bits.get_bits(60..64) {
0 => Mode::Bare,
8 => Mode::Sv39,
9 => Mode::Sv48,
10 => Mode::Sv57,
11 => Mode::Sv64,
_ => unreachable!(),
}
}
#[inline]
#[cfg(target_pointer_width = "32")]
pub fn asid(&self) -> usize {
self.bits.get_bits(22..31)
}
#[inline]
#[cfg(target_pointer_width = "64")]
pub fn asid(&self) -> usize {
self.bits.get_bits(44..60)
}
#[inline]
#[cfg(target_pointer_width = "32")]
pub fn ppn(&self) -> usize {
self.bits.get_bits(0..22)
}
#[inline]
#[cfg(target_pointer_width = "64")]
pub fn ppn(&self) -> usize {
self.bits.get_bits(0..44)
}
}
#[cfg(target_pointer_width = "32")]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Mode {
Bare = 0,
Sv32 = 1,
}
#[cfg(target_pointer_width = "64")]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Mode {
Bare = 0,
Sv39 = 8,
Sv48 = 9,
Sv57 = 10,
Sv64 = 11,
}
read_csr_as!(Satp, 0x180, __read_satp);
write_csr_as_usize!(0x180, __write_satp);
#[inline]
#[cfg(target_pointer_width = "32")]
pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) {
let mut bits = 0usize;
bits.set_bits(31..32, mode as usize);
bits.set_bits(22..31, asid);
bits.set_bits(0..22, ppn);
_write(bits);
}
#[inline]
#[cfg(target_pointer_width = "64")]
pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) {
let mut bits = 0usize;
bits.set_bits(60..64, mode as usize);
bits.set_bits(44..60, asid);
bits.set_bits(0..44, ppn);
_write(bits);
}