From e237ed45946a0a099e7df8224bbc92c27569ec20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Thu, 19 Dec 2024 09:16:57 +0100 Subject: [PATCH] Make all CSR writes unsafe by default --- riscv/CHANGELOG.md | 1 + riscv/src/register/macros.rs | 62 +++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/riscv/CHANGELOG.md b/riscv/CHANGELOG.md index 4f2dde0f..c61f9b22 100644 --- a/riscv/CHANGELOG.md +++ b/riscv/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed +- Make all CSR writes `unsafe` by default (#209) - Simplify register macros with `cfg` field - Align assembly functions with `cortex-m` - Use CSR helper macros to define `marchid` register diff --git a/riscv/src/register/macros.rs b/riscv/src/register/macros.rs index ac89c0d8..08fcfdcd 100644 --- a/riscv/src/register/macros.rs +++ b/riscv/src/register/macros.rs @@ -12,13 +12,13 @@ macro_rules! read_csr { /// Reads the CSR. /// /// **WARNING**: panics on non-`riscv` targets. - #[inline] + #[inline(always)] unsafe fn _read() -> usize { _try_read().unwrap() } /// Attempts to read the CSR. - #[inline] + #[inline(always)] unsafe fn _try_read() -> $crate::result::Result { match () { #[cfg($($cfg),*)] @@ -155,13 +155,13 @@ macro_rules! write_csr { /// Writes the CSR. /// /// **WARNING**: panics on non-`riscv` targets. - #[inline] + #[inline(always)] unsafe fn _write(bits: usize) { _try_write(bits).unwrap(); } /// Attempts to write the CSR. - #[inline] + #[inline(always)] #[cfg_attr(not($($cfg),*), allow(unused_variables))] unsafe fn _try_write(bits: usize) -> $crate::result::Result<()> { match () { @@ -195,9 +195,29 @@ macro_rules! write_csr_as { ($csr_type:ty, $csr_number:literal) => { $crate::write_csr_as!($csr_type, $csr_number, any(target_arch = "riscv32", target_arch = "riscv64")); }; + (safe $csr_type:ty, $csr_number:literal) => { + $crate::write_csr_as!(safe $csr_type, $csr_number, any(target_arch = "riscv32", target_arch = "riscv64")); + }; ($csr_type:ty, $csr_number:literal, $($cfg:meta),*) => { $crate::write_csr!($csr_number, $($cfg),*); + /// Writes the CSR. + /// + /// **WARNING**: panics on non-`riscv` targets. + #[inline] + pub unsafe fn write(value: $csr_type) { + _write(value.bits); + } + + /// Attempts to write the CSR. + #[inline] + pub unsafe fn try_write(value: $csr_type) -> $crate::result::Result<()> { + _try_write(value.bits) + } + }; + (safe $csr_type:ty, $csr_number:literal, $($cfg:meta),*) => { + $crate::write_csr!($csr_number, $($cfg),*); + /// Writes the CSR. /// /// **WARNING**: panics on non-`riscv` targets. @@ -220,6 +240,9 @@ macro_rules! write_csr_as_rv32 { ($csr_type:ty, $csr_number:literal) => { $crate::write_csr_as!($csr_type, $csr_number, target_arch = "riscv32"); }; + (safe $csr_type:ty, $csr_number:literal) => { + $crate::write_csr_as!(safe $csr_type, $csr_number, target_arch = "riscv32"); + }; } /// Convenience macro to write a [`usize`] value to a CSR register. @@ -228,9 +251,29 @@ macro_rules! write_csr_as_usize { ($csr_number:literal) => { $crate::write_csr_as_usize!($csr_number, any(target_arch = "riscv32", target_arch = "riscv64")); }; + (safe $csr_number:literal) => { + $crate::write_csr_as_usize!(safe $csr_number, any(target_arch = "riscv32", target_arch = "riscv64")); + }; ($csr_number:literal, $($cfg:meta),*) => { $crate::write_csr!($csr_number, $($cfg),*); + /// Writes the CSR. + /// + /// **WARNING**: panics on non-`riscv` targets. + #[inline] + pub unsafe fn write(bits: usize) { + _write(bits); + } + + /// Attempts to write the CSR. + #[inline] + pub unsafe fn try_write(bits: usize) -> $crate::result::Result<()> { + _try_write(bits) + } + }; + (safe $csr_number:literal, $($cfg:meta),*) => { + $crate::write_csr!($csr_number, $($cfg),*); + /// Writes the CSR. /// /// **WARNING**: panics on non-`riscv` targets. @@ -253,6 +296,9 @@ macro_rules! write_csr_as_usize_rv32 { ($csr_number:literal) => { $crate::write_csr_as_usize!($csr_number, target_arch = "riscv32"); }; + (safe $csr_number:literal) => { + $crate::write_csr_as_usize!(safe $csr_number, target_arch = "riscv32"); + }; } /// Convenience macro around the `csrrs` assembly instruction to set the CSR register. @@ -267,13 +313,13 @@ macro_rules! set { /// Set the CSR. /// /// **WARNING**: panics on non-`riscv` targets. - #[inline] + #[inline(always)] unsafe fn _set(bits: usize) { _try_set(bits).unwrap(); } /// Attempts to set the CSR. - #[inline] + #[inline(always)] #[cfg_attr(not($($cfg),*), allow(unused_variables))] unsafe fn _try_set(bits: usize) -> $crate::result::Result<()> { match () { @@ -311,13 +357,13 @@ macro_rules! clear { /// Clear the CSR. /// /// **WARNING**: panics on non-`riscv` targets. - #[inline] + #[inline(always)] unsafe fn _clear(bits: usize) { _try_clear(bits).unwrap(); } /// Attempts to clear the CSR. - #[inline] + #[inline(always)] #[cfg_attr(not($($cfg),*), allow(unused_variables))] unsafe fn _try_clear(bits: usize) -> $crate::result::Result<()> { match () {