11
11
//! The following `extern "Rust"` functions must be implemented:
12
12
//!
13
13
//! - `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.
14
15
//! - `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.
15
16
//! If it fails (e.g., the timer queue is full), it returns back the timer that failed to be pushed.
16
17
//! 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.
19
20
//! The function returns the next [`MTIME`] tick at which the next timer expires. If the queue is empty, it returns `None`.
20
21
21
22
use crate :: aclint:: mtimer:: { MTIME , MTIMECMP , MTIMER } ;
@@ -28,13 +29,13 @@ use core::{
28
29
} ;
29
30
30
31
extern "Rust" {
31
- /// Returns the `MTIMER` register for the given HART ID.
32
+ /// Returns the `MTIMER` register for the current HART ID.
32
33
/// This is necessary for [`MachineTimer`] to obtain the corresponding `MTIMER` register.
33
34
///
34
35
/// # Safety
35
36
///
36
37
/// 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 ;
38
39
39
40
/// Tries to push a new timer to the timer queue assigned to the given HART ID.
40
41
/// 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" {
44
45
/// Do not call this function directly. It is only meant to be called by [`DelayAsync`].
45
46
fn _riscv_peripheral_aclint_push_timer ( t : Timer ) -> Result < ( ) , Timer > ;
46
47
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.
48
49
/// Once it is done, if the queue is empty, it returns `None`.
49
50
/// Alternatively, if the queue is not empty but the earliest timer has not expired yet,
50
51
/// it returns `Some(next_expires)` where `next_expires` is the tick at which this timer expires.
51
52
///
52
53
/// # Safety
53
54
///
54
55
/// 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 > ;
56
57
}
57
58
58
59
/// Machine-level timer interrupt handler. This handler is triggered whenever the `MTIME`
@@ -61,20 +62,17 @@ extern "Rust" {
61
62
#[ allow( non_snake_case) ]
62
63
fn MachineTimer ( ) {
63
64
// 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 ( ) } ;
66
66
let ( mtime, mtimercmp) = ( mtimer. mtime , mtimer. mtimecmp_mhartid ( ) ) ;
67
67
// schedule the next machine timer interrupt
68
- schedule_machine_timer ( hart_id , mtime, mtimercmp) ;
68
+ schedule_machine_timer ( mtime, mtimercmp) ;
69
69
}
70
70
71
71
/// 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 ) {
73
73
unsafe { riscv:: register:: mie:: clear_mtimer ( ) } ; // disable machine timer interrupts to avoid reentrancy
74
74
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) } {
78
76
debug_assert ! ( next_expires > current_tick) ;
79
77
mtimercmp. write ( next_expires) ; // schedule next interrupt at next_expires
80
78
unsafe { riscv:: register:: mie:: set_mtimer ( ) } ; // enable machine timer interrupts again if necessary
@@ -102,7 +100,7 @@ impl Delay {
102
100
#[ inline]
103
101
pub fn new ( freq : usize ) -> Self {
104
102
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 ( ) } ;
106
104
let ( mtime, mtimecmp) = ( mtimer. mtime , mtimer. mtimecmp_mhartid ( ) ) ;
107
105
Self {
108
106
hart_id,
@@ -275,7 +273,7 @@ impl<'a> Future for DelayAsync<'a> {
275
273
_riscv_peripheral_aclint_push_timer ( timer) . expect ( "timer queue is full" ) ;
276
274
} ;
277
275
// 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 ) ;
279
277
}
280
278
Poll :: Pending
281
279
} else {
0 commit comments