Skip to content

Commit f877219

Browse files
committed
Fix bit ranges for permissions and ranges. Fully tested to be working :)
1 parent 0eea25a commit f877219

File tree

1 file changed

+78
-53
lines changed

1 file changed

+78
-53
lines changed

src/register/pmpcfgx.rs

Lines changed: 78 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,74 +4,69 @@ 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 = 0,
8-
R = 1,
9-
W = 2,
10-
RW = 3,
11-
X = 4,
12-
RX = 5,
13-
WX = 6,
14-
RWX = 7,
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,
1515
}
1616

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

2626
#[derive(Clone, Copy, Debug)]
2727
pub struct Pmpcfg {
2828
pub bits: usize,
2929
}
3030

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+
}
40+
3141
impl Pmpcfg {
3242
#[inline]
33-
pub fn get_byte(&self, index: usize) -> PmpByte {
43+
pub fn get_config(&self, index: usize) -> PmpEntry {
3444
#[cfg(riscv32)]
3545
assert!(index < 4);
3646

3747
#[cfg(riscv64)]
3848
assert!(index < 8);
3949

40-
PmpByte {
41-
byte: self.bits.get_bits(8 * index..8 * (index + 1)) as u8,
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)
4256
}
4357
}
44-
}
4558

46-
/// PmpByte holds the a single pmp configuration
47-
#[derive(Clone, Copy, Debug)]
48-
pub struct PmpByte {
49-
pub byte: u8,
50-
//permission: Option<Permission>,
51-
//range: Option<Range>,
52-
//locked: bool
53-
}
54-
/// PmpByte methods to get a pmp configuration attributes
55-
impl PmpByte {
56-
#[inline]
57-
pub fn is_locked(&self) -> bool {
58-
self.byte.get_bit(7)
59-
}
59+
/// PmpByte methods to get a pmp configuration attributes
60+
pub fn get_byte(&self, index: usize) -> usize { self.bits.get_bits(8 * index..=(8 * index) + 7) as usize }
6061

6162
#[inline]
62-
pub fn get_range(&self) -> Option<Range> {
63-
match self.byte.get_bits(3..=4) {
64-
0 => Some(Range::OFF),
65-
1 => Some(Range::TOR),
66-
2 => Some(Range::NA4),
67-
3 => Some(Range::NAPOT),
68-
_ => unreachable!(),
69-
}
63+
pub fn is_locked(&self, index: usize) -> bool {
64+
self.bits.get_bit(7 + (8 * index))
7065
}
7166

7267
#[inline]
73-
pub fn get_permission(&self) -> Option<Permission> {
74-
match self.byte.get_bits(0..=2) {
68+
pub fn get_permission(&self, index: usize) -> Option<Permission> {
69+
match self.bits.get_bits(8 * index..=8 * index + 2) {
7570
0 => Some(Permission::NONE),
7671
1 => Some(Permission::R),
7772
2 => Some(Permission::W),
@@ -83,13 +78,24 @@ impl PmpByte {
8378
_ => unreachable!(),
8479
}
8580
}
86-
}
8781

82+
#[inline]
83+
pub fn get_range(&self, index: usize) -> Option<Range> {
84+
match self.bits.get_bits(8 * index + 3..=8 * index + 4) {
85+
0 => Some(Range::OFF),
86+
1 => Some(Range::TOR),
87+
2 => Some(Range::NA4),
88+
3 => Some(Range::NAPOT),
89+
_ => unreachable!(),
90+
}
91+
}
92+
}
8893
/// Physical memory protection configuration
8994
/// Pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, or pmp0cfg - pmp7cfg for RV64
9095
/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
9196
pub mod pmpcfg0 {
9297
use super::{Permission, Pmpcfg, Range};
98+
use bit_field::BitField;
9399

94100
read_csr_as!(Pmpcfg, 0x3A0, __read_pmpcfg0);
95101
write_csr!(0x3A0, __write_pmpcfg0);
@@ -104,7 +110,9 @@ pub mod pmpcfg0 {
104110
#[cfg(riscv64)]
105111
assert!(index < 8);
106112

107-
_set((permission as usize) << (index * 8));
113+
let mut value = _read();
114+
value.set_bits(8 * index..=8 * index + 2,permission as usize);
115+
_write(value);
108116
}
109117

110118
#[inline]
@@ -115,7 +123,9 @@ pub mod pmpcfg0 {
115123
#[cfg(riscv64)]
116124
assert!(index < 8);
117125

118-
_set((range as usize) << (3 + (index * 8)));
126+
let mut value = _read();
127+
value.set_bits(8 * index + 3..=8 * index + 4,range as usize);
128+
_write(value);
119129
}
120130

121131
#[inline]
@@ -126,7 +136,7 @@ pub mod pmpcfg0 {
126136
#[cfg(riscv64)]
127137
assert!(index < 8);
128138

129-
_set(1 << (7 + (index * 8)));
139+
_set(1 << (7 + index * 8));
130140
}
131141
}
132142

@@ -135,6 +145,7 @@ pub mod pmpcfg0 {
135145
/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
136146
pub mod pmpcfg1 {
137147
use super::{Permission, Pmpcfg, Range};
148+
use bit_field::BitField;
138149

139150
read_csr_as!(Pmpcfg, 0x3A1, __read_pmpcfg1);
140151
write_csr!(0x3A1, __write_pmpcfg1);
@@ -149,7 +160,9 @@ pub mod pmpcfg1 {
149160
#[cfg(riscv64)]
150161
assert!(index < 8);
151162

152-
_set((permission as usize) << (index * 8));
163+
let mut value = _read();
164+
value.set_bits(8 * index..=8 * index + 2,permission as usize);
165+
_write(value);
153166
}
154167

155168
#[inline]
@@ -160,7 +173,9 @@ pub mod pmpcfg1 {
160173
#[cfg(riscv64)]
161174
assert!(index < 8);
162175

163-
_set((range as usize) << (3 + (index * 8)));
176+
let mut value = _read();
177+
value.set_bits(8 * index + 3..=8 * index + 4,range as usize);
178+
_write(value);
164179
}
165180

166181
#[inline]
@@ -171,7 +186,7 @@ pub mod pmpcfg1 {
171186
#[cfg(riscv64)]
172187
assert!(index < 8);
173188

174-
_set(1 << (7 + (index * 8)));
189+
_set(1 << (7 + index * 8));
175190
}
176191
}
177192

@@ -180,6 +195,7 @@ pub mod pmpcfg1 {
180195
/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
181196
pub mod pmpcfg2 {
182197
use super::{Permission, Pmpcfg, Range};
198+
use bit_field::BitField;
183199

184200
read_csr_as!(Pmpcfg, 0x3A2, __read_pmpcfg2);
185201
write_csr!(0x3A2, __write_pmpcfg2);
@@ -194,7 +210,9 @@ pub mod pmpcfg2 {
194210
#[cfg(riscv64)]
195211
assert!(index < 8);
196212

197-
_set((permission as usize) << (index * 8));
213+
let mut value = _read();
214+
value.set_bits(8 * index..=8 * index + 2,permission as usize);
215+
_write(value);
198216
}
199217

200218
#[inline]
@@ -205,7 +223,9 @@ pub mod pmpcfg2 {
205223
#[cfg(riscv64)]
206224
assert!(index < 8);
207225

208-
_set((range as usize) << (3 + (index * 8)));
226+
let mut value = _read();
227+
value.set_bits(8 * index + 3..=8 * index + 4,range as usize);
228+
_write(value);
209229
}
210230

211231
#[inline]
@@ -216,7 +236,7 @@ pub mod pmpcfg2 {
216236
#[cfg(riscv64)]
217237
assert!(index < 8);
218238

219-
_set(1 << (7 + (index * 8)));
239+
_set(1 << (7 + index * 8));
220240
}
221241
}
222242

@@ -225,6 +245,7 @@ pub mod pmpcfg2 {
225245
/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
226246
pub mod pmpcfg3 {
227247
use super::{Permission, Pmpcfg, Range};
248+
use bit_field::BitField;
228249

229250
read_csr_as!(Pmpcfg, 0x3A3, __read_pmpcfg3);
230251
write_csr!(0x3A3, __write_pmpcfg3);
@@ -239,7 +260,9 @@ pub mod pmpcfg3 {
239260
#[cfg(riscv64)]
240261
assert!(index < 8);
241262

242-
_set((permission as usize) << (index * 8));
263+
let mut value = _read();
264+
value.set_bits(8 * index..=8 * index + 2,permission as usize);
265+
_write(value);
243266
}
244267

245268
#[inline]
@@ -250,7 +273,9 @@ pub mod pmpcfg3 {
250273
#[cfg(riscv64)]
251274
assert!(index < 8);
252275

253-
_set((range as usize) << (3 + (index * 8)));
276+
let mut value = _read();
277+
value.set_bits(8 * index + 3..=8 * index + 4,range as usize);
278+
_write(value);
254279
}
255280

256281
#[inline]
@@ -261,6 +286,6 @@ pub mod pmpcfg3 {
261286
#[cfg(riscv64)]
262287
assert!(index < 8);
263288

264-
_set(1 << (7 + (index * 8)));
289+
_set(1 << (7 + index * 8));
265290
}
266291
}

0 commit comments

Comments
 (0)