Skip to content

Commit 297aa6e

Browse files
committed
m-mode as default
1 parent e70afe4 commit 297aa6e

File tree

6 files changed

+132
-113
lines changed

6 files changed

+132
-113
lines changed

riscv-semihosting/Cargo.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ edition = "2021"
1717
rust-version = "1.60.0"
1818

1919
[features]
20-
default = ["jlink-quirks"]
21-
machine-mode = []
22-
user-mode = []
20+
u-mode = []
2321
jlink-quirks = []
2422
no-semihosting = []
23+
default = ["jlink-quirks"]
2524

2625
[dependencies]
27-
riscv = "0.8.0"
28-
cfg-if = "1.0.0"
26+
critical-section = "1.0.0"
27+
riscv = {path = "../riscv", version = "0.10.1"}

riscv-semihosting/build.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use std::env;
2+
3+
fn main() {
4+
let target = env::var("TARGET").unwrap();
5+
6+
if target.starts_with("riscv") {
7+
println!("cargo:rustc-cfg=riscv");
8+
}
9+
}

riscv-semihosting/src/debug.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,14 @@
1111
//! ```no_run
1212
//! use riscv_semihosting::debug::{self, EXIT_SUCCESS, EXIT_FAILURE};
1313
//!
14-
//! fn main() {
15-
//! if 2 == 2 {
16-
//! // report success
17-
//! debug::exit(EXIT_SUCCESS);
18-
//! } else {
19-
//! // report failure
20-
//! debug::exit(EXIT_FAILURE);
21-
//! }
14+
//! if 2 == 2 {
15+
//! // report success
16+
//! debug::exit(EXIT_SUCCESS);
17+
//! } else {
18+
//! // report failure
19+
//! debug::exit(EXIT_FAILURE);
2220
//! }
23-
//!
21+
//!```
2422
2523
/// This values are taken from section 5.5.2 of
2624
/// ADS Debug Target Guide (DUI0058).

riscv-semihosting/src/export.rs

Lines changed: 92 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,103 @@
11
//! IMPLEMENTATION DETAILS USED BY MACROS
22
3+
use crate::hio::{self, HostStream};
34
use core::fmt::{self, Write};
45

5-
#[cfg(feature = "machine-mode")]
6-
use riscv::interrupt;
6+
static mut HSTDOUT: Option<HostStream> = None;
77

8-
use crate::hio::{self, HostStream};
8+
static mut HSTDERR: Option<HostStream> = None;
99

10-
static mut HSTDOUT: Option<HostStream> = None;
10+
#[cfg(not(feature = "u-mode"))]
11+
mod machine {
12+
use super::*;
13+
14+
pub fn hstdout_str(s: &str) {
15+
let _result = critical_section::with(|_| unsafe {
16+
if HSTDOUT.is_none() {
17+
HSTDOUT = Some(hio::hstdout()?);
18+
}
19+
20+
HSTDOUT.as_mut().unwrap().write_str(s).map_err(drop)
21+
});
22+
}
23+
24+
pub fn hstdout_fmt(args: fmt::Arguments) {
25+
let _result = critical_section::with(|_| unsafe {
26+
if HSTDOUT.is_none() {
27+
HSTDOUT = Some(hio::hstdout()?);
28+
}
29+
30+
HSTDOUT.as_mut().unwrap().write_fmt(args).map_err(drop)
31+
});
32+
}
33+
34+
pub fn hstderr_str(s: &str) {
35+
let _result = critical_section::with(|_| unsafe {
36+
if HSTDERR.is_none() {
37+
HSTDERR = Some(hio::hstderr()?);
38+
}
39+
40+
HSTDERR.as_mut().unwrap().write_str(s).map_err(drop)
41+
});
42+
}
43+
44+
pub fn hstderr_fmt(args: fmt::Arguments) {
45+
let _result = critical_section::with(|_| unsafe {
46+
if HSTDERR.is_none() {
47+
HSTDERR = Some(hio::hstderr()?);
48+
}
49+
50+
HSTDERR.as_mut().unwrap().write_fmt(args).map_err(drop)
51+
});
52+
}
53+
}
54+
#[cfg(not(feature = "u-mode"))]
55+
pub use machine::*;
56+
57+
#[cfg(feature = "u-mode")]
58+
mod user {
59+
use super::*;
60+
pub fn hstdout_str(s: &str) {
61+
let _result = unsafe {
62+
if HSTDOUT.is_none() {
63+
HSTDOUT = Some(hio::hstdout().unwrap());
64+
}
65+
66+
HSTDOUT.as_mut().unwrap().write_str(s).map_err(drop)
67+
};
68+
}
1169

12-
#[cfg(not(feature = "no-semihosting"))]
13-
cfg_if::cfg_if! {
14-
if #[cfg(feature="machine-mode")] {
15-
pub fn hstdout_str(s: &str) {
16-
let _result = interrupt::free(|_| unsafe {
17-
if HSTDOUT.is_none() {
18-
HSTDOUT = Some(hio::hstdout()?);
19-
}
20-
21-
HSTDOUT.as_mut().unwrap().write_str(s).map_err(drop)
22-
});
23-
}
24-
25-
pub fn hstdout_fmt(args: fmt::Arguments) {
26-
let _result = interrupt::free(|_| unsafe {
27-
if HSTDOUT.is_none() {
28-
HSTDOUT = Some(hio::hstdout()?);
29-
}
30-
31-
HSTDOUT.as_mut().unwrap().write_fmt(args).map_err(drop)
32-
});
33-
}
34-
35-
static mut HSTDERR: Option<HostStream> = None;
36-
37-
pub fn hstderr_str(s: &str) {
38-
let _result = interrupt::free(|_| unsafe {
39-
if HSTDERR.is_none() {
40-
HSTDERR = Some(hio::hstderr()?);
41-
}
42-
43-
HSTDERR.as_mut().unwrap().write_str(s).map_err(drop)
44-
});
45-
}
46-
47-
pub fn hstderr_fmt(args: fmt::Arguments) {
48-
let _result = interrupt::free(|_| unsafe {
49-
if HSTDERR.is_none() {
50-
HSTDERR = Some(hio::hstderr()?);
51-
}
52-
53-
HSTDERR.as_mut().unwrap().write_fmt(args).map_err(drop)
54-
});
55-
}
70+
pub fn hstdout_fmt(args: fmt::Arguments) {
71+
let _result = unsafe {
72+
if HSTDOUT.is_none() {
73+
HSTDOUT = Some(hio::hstdout().unwrap());
74+
}
75+
76+
HSTDOUT.as_mut().unwrap().write_fmt(args).map_err(drop)
77+
};
5678
}
57-
else if #[cfg(feature = "user-mode")] {
58-
pub fn hstdout_str(s: &str) {
59-
let _result = unsafe {
60-
if HSTDOUT.is_none() {
61-
HSTDOUT = Some(hio::hstdout().unwrap());
62-
}
63-
64-
HSTDOUT.as_mut().unwrap().write_str(s).map_err(drop)
65-
};
66-
}
67-
68-
pub fn hstdout_fmt(args: fmt::Arguments) {
69-
let _result = unsafe {
70-
if HSTDOUT.is_none() {
71-
HSTDOUT = Some(hio::hstdout().unwrap());
72-
}
73-
74-
HSTDOUT.as_mut().unwrap().write_fmt(args).map_err(drop)
75-
};
76-
}
77-
78-
static mut HSTDERR: Option<HostStream> = None;
79-
80-
pub fn hstderr_str(s: &str) {
81-
let _result = unsafe {
82-
if HSTDERR.is_none() {
83-
HSTDERR = Some(hio::hstderr().unwrap());
84-
}
85-
86-
HSTDERR.as_mut().unwrap().write_str(s).map_err(drop)
87-
};
88-
}
89-
90-
pub fn hstderr_fmt(args: fmt::Arguments) {
91-
let _result = unsafe {
92-
if HSTDERR.is_none() {
93-
HSTDERR = Some(hio::hstderr().unwrap());
94-
}
95-
96-
HSTDERR.as_mut().unwrap().write_fmt(args).map_err(drop)
97-
};
98-
}
79+
80+
static mut HSTDERR: Option<HostStream> = None;
81+
82+
pub fn hstderr_str(s: &str) {
83+
let _result = unsafe {
84+
if HSTDERR.is_none() {
85+
HSTDERR = Some(hio::hstderr().unwrap());
86+
}
87+
88+
HSTDERR.as_mut().unwrap().write_str(s).map_err(drop)
89+
};
9990
}
100-
else {
101-
compile_error!("A privilege level has not been selected. Enable either \
102-
the machine-mode or user-mode features as appropriate \
103-
for your use case.");
91+
92+
pub fn hstderr_fmt(args: fmt::Arguments) {
93+
let _result = unsafe {
94+
if HSTDERR.is_none() {
95+
HSTDERR = Some(hio::hstderr().unwrap());
96+
}
97+
98+
HSTDERR.as_mut().unwrap().write_fmt(args).map_err(drop)
99+
};
104100
}
105101
}
102+
#[cfg(feature = "u-mode")]
103+
pub use user::*;

riscv-semihosting/src/hio.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Host I/O
22
3+
// Fixing this lint requires a breaking change that does not add much value
4+
#![allow(clippy::result_unit_err)]
5+
36
use crate::nr;
47
use core::{fmt, slice};
58

riscv-semihosting/src/lib.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@
180180
#![deny(missing_docs)]
181181
#![no_std]
182182

183+
#[cfg(all(riscv, not(feature = "no-semihosting")))]
183184
use core::arch::asm;
184185

185186
#[macro_use]
@@ -192,23 +193,33 @@ pub mod hio;
192193
pub mod nr;
193194

194195
/// Performs a semihosting operation, takes a pointer to an argument block
196+
///
197+
/// # Safety
198+
///
199+
/// The syscall number must be a valid [semihosting operation],
200+
/// and the arguments must be valid for the associated operation.
201+
///
202+
/// [semihosting operation]: https://developer.arm.com/documentation/dui0471/i/semihosting/semihosting-operations?lang=en
195203
#[inline(always)]
196204
pub unsafe fn syscall<T>(nr: usize, arg: &T) -> usize {
197205
syscall1(nr, arg as *const T as usize)
198206
}
199207

200208
/// Performs a semihosting operation, takes one integer as an argument
209+
///
210+
/// # Safety
211+
///
212+
/// Same as [`syscall`].
201213
#[inline(always)]
202214
pub unsafe fn syscall1(_nr: usize, _arg: usize) -> usize {
203215
match () {
204-
#[cfg(not(feature = "no-semihosting"))]
216+
#[cfg(all(riscv, not(feature = "no-semihosting")))]
205217
() => {
206218
let mut nr = _nr;
207219
// The instructions below must always be uncompressed, otherwise
208220
// it will be treated as a regular break, hence the norvc option.
209221
//
210-
// See https://github.com/riscv/riscv-semihosting-spec for more
211-
// details.
222+
// See https://github.com/riscv/riscv-semihosting-spec for more details.
212223
asm!("
213224
.option push
214225
.option norvc
@@ -222,8 +233,9 @@ pub unsafe fn syscall1(_nr: usize, _arg: usize) -> usize {
222233
);
223234
nr
224235
}
225-
226-
#[cfg(feature = "no-semihosting")]
236+
#[cfg(all(riscv, feature = "no-semihosting"))]
227237
() => 0,
238+
#[cfg(not(riscv))]
239+
() => unimplemented!(),
228240
}
229241
}

0 commit comments

Comments
 (0)