Skip to content

Commit f6a5d52

Browse files
committed
riscv: add fallible functions to satp
Adds fallible access functions for `Satp` ASID and PPN fields.
1 parent 4efe97d commit f6a5d52

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

riscv/src/register/satp.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! satp register
22
3+
use crate::result::{Error, Result};
4+
35
/// satp register
46
#[derive(Clone, Copy, Debug)]
57
pub struct Satp {
@@ -105,6 +107,28 @@ pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) {
105107
_write(bits);
106108
}
107109

110+
/// Attempts to set the register to corresponding page table mode, physical page number and address space id.
111+
#[inline]
112+
#[cfg(target_pointer_width = "32")]
113+
pub unsafe fn try_set(mode: Mode, asid: usize, ppn: usize) -> Result<()> {
114+
if asid != asid & 0x1FF {
115+
Err(Error::InvalidValue {
116+
field: "asid",
117+
value: asid,
118+
bitmask: 0x1FF,
119+
})
120+
} else if ppn != ppn & 0x3F_FFFF {
121+
Err(Error::InvalidValue {
122+
field: "ppn",
123+
value: ppn,
124+
bitmask: 0x3F_FFFF,
125+
})
126+
} else {
127+
let bits = (mode as usize) << 31 | (asid << 22) | ppn;
128+
_try_write(bits)
129+
}
130+
}
131+
108132
/// Sets the register to corresponding page table mode, physical page number and address space id.
109133
#[inline]
110134
#[cfg(target_pointer_width = "64")]
@@ -114,3 +138,25 @@ pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) {
114138
let bits = (mode as usize) << 60 | (asid << 44) | ppn;
115139
_write(bits);
116140
}
141+
142+
/// Sets the register to corresponding page table mode, physical page number and address space id.
143+
#[inline]
144+
#[cfg(target_pointer_width = "64")]
145+
pub unsafe fn try_set(mode: Mode, asid: usize, ppn: usize) -> Result<()> {
146+
if asid != asid & 0xFFFF {
147+
Err(Error::InvalidValue {
148+
field: "asid",
149+
value: asid,
150+
bitmask: 0xFFFF,
151+
})
152+
} else if ppn != ppn & 0xFFF_FFFF_FFFF {
153+
Err(Error::InvalidValue {
154+
field: "ppn",
155+
value: ppn,
156+
bitmask: 0xFFF_FFFF_FFFF,
157+
})
158+
} else {
159+
let bits = (mode as usize) << 60 | (asid << 44) | ppn;
160+
_try_write(bits)
161+
}
162+
}

riscv/src/result.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ pub enum Error {
1515
},
1616
/// Unimplemented function or type.
1717
Unimplemented,
18+
/// Invalid field value.
19+
InvalidValue {
20+
field: &'static str,
21+
value: usize,
22+
bitmask: usize,
23+
},
1824
}
1925

2026
impl fmt::Display for Error {
@@ -25,6 +31,14 @@ impl fmt::Display for Error {
2531
"out-of-bounds access, index: {index}, min: {min}, max: {max}"
2632
),
2733
Self::Unimplemented => write!(f, "unimplemented"),
34+
Self::InvalidValue {
35+
field,
36+
value,
37+
bitmask,
38+
} => write!(
39+
f,
40+
"invalid {field} field value: {value:#x}, valid bitmask: {bitmask:#x}",
41+
),
2842
}
2943
}
3044
}

0 commit comments

Comments
 (0)