Skip to content

Commit c5a8b24

Browse files
Merge pull request #251 from rust-embedded/crs-write-unsafe
Make all CSR writes unsafe by default
2 parents f92d787 + 08abb73 commit c5a8b24

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

riscv/CHANGELOG.md

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

1414
### Changed
1515

16+
- Make all CSR writes `unsafe` by default (#209)
1617
- Use `RISCV_MTVEC_ALIGN` to control the alignment constraint of the vector table
1718
- Simplify register macros with `cfg` field
1819
- Align assembly functions with `cortex-m`

riscv/src/register/macros.rs

+54-8
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ macro_rules! read_csr {
1212
/// Reads the CSR.
1313
///
1414
/// **WARNING**: panics on non-`riscv` targets.
15-
#[inline]
15+
#[inline(always)]
1616
unsafe fn _read() -> usize {
1717
_try_read().unwrap()
1818
}
1919

2020
/// Attempts to read the CSR.
21-
#[inline]
21+
#[inline(always)]
2222
unsafe fn _try_read() -> $crate::result::Result<usize> {
2323
match () {
2424
#[cfg($($cfg),*)]
@@ -155,13 +155,13 @@ macro_rules! write_csr {
155155
/// Writes the CSR.
156156
///
157157
/// **WARNING**: panics on non-`riscv` targets.
158-
#[inline]
158+
#[inline(always)]
159159
unsafe fn _write(bits: usize) {
160160
_try_write(bits).unwrap();
161161
}
162162

163163
/// Attempts to write the CSR.
164-
#[inline]
164+
#[inline(always)]
165165
#[cfg_attr(not($($cfg),*), allow(unused_variables))]
166166
unsafe fn _try_write(bits: usize) -> $crate::result::Result<()> {
167167
match () {
@@ -195,9 +195,29 @@ macro_rules! write_csr_as {
195195
($csr_type:ty, $csr_number:literal) => {
196196
$crate::write_csr_as!($csr_type, $csr_number, any(target_arch = "riscv32", target_arch = "riscv64"));
197197
};
198+
(safe $csr_type:ty, $csr_number:literal) => {
199+
$crate::write_csr_as!(safe $csr_type, $csr_number, any(target_arch = "riscv32", target_arch = "riscv64"));
200+
};
198201
($csr_type:ty, $csr_number:literal, $($cfg:meta),*) => {
199202
$crate::write_csr!($csr_number, $($cfg),*);
200203

204+
/// Writes the CSR.
205+
///
206+
/// **WARNING**: panics on non-`riscv` targets.
207+
#[inline]
208+
pub unsafe fn write(value: $csr_type) {
209+
_write(value.bits);
210+
}
211+
212+
/// Attempts to write the CSR.
213+
#[inline]
214+
pub unsafe fn try_write(value: $csr_type) -> $crate::result::Result<()> {
215+
_try_write(value.bits)
216+
}
217+
};
218+
(safe $csr_type:ty, $csr_number:literal, $($cfg:meta),*) => {
219+
$crate::write_csr!($csr_number, $($cfg),*);
220+
201221
/// Writes the CSR.
202222
///
203223
/// **WARNING**: panics on non-`riscv` targets.
@@ -220,6 +240,9 @@ macro_rules! write_csr_as_rv32 {
220240
($csr_type:ty, $csr_number:literal) => {
221241
$crate::write_csr_as!($csr_type, $csr_number, target_arch = "riscv32");
222242
};
243+
(safe $csr_type:ty, $csr_number:literal) => {
244+
$crate::write_csr_as!(safe $csr_type, $csr_number, target_arch = "riscv32");
245+
};
223246
}
224247

225248
/// Convenience macro to write a [`usize`] value to a CSR register.
@@ -228,9 +251,29 @@ macro_rules! write_csr_as_usize {
228251
($csr_number:literal) => {
229252
$crate::write_csr_as_usize!($csr_number, any(target_arch = "riscv32", target_arch = "riscv64"));
230253
};
254+
(safe $csr_number:literal) => {
255+
$crate::write_csr_as_usize!(safe $csr_number, any(target_arch = "riscv32", target_arch = "riscv64"));
256+
};
231257
($csr_number:literal, $($cfg:meta),*) => {
232258
$crate::write_csr!($csr_number, $($cfg),*);
233259

260+
/// Writes the CSR.
261+
///
262+
/// **WARNING**: panics on non-`riscv` targets.
263+
#[inline]
264+
pub unsafe fn write(bits: usize) {
265+
_write(bits);
266+
}
267+
268+
/// Attempts to write the CSR.
269+
#[inline]
270+
pub unsafe fn try_write(bits: usize) -> $crate::result::Result<()> {
271+
_try_write(bits)
272+
}
273+
};
274+
(safe $csr_number:literal, $($cfg:meta),*) => {
275+
$crate::write_csr!($csr_number, $($cfg),*);
276+
234277
/// Writes the CSR.
235278
///
236279
/// **WARNING**: panics on non-`riscv` targets.
@@ -253,6 +296,9 @@ macro_rules! write_csr_as_usize_rv32 {
253296
($csr_number:literal) => {
254297
$crate::write_csr_as_usize!($csr_number, target_arch = "riscv32");
255298
};
299+
(safe $csr_number:literal) => {
300+
$crate::write_csr_as_usize!(safe $csr_number, target_arch = "riscv32");
301+
};
256302
}
257303

258304
/// Convenience macro around the `csrrs` assembly instruction to set the CSR register.
@@ -267,13 +313,13 @@ macro_rules! set {
267313
/// Set the CSR.
268314
///
269315
/// **WARNING**: panics on non-`riscv` targets.
270-
#[inline]
316+
#[inline(always)]
271317
unsafe fn _set(bits: usize) {
272318
_try_set(bits).unwrap();
273319
}
274320

275321
/// Attempts to set the CSR.
276-
#[inline]
322+
#[inline(always)]
277323
#[cfg_attr(not($($cfg),*), allow(unused_variables))]
278324
unsafe fn _try_set(bits: usize) -> $crate::result::Result<()> {
279325
match () {
@@ -311,13 +357,13 @@ macro_rules! clear {
311357
/// Clear the CSR.
312358
///
313359
/// **WARNING**: panics on non-`riscv` targets.
314-
#[inline]
360+
#[inline(always)]
315361
unsafe fn _clear(bits: usize) {
316362
_try_clear(bits).unwrap();
317363
}
318364

319365
/// Attempts to clear the CSR.
320-
#[inline]
366+
#[inline(always)]
321367
#[cfg_attr(not($($cfg),*), allow(unused_variables))]
322368
unsafe fn _try_clear(bits: usize) -> $crate::result::Result<()> {
323369
match () {

0 commit comments

Comments
 (0)