Skip to content

Commit 726d516

Browse files
committed
Add set_pmp fn in pmpcfg modules, and into_config method for Pmpcfg struct
1 parent 5558865 commit 726d516

File tree

1 file changed

+92
-208
lines changed

1 file changed

+92
-208
lines changed

src/register/pmpcfgx.rs

Lines changed: 92 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -4,290 +4,174 @@ use bit_field::BitField;
44
/// Permission enum contains all possible permission modes for pmp registers
55
#[derive(Clone, Copy, Debug)]
66
pub enum Permission {
7-
NONE = 0b_000,
8-
R = 0b_001,
9-
W = 0b_010,
10-
RW = 0b_011,
11-
X = 0b_100,
12-
RX = 0b_101,
13-
WX = 0b_110,
14-
RWX = 0b_111,
7+
NONE = 0b000,
8+
R = 0b001,
9+
W = 0b010,
10+
RW = 0b011,
11+
X = 0b100,
12+
RX = 0b101,
13+
WX = 0b110,
14+
RWX = 0b111,
1515
}
1616

1717
/// Range enum contains all possible addressing modes for pmp registers
1818
#[derive(Clone, Copy, Debug)]
1919
pub enum Range {
20-
OFF = 0b_00,
21-
TOR = 0b_01,
22-
NA4 = 0b_10,
23-
NAPOT = 0b_11,
20+
OFF = 0b00,
21+
TOR = 0b01,
22+
NA4 = 0b10,
23+
NAPOT = 0b11,
2424
}
2525

26+
/// RV64 Pmpcfg holds the entire register (8 Pmp configurations)
2627
#[derive(Clone, Copy, Debug)]
27-
pub struct Pmpcfg {
28-
pub bits: usize,
28+
pub struct Pmp {
29+
/// raw bits
30+
pub byte: u8,
31+
/// Current PMP Permission
32+
pub permission: Permission,
33+
/// Current PMP Range
34+
pub range: Range,
35+
/// Is PMP locked?
36+
pub locked: bool,
2937
}
3038

31-
/// PmpByte holds the a single pmp configuration
32-
#[derive(Clone, Copy, Debug)]
33-
pub struct PmpEntry {
34-
pub byte: usize,
35-
pub index: usize,
36-
pub permission: Option<Permission>,
37-
pub range: Option<Range>,
38-
pub locked: bool,
39+
pub struct Pmpcsr {
40+
/// Holds the raw contents of the PMP CSR
41+
pub bits: usize,
3942
}
4043

41-
impl Pmpcfg {
44+
impl Pmpcsr {
45+
/// Take the register contents and translate into configurations held in a Pmpcfg struct
46+
/// Takes `self` as a parameter and destroys the current Pmpcsr struct
4247
#[inline]
43-
pub fn get_config(&self, index: usize) -> PmpEntry {
48+
pub fn into_config(&self, index: usize) -> Pmp {
4449
#[cfg(riscv32)]
4550
assert!(index < 4);
4651

4752
#[cfg(riscv64)]
4853
assert!(index < 8);
4954

50-
PmpEntry {
51-
byte: self.get_byte(index),
52-
index,
53-
permission: self.get_permission(index),
54-
range: self.get_range(index),
55-
locked: self.is_locked(index),
56-
}
57-
}
58-
59-
/// PmpByte methods to get a pmp configuration attributes
60-
pub fn get_byte(&self, index: usize) -> usize {
61-
self.bits.get_bits(8 * index..=(8 * index) + 7) as usize
62-
}
63-
64-
#[inline]
65-
pub fn is_locked(&self, index: usize) -> bool {
66-
self.bits.get_bit(7 + 8 * index)
67-
}
68-
69-
#[inline]
70-
pub fn get_permission(&self, index: usize) -> Option<Permission> {
71-
match self.bits.get_bits(8 * index..=8 * index + 2) {
72-
0 => Some(Permission::NONE),
73-
1 => Some(Permission::R),
74-
2 => Some(Permission::W),
75-
3 => Some(Permission::RW),
76-
4 => Some(Permission::X),
77-
5 => Some(Permission::RX),
78-
6 => Some(Permission::WX),
79-
7 => Some(Permission::RWX),
80-
_ => unreachable!(),
81-
}
82-
}
83-
84-
#[inline]
85-
pub fn get_range(&self, index: usize) -> Option<Range> {
86-
match self.bits.get_bits(8 * index + 3..=8 * index + 4) {
87-
0 => Some(Range::OFF),
88-
1 => Some(Range::TOR),
89-
2 => Some(Range::NA4),
90-
3 => Some(Range::NAPOT),
91-
_ => unreachable!(),
55+
let byte = self.bits.get_bits(8 * index..=8 * index + 7) as u8;
56+
Pmp {
57+
byte,
58+
permission: match byte.get_bits(0..=2) {
59+
0 => Permission::NONE,
60+
1 => Permission::R,
61+
2 => Permission::W,
62+
3 => Permission::RW,
63+
4 => Permission::X,
64+
5 => Permission::RX,
65+
6 => Permission::WX,
66+
7 => Permission::RWX,
67+
_ => unreachable!(),
68+
},
69+
range: match byte.get_bits(3..=4) {
70+
0 => Range::OFF,
71+
1 => Range::TOR,
72+
2 => Range::NA4,
73+
3 => Range::NAPOT,
74+
_ => unreachable!(),
75+
},
76+
locked: byte.get_bit(7) as bool,
9277
}
9378
}
9479
}
80+
9581
/// Physical memory protection configuration
96-
/// Pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, or pmp0cfg - pmp7cfg for RV64
97-
/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
98-
pub mod pmpcfg0 {
99-
use super::{Permission, Pmpcfg, Range};
82+
/// pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, and pmp0cfg - pmp7cfg for RV64
83+
mod pmpcfg0 {
84+
use super::{Permission, Pmpcsr, Range};
10085
use bit_field::BitField;
10186

102-
read_csr_as!(Pmpcfg, 0x3A0, __read_pmpcfg0);
103-
write_csr!(0x3A0, __write_pmpcfg0);
87+
read_csr_as!(Pmpcsr, 0x3A0, __read_pmpcfg0);
88+
write_csr_as_usize!(0x3A0, __write_pmpcfg0);
10489
set!(0x3A0, __set_pmpcfg0);
10590
clear!(0x3A0, __clear_pmpcfg0);
10691

107-
#[inline]
108-
pub unsafe fn set_permissions(permission: Permission, index: usize) {
109-
#[cfg(riscv32)]
110-
assert!(index < 4);
111-
112-
#[cfg(riscv64)]
113-
assert!(index < 8);
114-
115-
let mut value = _read();
116-
value.set_bits(8 * index..=8 * index + 2, permission as usize);
117-
_write(value);
118-
}
119-
120-
#[inline]
121-
pub unsafe fn set_range(range: Range, index: usize) {
92+
/// set the configuration for pmp(x)
93+
pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
12294
#[cfg(riscv32)]
12395
assert!(index < 4);
12496

12597
#[cfg(riscv64)]
12698
assert!(index < 8);
12799

128100
let mut value = _read();
129-
value.set_bits(8 * index + 3..=8 * index + 4, range as usize);
130-
_write(value);
131-
}
132-
133-
#[inline]
134-
pub unsafe fn set_lock(index: usize) {
135-
#[cfg(riscv32)]
136-
assert!(index < 4);
137-
138-
#[cfg(riscv64)]
139-
assert!(index < 8);
140-
141-
_set(1 << (7 + index * 8));
101+
let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
102+
value.set_bits(8 * index..=8 * index + 7, byte);
103+
_set(value)
142104
}
143105
}
144106

145107
/// Physical memory protection configuration
146-
/// Pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only
147-
/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
148-
pub mod pmpcfg1 {
149-
use super::{Permission, Pmpcfg, Range};
108+
/// pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only
109+
#[cfg(riscv32)]
110+
mod pmpcfg1 {
111+
use super::{Permission, Pmpcsr, Range};
150112
use bit_field::BitField;
151113

152-
read_csr_as!(Pmpcfg, 0x3A1, __read_pmpcfg1);
153-
write_csr!(0x3A1, __write_pmpcfg1);
114+
read_csr_as!(Pmpcsr, 0x3A1, __read_pmpcfg1);
115+
write_csr_as_usize_rv32!(0x3A1, __write_pmpcfg1);
154116
set!(0x3A1, __set_pmpcfg1);
155117
clear!(0x3A1, __clear_pmpcfg1);
156118

157-
#[inline]
158-
pub unsafe fn set_permissions(permission: Permission, index: usize) {
159-
#[cfg(riscv32)]
119+
/// set the configuration for pmp(x)
120+
pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
160121
assert!(index < 4);
161122

162-
#[cfg(riscv64)]
163-
assert!(index < 8);
164-
165-
let mut value = _read();
166-
value.set_bits(8 * index..=8 * index + 2, permission as usize);
167-
_write(value);
168-
}
169-
170-
#[inline]
171-
pub unsafe fn set_range(range: Range, index: usize) {
172-
#[cfg(riscv32)]
173-
assert!(index < 4);
174-
175-
#[cfg(riscv64)]
176-
assert!(index < 8);
177-
178123
let mut value = _read();
179-
value.set_bits(8 * index + 3..=8 * index + 4, range as usize);
180-
_write(value);
181-
}
182-
183-
#[inline]
184-
pub unsafe fn set_lock(index: usize) {
185-
#[cfg(riscv32)]
186-
assert!(index < 4);
187-
188-
#[cfg(riscv64)]
189-
assert!(index < 8);
190-
191-
_set(1 << (7 + index * 8));
124+
let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
125+
value.set_bits(8 * index..=8 * index + 7, byte);
126+
_set(value)
192127
}
193128
}
194129

195130
/// Physical memory protection configuration
196-
/// Pmpcfg0 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
197-
/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
131+
/// pmpcfg2 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
198132
pub mod pmpcfg2 {
199-
use super::{Permission, Pmpcfg, Range};
133+
use super::{Permission, Pmpcsr, Range};
200134
use bit_field::BitField;
201135

202-
read_csr_as!(Pmpcfg, 0x3A2, __read_pmpcfg2);
203-
write_csr!(0x3A2, __write_pmpcfg2);
136+
read_csr_as!(Pmpcsr, 0x3A2, __read_pmpcfg2);
137+
write_csr_as_usize!(0x3A2, __write_pmpcfg2);
204138
set!(0x3A2, __set_pmpcfg2);
205139
clear!(0x3A2, __clear_pmpcfg2);
206140

207-
#[inline]
208-
pub unsafe fn set_permissions(permission: Permission, index: usize) {
141+
/// set the configuration for pmp(x)
142+
pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
209143
#[cfg(riscv32)]
210144
assert!(index < 4);
211145

212146
#[cfg(riscv64)]
213147
assert!(index < 8);
214148

215149
let mut value = _read();
216-
value.set_bits(8 * index..=8 * index + 2, permission as usize);
217-
_write(value);
218-
}
219-
220-
#[inline]
221-
pub unsafe fn set_range(range: Range, index: usize) {
222-
#[cfg(riscv32)]
223-
assert!(index < 4);
224-
225-
#[cfg(riscv64)]
226-
assert!(index < 8);
227-
228-
let mut value = _read();
229-
value.set_bits(8 * index + 3..=8 * index + 4, range as usize);
230-
_write(value);
231-
}
232-
233-
#[inline]
234-
pub unsafe fn set_lock(index: usize) {
235-
#[cfg(riscv32)]
236-
assert!(index < 4);
237-
238-
#[cfg(riscv64)]
239-
assert!(index < 8);
240-
241-
_set(1 << (7 + index * 8));
150+
let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
151+
value.set_bits(8 * index..=8 * index + 7, byte);
152+
_set(value)
242153
}
243154
}
244155

245156
/// Physical memory protection configuration
246-
/// Pmpcfg0 struct contains pmp12cfg - pmp15cfg for RV32 only
247-
/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
157+
/// pmpcfg3 struct contains pmp12cfg - pmp15cfg for RV32 only
158+
#[cfg(riscv32)]
248159
pub mod pmpcfg3 {
249-
use super::{Permission, Pmpcfg, Range};
160+
use super::{Permission, Pmpcsr, Range};
250161
use bit_field::BitField;
251162

252-
read_csr_as!(Pmpcfg, 0x3A3, __read_pmpcfg3);
253-
write_csr!(0x3A3, __write_pmpcfg3);
163+
read_csr_as!(Pmpcsr, 0x3A3, __read_pmpcfg3);
164+
write_csr_as_usize_rv32!(0x3A3, __read_pmpcfg3);
254165
set!(0x3A3, __set_pmpcfg3);
255166
clear!(0x3A3, __clear_pmpcfg3);
256167

257-
#[inline]
258-
pub unsafe fn set_permissions(permission: Permission, index: usize) {
259-
#[cfg(riscv32)]
260-
assert!(index < 4);
261-
262-
#[cfg(riscv64)]
263-
assert!(index < 8);
264-
265-
let mut value = _read();
266-
value.set_bits(8 * index..=8 * index + 2, permission as usize);
267-
_write(value);
268-
}
269-
270-
#[inline]
271-
pub unsafe fn set_range(range: Range, index: usize) {
272-
#[cfg(riscv32)]
168+
/// set the configuration for pmp(x)
169+
pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
273170
assert!(index < 4);
274171

275-
#[cfg(riscv64)]
276-
assert!(index < 8);
277-
278172
let mut value = _read();
279-
value.set_bits(8 * index + 3..=8 * index + 4, range as usize);
280-
_write(value);
281-
}
282-
283-
#[inline]
284-
pub unsafe fn set_lock(index: usize) {
285-
#[cfg(riscv32)]
286-
assert!(index < 4);
287-
288-
#[cfg(riscv64)]
289-
assert!(index < 8);
290-
291-
_set(1 << (7 + index * 8));
173+
let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
174+
value.set_bits(8 * index..=8 * index + 7, byte);
175+
_set(value)
292176
}
293177
}

0 commit comments

Comments
 (0)