Skip to content

Commit e7c85a8

Browse files
committed
Merge branch '✨-riscv-s' into 🦆
`r3_port_riscv` changelog: > ### Added > > - The new option `ThreadingOptions::PRIVILEGE_LEVEL` allows for > running the kernel in other privilege levels than M-mode. > - `use_sbi_timer!` can be used to install a timer driver based on > the RISC-V Supervisor Binary Interface. > > ### Changed > > - Rename `use_timer!` → `use_mtime!`, `TimerOptions` → `MtimeOptions`
2 parents e94ab41 + 80cd885 commit e7c85a8

File tree

28 files changed

+1409
-417
lines changed

28 files changed

+1409
-417
lines changed

.github/actions/install-qemu/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ inputs:
44
version:
55
description: QEMU version to install
66
required: true
7-
default: 5.1.0
7+
default: 6.1.0
88
target-list:
99
description: List of targets to build
1010
required: true

.github/workflows/ci.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ jobs:
214214
- { ty: riscv, runner_target: qemu_sifive_u_rv64, runner_args: --arch rv64i+m+a }
215215
# SiFive U, RV32GC
216216
- { ty: riscv, runner_target: qemu_sifive_u_rv32, runner_args: "" }
217+
# SiFive U, RV64GC, S-mode
218+
- { ty: riscv, runner_target: qemu_sifive_u_s_rv64, runner_args: "" }
219+
# SiFive U, RV32GC, S-mode
220+
- { ty: riscv, runner_target: qemu_sifive_u_s_rv32, runner_args: "" }
217221
# SiFive E, RV32IMAC
218222
- { ty: riscv, runner_target: qemu_sifive_e_rv32, runner_args: "" }
219223
# SiFive E, RV32IA
@@ -231,15 +235,15 @@ jobs:
231235
- name: Install dependencies (Linux)
232236
run: |
233237
sudo apt-get update
234-
sudo apt-get install libusb-1.0-0-dev libudev-dev
238+
sudo apt-get install libusb-1.0-0-dev libudev-dev ninja-build
235239
236240
- name: Cache QEMU's built binaries
237241
uses: actions/cache@v2
238242
with:
239243
path: ~/.qemu
240244
key: ${{ runner.os }}-ci-qemu-arm_riscv
241245

242-
- name: Install QEMU 5.1.0 from source
246+
- name: Install QEMU 6.1.0 from source
243247
uses: ./.github/actions/install-qemu
244248
with:
245249
target-list: arm-softmmu,riscv32-softmmu,riscv64-softmmu

Cargo.lock

Lines changed: 22 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/testing.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ The following table shows how to run the kernel test suite for each target.
4141
| RV32GC | [SiFive U][] (QEMU) | `cargo r3test -t qemu_sifive_u_rv32` |
4242
| RV64IMAC | SiFive U (QEMU) | `cargo r3test -t qemu_sifive_u_rv64 -a rv64i+m+a+c` |
4343
| RV64GC | SiFive U (QEMU) | `cargo r3test -t qemu_sifive_u_rv64` |
44+
| RV64GC | SiFive U (S-mode, QEMU) | `cargo r3test -t qemu_sifive_u_s_rv64` |
4445
| RV32IMAC | [RED-V][] (SPI flash XIP) | `cargo r3test -t red_v` |
4546
| RV64GC | [Maix][] boards (UART ISP) | `cargo r3test -t maix` |
4647

src/r3_port_riscv/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- The new option `ThreadingOptions::PRIVILEGE_LEVEL` allows for running the kernel in other privilege levels than M-mode.
13+
- `use_sbi_timer!` can be used to install a timer driver based on [the RISC-V Supervisor Binary Interface](https://github.com/riscv-non-isa/riscv-sbi-doc).
14+
15+
### Changed
16+
17+
- Rename `use_timer!``use_mtime!`, `TimerOptions``MtimeOptions`
18+
1019
### Fixed
1120

1221
- The default stack alignment (`PortThreading::STACK_ALIGN`) now conforms to the standard ABI requirement (128-bit alignment).
22+
- The port startup code now calls `<Traits as Timer>::init`.
1323

1424
## [0.1.3] - 2021-10-29
1525

src/r3_port_riscv/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ r3_kernel = { version = "0.0.0", path = "../r3_kernel" }
2222
r3_core = { version = "0.1.0", path = "../r3_core" }
2323

2424
tock-registers = { version = "0.7.0" }
25+
unstringify = { version = "0.1.4" }
26+
seq-macro = { version = "0.3.0" }
2527
svgbobdoc = { version = "0.3.0-alpha.4" }
2628
riscv-rt = { version = ">= 0.6.0, < 0.9.0" }
2729
riscv = { version = ">= 0.5.0, < 0.8.0" }

src/r3_port_riscv/src/lib.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,4 @@ The trap handler stores a first-level state directly below the current stack poi
197197

198198
## Processor Modes
199199

200-
All code executes in Machine mode. The value of `mstatus.MPP` is always `M` (`0b11`).
200+
All code executes in Machine mode by default. The value of `mstatus.MPP` is always `M` (`0b11`). Other modes can be selected by [`ThreadingOptions::PRIVILEGE_LEVEL`], which changes all CSRs and CSR values accordingly.

src/r3_port_riscv/src/lib.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
#![feature(const_mut_refs)]
1010
#![feature(const_fn_fn_ptr_basics)]
1111
#![feature(const_trait_impl)]
12+
#![feature(generic_const_exprs)]
1213
#![deny(unsafe_op_in_unsafe_fn)]
1314
#![deny(unsupported_naked_functions)]
1415
#![doc(html_logo_url = "https://r3-os.github.io/r3/logo-small.svg")]
1516
#![doc = include_str!("./lib.md")]
1617
#![doc = include_str!("./common.md")]
1718
#![doc = include!("../doc/interrupts.rs")] // `![interrupts]`
19+
#![recursion_limit = "1024"]
1820
#![no_std]
1921
use core::ops::Range;
2022
use r3_core::kernel::{
@@ -66,17 +68,25 @@ pub mod threading {
6668
pub mod imp;
6769
}
6870

69-
/// The standard timer driver.
71+
/// The `mtime`-based timer driver.
7072
#[doc(hidden)]
71-
pub mod timer {
73+
pub mod mtime {
7274
pub mod cfg;
7375
pub mod imp;
7476
}
7577

78+
/// The SBI-based timer driver.
79+
#[doc(hidden)]
80+
pub mod sbi_timer {
81+
pub mod cfg;
82+
pub mod imp;
83+
}
84+
85+
pub use self::mtime::cfg::*;
7686
pub use self::plic::cfg::*;
7787
pub use self::rt::cfg::*;
88+
pub use self::sbi_timer::cfg::*;
7889
pub use self::threading::cfg::*;
79-
pub use self::timer::cfg::*;
8090

8191
/// Defines the entry points of a port instantiation. Implemented by
8292
/// [`use_port!`].
@@ -85,7 +95,9 @@ pub trait EntryPoint {
8595
///
8696
/// # Safety
8797
///
88-
/// - The processor should be in M-mode and have M-mode interrupts masked.
98+
/// - The processor should be in the privilege mode specified by
99+
/// [`ThreadingOptions::PRIVILEGE_LEVEL`] and have interrupts masked for
100+
/// this privilege level.
89101
/// - This method hasn't been entered yet.
90102
///
91103
unsafe fn start() -> !;
@@ -96,15 +108,17 @@ pub trait EntryPoint {
96108
///
97109
/// # Safety
98110
///
99-
/// - The processor should be in M-mode and have M-mode interrupts masked.
111+
/// - The processor should be in the privilege mode specified by
112+
/// [`ThreadingOptions::PRIVILEGE_LEVEL`] and have interrupts masked for
113+
/// this privilege level
100114
/// - The register state of the background context should be preserved so
101115
/// that the handler can restore it later.
102116
///
103117
const TRAP_HANDLER: unsafe extern "C" fn() -> !;
104118
}
105119

106120
/// An abstract inferface to a port timer driver. Implemented by
107-
/// [`use_timer!`].
121+
/// [`use_mtime!`] and [`use_sbi_timer!`].
108122
pub trait Timer {
109123
/// Initialize the driver. This will be called just before entering
110124
/// [`PortToKernel::boot`].

src/r3_port_riscv/src/timer/cfg.rs renamed to src/r3_port_riscv/src/mtime/cfg.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
//! The public interface for the RISC-V timer.
1+
//! The public interface for the `mtime`-based timer driver.
22
use r3_core::kernel::InterruptNum;
33

4-
/// Attach the implementation of [`PortTimer`] that is based on the RISC-V timer
5-
/// (`mtime`/`mtimecfg`) to a given kernel trait type. This macro also
4+
/// Attach the implementation of [`PortTimer`] based on the RISC-V machine-mode
5+
/// timer (`mtime`/`mtimecfg`) to a given kernel trait type. This macro also
66
/// implements [`Timer`] on the system type.
7-
/// **Requires [`TimerOptions`].**
7+
/// **Requires [`MtimeOptions`].**
88
///
99
/// [`PortTimer`]: r3_kernel::PortTimer
1010
/// [`Timer`]: crate::Timer
1111
///
1212
/// You should do the following:
1313
///
14-
/// - Implement [`TimerOptions`] on the system type `$Traits`.
14+
/// - Implement [`MtimeOptions`] on the system type `$Traits`.
1515
/// - Call `$Traits::configure_timer()` in your configuration function.
1616
/// See the following example.
1717
///
1818
/// ```rust,ignore
19-
/// r3_port_riscv::use_timer!(unsafe impl PortTimer for System);
19+
/// r3_port_riscv::use_mtime!(unsafe impl PortTimer for System);
2020
///
21-
/// impl r3_port_riscv::TimerOptions for System {
21+
/// impl r3_port_riscv::MtimeOptions for System {
2222
/// const MTIME_PTR: usize = 0x1001_1000;
2323
/// const MTIMECMP_PTR: usize = 0x1001_1000;
2424
/// const FREQUENCY: u64 = 1_000_000;
@@ -32,10 +32,10 @@ use r3_core::kernel::InterruptNum;
3232
///
3333
/// # Safety
3434
///
35-
/// - `TimerOptions` must be configured correctly.
35+
/// - `MtimeOptions` must be configured correctly.
3636
///
3737
#[macro_export]
38-
macro_rules! use_timer {
38+
macro_rules! use_mtime {
3939
(unsafe impl PortTimer for $Traits:ty) => {
4040
const _: () = {
4141
use $crate::r3_core::{
@@ -44,55 +44,55 @@ macro_rules! use_timer {
4444
};
4545
use $crate::r3_kernel::{PortTimer, System, UTicks};
4646
use $crate::r3_portkit::tickless;
47-
use $crate::{timer, Timer, TimerOptions};
47+
use $crate::{mtime, MtimeOptions, Timer};
4848

4949
impl PortTimer for $Traits {
5050
const MAX_TICK_COUNT: UTicks = u32::MAX;
5151
const MAX_TIMEOUT: UTicks = u32::MAX;
5252

5353
unsafe fn tick_count() -> UTicks {
5454
// Safety: We are just forwarding the call
55-
unsafe { timer::imp::tick_count::<Self>() }
55+
unsafe { mtime::imp::tick_count::<Self>() }
5656
}
5757

5858
unsafe fn pend_tick() {
5959
// Safety: We are just forwarding the call
60-
unsafe { timer::imp::pend_tick::<Self>() }
60+
unsafe { mtime::imp::pend_tick::<Self>() }
6161
}
6262

6363
unsafe fn pend_tick_after(tick_count_delta: UTicks) {
6464
// Safety: We are just forwarding the call
65-
unsafe { timer::imp::pend_tick_after::<Self>(tick_count_delta) }
65+
unsafe { mtime::imp::pend_tick_after::<Self>(tick_count_delta) }
6666
}
6767
}
6868

6969
impl Timer for $Traits {
7070
unsafe fn init() {
71-
unsafe { timer::imp::init::<Self>() }
71+
unsafe { mtime::imp::init::<Self>() }
7272
}
7373
}
7474

7575
const TICKLESS_CFG: tickless::TicklessCfg =
7676
match tickless::TicklessCfg::new(tickless::TicklessOptions {
77-
hw_freq_num: <$Traits as TimerOptions>::FREQUENCY,
78-
hw_freq_denom: <$Traits as TimerOptions>::FREQUENCY_DENOMINATOR,
79-
hw_headroom_ticks: <$Traits as TimerOptions>::HEADROOM,
77+
hw_freq_num: <$Traits as MtimeOptions>::FREQUENCY,
78+
hw_freq_denom: <$Traits as MtimeOptions>::FREQUENCY_DENOMINATOR,
79+
hw_headroom_ticks: <$Traits as MtimeOptions>::HEADROOM,
8080
// `mtime` is a 64-bit free-running counter and it is
8181
// expensive to create a 32-bit timer with an arbitrary
8282
// period out of it.
8383
force_full_hw_period: true,
8484
// If clearing `mtime` is not allowed, we must record the
8585
// starting value of `mtime` by calling `reset`.
86-
resettable: !<$Traits as TimerOptions>::RESET_MTIME,
86+
resettable: !<$Traits as MtimeOptions>::RESET_MTIME,
8787
}) {
8888
Ok(x) => x,
8989
Err(e) => e.panic(),
9090
};
9191

9292
static mut TIMER_STATE: tickless::TicklessState<TICKLESS_CFG> = Init::INIT;
9393

94-
// Safety: Only `use_timer!` is allowed to `impl` this
95-
unsafe impl timer::imp::TimerInstance for $Traits {
94+
// Safety: Only `use_mtime!` is allowed to `impl` this
95+
unsafe impl mtime::imp::TimerInstance for $Traits {
9696
const TICKLESS_CFG: tickless::TicklessCfg = TICKLESS_CFG;
9797

9898
type TicklessState = tickless::TicklessState<TICKLESS_CFG>;
@@ -107,15 +107,15 @@ macro_rules! use_timer {
107107
where
108108
C: ~const traits::CfgInterruptLine<System = System<Self>>,
109109
{
110-
timer::imp::configure(b);
110+
mtime::imp::configure(b);
111111
}
112112
}
113113
};
114114
};
115115
}
116116

117-
/// The options for [`use_timer!`].
118-
pub trait TimerOptions {
117+
/// The options for [`use_mtime!`].
118+
pub trait MtimeOptions {
119119
/// The memory address of the `mtime` register.
120120
const MTIME_PTR: usize;
121121

0 commit comments

Comments
 (0)