Skip to content

Commit 3875ed5

Browse files
committed
mecall backend now deals with the nested interrupt issues
1 parent 31aac9f commit 3875ed5

File tree

5 files changed

+14
-25
lines changed

5 files changed

+14
-25
lines changed

riscv-slic-macros/src/export/mecall.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ pub fn export_quote(_input: &CodegenInput) -> TokenStream {
2727
#[inline]
2828
#[no_mangle]
2929
pub unsafe fn __riscv_slic_swi_pend() {
30-
riscv::asm::ecall();
30+
let mepc = riscv_slic::riscv::register::mepc::read();
31+
riscv_slic::riscv::asm::ecall();
32+
riscv_slic::riscv::register::mepc::write(mepc);
3133
}
3234

3335
/// Increments the machine exception program counter by 4
@@ -38,8 +40,8 @@ pub fn export_quote(_input: &CodegenInput) -> TokenStream {
3840
#[inline]
3941
#[no_mangle]
4042
pub unsafe fn __riscv_slic_swi_unpend() {
41-
let mepc = riscv::register::mepc::read();
42-
riscv::register::mepc::write(mepc + 4);
43+
let mepc = riscv_slic::riscv::register::mepc::read();
44+
riscv_slic::riscv::register::mepc::write(mepc + 4);
4345
}
4446
}
4547
}

riscv-slic-macros/src/export/ssoft.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub fn export_quote(_input: &CodegenInput) -> TokenStream {
2727
#[inline]
2828
#[no_mangle]
2929
pub unsafe fn __riscv_slic_swi_pend() {
30-
riscv::register::sip::set_ssoft();
30+
riscv_slic::riscv::register::sip::set_ssoft();
3131
}
3232

3333
/// Clears the Supervisor Software Interrupt Pending bit in the `SIP` register.
@@ -38,7 +38,7 @@ pub fn export_quote(_input: &CodegenInput) -> TokenStream {
3838
#[inline]
3939
#[no_mangle]
4040
pub unsafe fn __riscv_slic_swi_unpend() {
41-
riscv::register::sip::clear_ssoft();
41+
riscv_slic::riscv::register::sip::clear_ssoft();
4242
}
4343
}
4444
}

riscv-slic-macros/src/swi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub fn swi_mod(input: &CodegenInput) -> TokenStream {
7878
];
7979

8080
/// The static SLIC instance
81-
static mut __SLIC: MutexSLIC<#n_interrupts> = new_slic();
81+
static mut __SLIC: riscv_slic::MutexSLIC<#n_interrupts> = riscv_slic::new_slic();
8282

8383
/// Software interrupt handler to be used with the SLIC.
8484
#swi_handler_attribute

riscv-slic/src/api.rs

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ extern "Rust" {
2020
///
2121
/// # Note
2222
///
23-
/// This function does **NOT** modify the [`riscv::register::mstatus`] register.
23+
/// This function does **NOT** modify the [`mstatus`](`riscv::register::mstatus`) register.
2424
/// If you want to disable **ANY** other interrupt source, you must **ALSO** use the [`disable`] function.
2525
#[inline]
2626
pub fn clear_interrupts() {
@@ -38,7 +38,7 @@ pub fn clear_interrupts() {
3838
///
3939
/// # Note
4040
///
41-
/// This function does not modify the [`riscv::register::mstatus`] register.
41+
/// This function does not modify the [`mstatus`](`riscv::register::mstatus`) register.
4242
/// If you want to enable **ANY** other interrupt source, you must **ALSO** use the [`enable`] function.
4343
///
4444
/// # Safety
@@ -62,9 +62,7 @@ pub fn get_threshold() -> u8 {
6262
///
6363
/// # Safety
6464
///
65-
/// Setting the priority threshold to a value lower than the current threshold
66-
/// may lead to priority inversion. If you want to make sure that the threshold
67-
/// is only raised, use the [`raise_threshold`] function instead.
65+
/// Setting the priority threshold to a value lower than the current may lead to priority inversion.
6866
#[inline]
6967
pub unsafe fn set_threshold(priority: u8) {
7068
__riscv_slic_set_threshold(priority);
@@ -81,20 +79,6 @@ pub unsafe fn set_priority<I: crate::InterruptNumber>(interrupt: I, priority: u8
8179
}
8280

8381
/// Stabilized API for pending a software interrupt on the SLIC.
84-
///
85-
/// # Note
86-
///
87-
/// When working with the `mecall-backend` feature, special care must be taken
88-
/// when using this function **inside** an interrupt handler. This is because
89-
/// this backend uses the `ecall` instruction to trigger software interrupts.
90-
/// If you call this function inside an interrupt handler, the `mepc` register
91-
/// will be incremented by 4, leading to unexpected behavior.
92-
/// To avoid this, make sure that:
93-
///
94-
/// - You only call this function **outside** of interrupt handlers.
95-
/// - If you need to trigger a software interrupt inside an interrupt handler,
96-
/// do it inside a [`nested`] block. This will ensure that the
97-
/// `mepc` register is not incremented incorrectly.
9882
#[inline]
9983
pub fn pend<I: crate::InterruptNumber>(interrupt: I) {
10084
// SAFETY: it is safe to pend a software interrupt

riscv-slic/src/slic.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ use core::cell::RefCell;
22
use critical_section::Mutex;
33
use heapless::binary_heap::{BinaryHeap, Max};
44

5+
#[doc(hidden)]
56
pub type MutexSLIC<const N: usize> = Mutex<RefCell<SLIC<N>>>;
67

8+
#[doc(hidden)]
9+
#[inline]
710
pub const fn new_slic<const N: usize>() -> MutexSLIC<N> {
811
Mutex::new(RefCell::new(SLIC::new()))
912
}

0 commit comments

Comments
 (0)