Skip to content

Commit 7e635ba

Browse files
Merge pull request #280 from rmsyn/riscv/register/senvcfg
register: add `senvcfg` register
2 parents cb6a264 + fcbb24b commit 7e635ba

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

riscv/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- CSR helper macro `write_composite_csr` for writing 64-bit CSRs on 32-bit targets.
1313
- Write utilities for `mcycle`, `minstret`
14+
- Add `senvcfg` CSR
1415

1516
### Changed
1617

riscv/src/register.rs

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub mod stvec;
5757

5858
// Supervisor Trap Handling
5959
pub mod scause;
60+
pub mod senvcfg;
6061
pub mod sepc;
6162
pub mod sip;
6263
pub mod sscratch;

riscv/src/register/senvcfg.rs

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
//! `senvcfg` register.
2+
3+
#[cfg(target_arch = "riscv32")]
4+
const MASK: usize = 0xf5;
5+
#[cfg(not(target_arch = "riscv32"))]
6+
const MASK: usize = 0x3_0000_00fd;
7+
8+
read_write_csr! {
9+
/// `senvcfg` register.
10+
Senvcfg: 0x10a,
11+
mask: MASK,
12+
}
13+
14+
set!(0x10a);
15+
clear!(0x10a);
16+
17+
read_write_csr_field! {
18+
Senvcfg,
19+
/// Gets the `fiom` (Fence of I/O Implies Memory) field value.
20+
fiom: 0,
21+
}
22+
23+
read_write_csr_field! {
24+
Senvcfg,
25+
/// Gets the `lpe` (Landing Pad Enable) field value.
26+
lpe: 2,
27+
}
28+
29+
#[cfg(not(target_arch = "riscv32"))]
30+
read_write_csr_field! {
31+
Senvcfg,
32+
/// Gets the `sse` (Shadow Stack Enable) field value.
33+
sse: 3,
34+
}
35+
36+
csr_field_enum! {
37+
/// Represents CBIE (Cache Block Invalidate instruction Enable) field of the `senvcfg` CSR.
38+
Cbie {
39+
default: IllegalInstruction,
40+
/// The instruction takes an illegal instruction exception.
41+
IllegalInstruction = 0b00,
42+
/// The instruction is executed and performs a flush operation.
43+
Flush = 0b01,
44+
/// The instruction is executed and performs an invalidate operation.
45+
Invalidate = 0b11,
46+
}
47+
}
48+
49+
read_write_csr_field! {
50+
Senvcfg,
51+
/// Gets the `cbie` (Cache Block Invalidate Enable) field value.
52+
cbie,
53+
Cbie: [4:5],
54+
}
55+
56+
read_write_csr_field! {
57+
Senvcfg,
58+
/// Gets the `cbcfe` (Cache Block Clean and Flush Enable) field value.
59+
cbcfe: 6,
60+
}
61+
62+
read_write_csr_field! {
63+
Senvcfg,
64+
/// Gets the `cbze` (Cache Block Zero Enable) field value.
65+
cbze: 7,
66+
}
67+
68+
#[cfg(not(target_arch = "riscv32"))]
69+
csr_field_enum! {
70+
/// Represents PMM (Pointer Masking Mode) field of the `senvcfg` CSR.
71+
Pmm {
72+
default: Disabled,
73+
/// Pointer masking is disabled (PMLEN=0).
74+
Disabled = 0b00,
75+
/// Pointer masking is enabled with PMLEN=XLEN-57 (PMLEN=7 on RV64).
76+
Mask7bit = 0b10,
77+
/// Pointer masking is enabled with PMLEN=XLEN-48 (PMLEN=16 on RV64).
78+
Mask16bit = 0b11,
79+
}
80+
}
81+
82+
#[cfg(not(target_arch = "riscv32"))]
83+
read_write_csr_field! {
84+
Senvcfg,
85+
/// Gets the `pmm` (Pointer Masking Mode) field value.
86+
pmm,
87+
Pmm: [32:33],
88+
}
89+
90+
#[cfg(test)]
91+
mod tests {
92+
use super::*;
93+
94+
#[test]
95+
fn test_senvcfg() {
96+
let mut senvcfg = Senvcfg::from_bits(0);
97+
98+
test_csr_field!(senvcfg, fiom);
99+
test_csr_field!(senvcfg, lpe);
100+
101+
#[cfg(not(target_arch = "riscv32"))]
102+
test_csr_field!(senvcfg, sse);
103+
104+
[Cbie::IllegalInstruction, Cbie::Flush, Cbie::Invalidate]
105+
.into_iter()
106+
.for_each(|cbie| {
107+
test_csr_field!(senvcfg, cbie: cbie);
108+
});
109+
110+
test_csr_field!(senvcfg, cbcfe);
111+
test_csr_field!(senvcfg, cbze);
112+
113+
#[cfg(not(target_arch = "riscv32"))]
114+
[Pmm::Disabled, Pmm::Mask7bit, Pmm::Mask16bit]
115+
.into_iter()
116+
.for_each(|pmm| {
117+
test_csr_field!(senvcfg, pmm: pmm);
118+
});
119+
}
120+
}

0 commit comments

Comments
 (0)