Skip to content

Commit a38fb8d

Browse files
Merge pull request #141 from luojia65/luojia65/asm-fixes
asm: set unsafety of `nop` and `delay` functions to safe
2 parents 622f6fe + f422a25 commit a38fb8d

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1818

1919
- CI actions updated. They now use `checkout@v3` and `dtolnay/rust-toolchain`.
2020
- `mcause::{Interrupt, Exception}` and `scause::{Interrupt, Exception}` now implement `From` trait for `usize`
21+
- Set safety of `asm::nop` and `asm::delay` functions to safe.
2122

2223
### Fixed
2324

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ plic = ["volatile-register"]
2626
bit_field = "0.10.0"
2727
critical-section = "1.1.0"
2828
embedded-hal = "0.2.6"
29-
volatile-register = {version = "0.2.1", optional = true}
29+
volatile-register = { version = "0.2.1", optional = true }

src/asm.rs

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Assembly instructions
22
33
macro_rules! instruction {
4-
($(#[$attr:meta])*, $fnname:ident, $asm:expr) => (
4+
($(#[$attr:meta])*, unsafe $fnname:ident, $asm:expr) => (
55
$(#[$attr])*
66
#[inline]
77
pub unsafe fn $fnname() {
@@ -13,25 +13,42 @@ macro_rules! instruction {
1313
() => unimplemented!(),
1414
}
1515
}
16-
)
16+
);
17+
($(#[$attr:meta])*, $fnname:ident, $asm:expr) => (
18+
$(#[$attr])*
19+
#[inline]
20+
pub fn $fnname() {
21+
match () {
22+
#[cfg(riscv)]
23+
() => unsafe { core::arch::asm!($asm) },
24+
25+
#[cfg(not(riscv))]
26+
() => unimplemented!(),
27+
}
28+
}
29+
);
1730
}
1831

1932
instruction!(
2033
/// `nop` instruction wrapper
2134
///
22-
/// Generates a no-operation. Useful to prevent delay loops from being optimized away.
35+
/// The `NOP` instruction does not change any architecturally visible state, except for
36+
/// advancing the pc and incrementing any applicable performance counters.
37+
///
38+
/// This function generates a no-operation; it's useful to prevent delay loops from being
39+
/// optimized away.
2340
, nop, "nop");
2441
instruction!(
2542
/// `EBREAK` instruction wrapper
2643
///
2744
/// Generates a breakpoint exception.
28-
, ebreak, "ebreak");
45+
, unsafe ebreak, "ebreak");
2946
instruction!(
3047
/// `WFI` instruction wrapper
3148
///
3249
/// Provides a hint to the implementation that the current hart can be stalled until an interrupt might need servicing.
3350
/// The WFI instruction is just a hint, and a legal implementation is to implement WFI as a NOP.
34-
, wfi, "wfi");
51+
, unsafe wfi, "wfi");
3552
instruction!(
3653
/// `SFENCE.VMA` instruction wrapper (all address spaces and page table levels)
3754
///
@@ -40,7 +57,7 @@ instruction!(
4057
/// are ordinarily not ordered with respect to loads and stores in the instruction stream.
4158
/// Executing an `SFENCE.VMA` instruction guarantees that any stores in the instruction stream prior to the
4259
/// `SFENCE.VMA` are ordered before all implicit references subsequent to the `SFENCE.VMA`.
43-
, sfence_vma_all, "sfence.vma");
60+
, unsafe sfence_vma_all, "sfence.vma");
4461
instruction!(
4562
/// `FENCE` instruction wrapper
4663
///
@@ -54,7 +71,7 @@ instruction!(
5471
/// The FENCE instruction also orders memory reads and writes made by the hart as observed by
5572
/// memory reads and writes made by an external device. However, FENCE does not order observations
5673
/// of events made by an external device using any other signaling mechanism.
57-
, fence, "fence");
74+
, unsafe fence, "fence");
5875
instruction!(
5976
/// `FENCE.I` instruction wrapper
6077
///
@@ -72,7 +89,7 @@ instruction!(
7289
/// The unused fields in the FENCE.I instruction, imm\[11:0\], rs1, and rd, are reserved for
7390
/// finer-grain fences in future extensions. For forward compatibility, base
7491
/// implementations shall ignore these fields, and standard software shall zero these fields.
75-
, fence_i, "fence.i");
92+
, unsafe fence_i, "fence.i");
7693

7794
/// `SFENCE.VMA` instruction wrapper
7895
///
@@ -104,10 +121,10 @@ pub unsafe fn sfence_vma(asid: usize, addr: usize) {
104121
/// any other case please use a more accurate method to produce a delay.
105122
#[inline]
106123
#[allow(unused_variables)]
107-
pub unsafe fn delay(cycles: u32) {
124+
pub fn delay(cycles: u32) {
108125
match () {
109126
#[cfg(riscv)]
110-
() => {
127+
() => unsafe {
111128
let real_cyc = 1 + cycles / 2;
112129
core::arch::asm!(
113130
"1:",
@@ -116,7 +133,7 @@ pub unsafe fn delay(cycles: u32) {
116133
inout(reg) real_cyc => _,
117134
options(nomem, nostack),
118135
)
119-
}
136+
},
120137

121138
#[cfg(not(riscv))]
122139
() => unimplemented!(),

0 commit comments

Comments
 (0)