Skip to content

Commit 9920537

Browse files
committed
riscv: define satp CSR with macro helpers
Uses CSR macro helpers to define the `satp` CSR register.
1 parent cbb5a7b commit 9920537

File tree

2 files changed

+58
-115
lines changed

2 files changed

+58
-115
lines changed

riscv/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2929
- Use CSR helper macros to define `mstatush` register
3030
- Use CSR helper macros to define `mtvec` register
3131
- Use CSR helper macros to define `mtvendorid` register
32+
- Use CSR helper macros to define `satp` register
3233

3334
## [v0.12.1] - 2024-10-20
3435

riscv/src/register/satp.rs

Lines changed: 57 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -2,144 +2,86 @@
22
33
use crate::result::{Error, Result};
44

5-
/// satp register
6-
#[derive(Clone, Copy, Debug)]
7-
pub struct Satp {
8-
bits: usize,
5+
read_write_csr! {
6+
/// `satp` register
7+
Satp: 0x180,
8+
mask: usize::MAX,
99
}
1010

11-
impl Satp {
12-
/// Returns the contents of the register as raw bits
13-
#[inline]
14-
pub fn bits(&self) -> usize {
15-
self.bits
16-
}
17-
18-
/// Current address-translation scheme
19-
///
20-
/// **WARNING**: panics if the field has an invalid variant.
21-
#[inline]
22-
#[cfg(target_pointer_width = "32")]
23-
pub fn mode(&self) -> Mode {
24-
self.try_mode().unwrap()
25-
}
26-
27-
/// Attempts to get the current address-translation scheme.
28-
#[inline]
29-
#[cfg(target_pointer_width = "32")]
30-
pub fn try_mode(&self) -> Result<Mode> {
31-
((self.bits >> 31) as u8).try_into()
32-
}
33-
34-
/// Current address-translation scheme
35-
///
36-
/// **WARNING**: panics if the field has an invalid variant.
37-
#[inline]
38-
#[cfg(target_pointer_width = "64")]
39-
pub fn mode(&self) -> Mode {
40-
self.try_mode().unwrap()
41-
}
42-
43-
/// Attempts to get the current address-translation scheme.
44-
#[inline]
45-
#[cfg(target_pointer_width = "64")]
46-
pub fn try_mode(&self) -> Result<Mode> {
47-
((self.bits >> 60) as u8).try_into()
48-
}
49-
50-
/// Address space identifier
51-
#[inline]
52-
#[cfg(target_pointer_width = "32")]
53-
pub fn asid(&self) -> usize {
54-
(self.bits >> 22) & 0x1FF // bits 22-30
11+
#[cfg(target_pointer_width = "32")]
12+
csr_field_enum! {
13+
/// 32-bit satp mode
14+
Mode {
15+
default: Bare,
16+
/// No translation or protection
17+
Bare = 0,
18+
/// Page-based 32-bit virtual addressing
19+
Sv32 = 1,
5520
}
21+
}
5622

57-
/// Address space identifier
58-
#[inline]
59-
#[cfg(target_pointer_width = "64")]
60-
pub fn asid(&self) -> usize {
61-
(self.bits >> 44) & 0xFFFF // bits 44-59
23+
#[cfg(target_pointer_width = "64")]
24+
csr_field_enum! {
25+
/// 64-bit satp mode
26+
Mode {
27+
default: Bare,
28+
/// No translation or protection
29+
Bare = 0,
30+
/// Page-based 39-bit virtual addressing
31+
Sv39 = 8,
32+
/// Page-based 48-bit virtual addressing
33+
Sv48 = 9,
34+
/// Page-based 57-bit virtual addressing
35+
Sv57 = 10,
36+
/// Page-based 64-bit virtual addressing
37+
Sv64 = 11,
6238
}
39+
}
6340

41+
#[cfg(target_pointer_width = "32")]
42+
read_write_csr_field! {
43+
Satp,
6444
/// Physical page number
65-
#[inline]
66-
#[cfg(target_pointer_width = "32")]
67-
pub fn ppn(&self) -> usize {
68-
self.bits & 0x3F_FFFF // bits 0-21
69-
}
45+
ppn: [0:21],
46+
}
7047

48+
#[cfg(target_pointer_width = "64")]
49+
read_write_csr_field! {
50+
Satp,
7151
/// Physical page number
72-
#[inline]
73-
#[cfg(target_pointer_width = "64")]
74-
pub fn ppn(&self) -> usize {
75-
self.bits & 0xFFF_FFFF_FFFF // bits 0-43
76-
}
52+
ppn: [0:43],
7753
}
7854

79-
/// 32-bit satp mode
8055
#[cfg(target_pointer_width = "32")]
81-
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
82-
pub enum Mode {
83-
/// No translation or protection
84-
Bare = 0,
85-
/// Page-based 32-bit virtual addressing
86-
Sv32 = 1,
56+
read_write_csr_field! {
57+
Satp,
58+
/// Address space identifier
59+
asid: [22:30],
8760
}
8861

89-
/// 64-bit satp mode
9062
#[cfg(target_pointer_width = "64")]
91-
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
92-
pub enum Mode {
93-
/// No translation or protection
94-
Bare = 0,
95-
/// Page-based 39-bit virtual addressing
96-
Sv39 = 8,
97-
/// Page-based 48-bit virtual addressing
98-
Sv48 = 9,
99-
/// Page-based 57-bit virtual addressing
100-
Sv57 = 10,
101-
/// Page-based 64-bit virtual addressing
102-
Sv64 = 11,
63+
read_write_csr_field! {
64+
Satp,
65+
/// Address space identifier
66+
asid: [44:59],
10367
}
10468

10569
#[cfg(target_pointer_width = "32")]
106-
impl TryFrom<u8> for Mode {
107-
type Error = Error;
108-
109-
fn try_from(val: u8) -> Result<Self> {
110-
match val {
111-
0 => Ok(Mode::Bare),
112-
1 => Ok(Mode::Sv32),
113-
_ => Err(Error::InvalidFieldVariant {
114-
field: "mode",
115-
value: val as usize,
116-
}),
117-
}
118-
}
70+
read_write_csr_field! {
71+
Satp,
72+
/// Current address-translation scheme.
73+
mode,
74+
Mode: [31:31],
11975
}
12076

12177
#[cfg(target_pointer_width = "64")]
122-
impl TryFrom<u8> for Mode {
123-
type Error = Error;
124-
125-
fn try_from(val: u8) -> Result<Self> {
126-
match val {
127-
0 => Ok(Mode::Bare),
128-
8 => Ok(Mode::Sv39),
129-
9 => Ok(Mode::Sv48),
130-
10 => Ok(Mode::Sv57),
131-
11 => Ok(Mode::Sv64),
132-
_ => Err(Error::InvalidFieldVariant {
133-
field: "mode",
134-
value: val as usize,
135-
}),
136-
}
137-
}
78+
read_write_csr_field! {
79+
Satp,
80+
/// Current address-translation scheme.
81+
mode,
82+
Mode: [60:63],
13883
}
13984

140-
read_csr_as!(Satp, 0x180);
141-
write_csr_as_usize!(0x180);
142-
14385
/// Sets the register to corresponding page table mode, physical page number and address space id.
14486
///
14587
/// **WARNING**: panics on:

0 commit comments

Comments
 (0)