Skip to content

Commit f4e29c4

Browse files
committed
async stuff (WIP)
1 parent 2531e68 commit f4e29c4

File tree

2 files changed

+19
-15
lines changed

2 files changed

+19
-15
lines changed

riscv-peripheral/src/hal_async/aclint.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
//! The following `extern "Rust"` functions must be implemented:
1212
//!
1313
//! - `fn _riscv_peripheral_aclint_mtimer(hart_id: usize) -> MTIMER`: This function returns the `MTIMER` register for the given HART ID.
14+
//! This function is implemented by the [`crate::clint_codegen`] macro when asyn_delay is provided.
1415
//! - `fn _riscv_peripheral_aclint_push_timer(t: Timer) -> Result<(), Timer>`: This function pushes a new timer to a timer queue assigned to the given HART ID.
1516
//! If it fails (e.g., the timer queue is full), it returns back the timer that failed to be pushed.
1617
//! The logic of timer queues are application-specific and are not provided by this crate.
17-
//! - `fn _riscv_peripheral_aclint_wake_timers(hart_id: usize, current_tick: u64) -> Option<u64>`:
18-
//! This function pops all the expired timers from a timer queue assigned to the given HART ID and wakes their associated wakers.
18+
//! - `fn _riscv_peripheral_aclint_wake_timers(current_tick: u64) -> Option<u64>`:
19+
//! This function pops all the expired timers from a timer queue assigned to the current HART ID and wakes their associated wakers.
1920
//! The function returns the next [`MTIME`] tick at which the next timer expires. If the queue is empty, it returns `None`.
2021
2122
use crate::aclint::mtimer::{MTIME, MTIMECMP, MTIMER};
@@ -28,13 +29,13 @@ use core::{
2829
};
2930

3031
extern "Rust" {
31-
/// Returns the `MTIMER` register for the given HART ID.
32+
/// Returns the `MTIMER` register for the current HART ID.
3233
/// This is necessary for [`MachineTimer`] to obtain the corresponding `MTIMER` register.
3334
///
3435
/// # Safety
3536
///
3637
/// Do not call this function directly. It is only meant to be called by [`MachineTimer`].
37-
fn _riscv_peripheral_aclint_mtimer(hart_id: usize) -> MTIMER;
38+
fn _riscv_peripheral_aclint_mtimer() -> MTIMER;
3839

3940
/// Tries to push a new timer to the timer queue assigned to the given HART ID.
4041
/// If it fails (e.g., the timer queue is full), it returns back the timer that failed to be pushed.
@@ -44,15 +45,15 @@ extern "Rust" {
4445
/// Do not call this function directly. It is only meant to be called by [`DelayAsync`].
4546
fn _riscv_peripheral_aclint_push_timer(t: Timer) -> Result<(), Timer>;
4647

47-
/// Pops all the expired timers from the timer queue assigned to the given HART ID and wakes their associated wakers.
48+
/// Pops all the expired timers from the timer queue assigned to the current HART ID and wakes their associated wakers.
4849
/// Once it is done, if the queue is empty, it returns `None`.
4950
/// Alternatively, if the queue is not empty but the earliest timer has not expired yet,
5051
/// it returns `Some(next_expires)` where `next_expires` is the tick at which this timer expires.
5152
///
5253
/// # Safety
5354
///
5455
/// Do not call this function directly. It is only meant to be called by [`MachineTimer`] and [`DelayAsync`].
55-
fn _riscv_peripheral_aclint_wake_timers(hart_id: usize, current_tick: u64) -> Option<u64>;
56+
fn _riscv_peripheral_aclint_wake_timers(current_tick: u64) -> Option<u64>;
5657
}
5758

5859
/// Machine-level timer interrupt handler. This handler is triggered whenever the `MTIME`
@@ -61,20 +62,17 @@ extern "Rust" {
6162
#[allow(non_snake_case)]
6263
fn MachineTimer() {
6364
// recover the MTIME and MTIMECMP registers for the current HART
64-
let hart_id = riscv::register::mhartid::read();
65-
let mtimer = unsafe { _riscv_peripheral_aclint_mtimer(hart_id) };
65+
let mtimer = unsafe { _riscv_peripheral_aclint_mtimer() };
6666
let (mtime, mtimercmp) = (mtimer.mtime, mtimer.mtimecmp_mhartid());
6767
// schedule the next machine timer interrupt
68-
schedule_machine_timer(hart_id, mtime, mtimercmp);
68+
schedule_machine_timer(mtime, mtimercmp);
6969
}
7070

7171
/// Schedules the next machine timer interrupt for the given HART ID according to the timer queue.
72-
fn schedule_machine_timer(hart_id: usize, mtime: MTIME, mtimercmp: MTIMECMP) {
72+
fn schedule_machine_timer(mtime: MTIME, mtimercmp: MTIMECMP) {
7373
unsafe { riscv::register::mie::clear_mtimer() }; // disable machine timer interrupts to avoid reentrancy
7474
let current_tick = mtime.read();
75-
if let Some(next_expires) =
76-
unsafe { _riscv_peripheral_aclint_wake_timers(hart_id, current_tick) }
77-
{
75+
if let Some(next_expires) = unsafe { _riscv_peripheral_aclint_wake_timers(current_tick) } {
7876
debug_assert!(next_expires > current_tick);
7977
mtimercmp.write(next_expires); // schedule next interrupt at next_expires
8078
unsafe { riscv::register::mie::set_mtimer() }; // enable machine timer interrupts again if necessary
@@ -102,7 +100,7 @@ impl Delay {
102100
#[inline]
103101
pub fn new(freq: usize) -> Self {
104102
let hart_id = riscv::register::mhartid::read();
105-
let mtimer = unsafe { _riscv_peripheral_aclint_mtimer(hart_id) };
103+
let mtimer = unsafe { _riscv_peripheral_aclint_mtimer() };
106104
let (mtime, mtimecmp) = (mtimer.mtime, mtimer.mtimecmp_mhartid());
107105
Self {
108106
hart_id,
@@ -275,7 +273,7 @@ impl<'a> Future for DelayAsync<'a> {
275273
_riscv_peripheral_aclint_push_timer(timer).expect("timer queue is full");
276274
};
277275
// we also need to reschedule the machine timer interrupt
278-
schedule_machine_timer(self.delay.hart_id, self.delay.mtime, self.delay.mtimecmp);
276+
schedule_machine_timer(self.delay.mtime, self.delay.mtimecmp);
279277
}
280278
Poll::Pending
281279
} else {

riscv-peripheral/src/macros.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ macro_rules! clint_codegen {
214214
$crate::clint_codegen!($($tail)*);
215215
};
216216
(async_delay, $($tail:tt)*) => {
217+
218+
#[no_mangle]
219+
const fn _riscv_peripheral_aclint_mtimer() -> $crate::aclint::mtimer::MTIMER {
220+
CLINT::mtimer()
221+
}
222+
217223
impl CLINT {
218224
/// Asynchronous delay implementation for CLINT peripherals.
219225
///

0 commit comments

Comments
 (0)