From 814807298494ab94de3bd54faec3dda061b2acf6 Mon Sep 17 00:00:00 2001 From: Zhang Junyang Date: Mon, 1 Sep 2025 22:16:23 +0800 Subject: [PATCH] Upgrade the `riscv` crate to fix the ssoft handling https://github.com/rust-embedded/riscv/commit/3c618636307fb5c9cd8db6c58cf4207e5742b35e --- Cargo.lock | 24 +++++++++++++++-- kernel/Cargo.toml | 2 +- ostd/Cargo.toml | 2 +- ostd/src/arch/riscv/cpu/context.rs | 29 ++++++++++++++------- ostd/src/arch/riscv/mm/mod.rs | 4 +-- ostd/src/arch/riscv/trap/mod.rs | 42 +++++++++++------------------- 6 files changed, 59 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b2c2ba04..abf34a421 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1535,14 +1535,34 @@ dependencies = [ [[package]] name = "riscv" -version = "0.11.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9" +checksum = "b05cfa3f7b30c84536a9025150d44d26b8e1cc20ddf436448d74cd9591eefb25" dependencies = [ "critical-section", "embedded-hal", + "paste", + "riscv-macros", + "riscv-pac", ] +[[package]] +name = "riscv-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d323d13972c1b104aa036bc692cd08b822c8bbf23d79a27c526095856499799" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "riscv-pac" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8188909339ccc0c68cfb5a04648313f09621e8b87dc03095454f1a11f6c5d436" + [[package]] name = "rle-decode-fast" version = "1.0.3" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index d0a427e3c..3e17827d6 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -69,7 +69,7 @@ cfg-if = "1.0" tdx-guest = { version = "0.2.1", optional = true } [target.riscv64imac-unknown-none-elf.dependencies] -riscv = { version = "0.11.1", features = ["s-mode"] } +riscv = { version = "0.15.0", features = ["s-mode"] } [target.loongarch64-unknown-none-softfloat.dependencies] loongArch64 = "0.2.5" diff --git a/ostd/Cargo.toml b/ostd/Cargo.toml index 07bfdb27d..f58354416 100644 --- a/ostd/Cargo.toml +++ b/ostd/Cargo.toml @@ -61,7 +61,7 @@ tdx-guest = { version = "0.2.1", optional = true } unwinding = { version = "=0.2.5", default-features = false, features = ["fde-gnu-eh-frame-hdr", "hide-trace", "panic", "personality", "unwinder"] } [target.riscv64imac-unknown-none-elf.dependencies] -riscv = { version = "0.11.1", features = ["s-mode"] } +riscv = { version = "0.15.0", features = ["s-mode"] } sbi-rt = "0.0.3" fdt = { version = "0.1.5", features = ["pretty-printing"] } unwinding = { version = "=0.2.5", default-features = false, features = ["fde-static", "hide-trace", "panic", "personality", "unwinder"] } diff --git a/ostd/src/arch/riscv/cpu/context.rs b/ostd/src/arch/riscv/cpu/context.rs index c535a3f56..69e0a44a4 100644 --- a/ostd/src/arch/riscv/cpu/context.rs +++ b/ostd/src/arch/riscv/cpu/context.rs @@ -6,12 +6,15 @@ use alloc::boxed::Box; use core::{arch::global_asm, fmt::Debug}; use ostd_pod::Pod; -use riscv::register::scause::{Exception, Trap}; +use riscv::{ + interrupt::supervisor::{Exception, Interrupt}, + register::scause::Trap, +}; use crate::{ arch::{ cpu::extension::{has_extensions, IsaExtensions}, - trap::{call_irq_callback_functions_by_scause, RawUserContext, TrapFrame, SSTATUS_FS_MASK}, + trap::{handle_irq, RawUserContext, TrapFrame, SSTATUS_FS_MASK}, }, cpu::PrivilegeLevel, user::{ReturnReason, UserContextApi, UserContextApiInternal}, @@ -125,7 +128,6 @@ impl CpuException { InstructionPageFault => Self::InstructionPageFault(stval), LoadPageFault => Self::LoadPageFault(stval), StorePageFault => Self::StorePageFault(stval), - Unknown => Self::Unknown, } } } @@ -186,14 +188,21 @@ impl UserContextApiInternal for UserContext { self.user_context.run(); let scause = riscv::register::scause::read(); - match scause.cause() { + let Ok(cause) = Trap::::try_from(scause.cause()) else { + match scause.cause() { + Trap::Interrupt(i) => { + panic!("Unknown interrupt in user mode: {:?}", i); + } + Trap::Exception(e) => { + log::info!("Unknown exception in user mode: {:?}", e); + self.exception = Some(CpuException::Unknown); + break ReturnReason::UserException; + } + } + }; + match cause { Trap::Interrupt(interrupt) => { - call_irq_callback_functions_by_scause( - &self.as_trap_frame(), - scause.bits(), - interrupt, - PrivilegeLevel::User, - ); + handle_irq(&self.as_trap_frame(), interrupt, PrivilegeLevel::User); crate::arch::irq::enable_local(); } Trap::Exception(Exception::UserEnvCall) => { diff --git a/ostd/src/arch/riscv/mm/mod.rs b/ostd/src/arch/riscv/mm/mod.rs index 0ee96993d..8aabb3ec7 100644 --- a/ostd/src/arch/riscv/mm/mod.rs +++ b/ostd/src/arch/riscv/mm/mod.rs @@ -84,9 +84,7 @@ bitflags::bitflags! { } pub(crate) fn tlb_flush_addr(vaddr: Vaddr) { - unsafe { - riscv::asm::sfence_vma(0, vaddr); - } + riscv::asm::sfence_vma(0, vaddr); } pub(crate) fn tlb_flush_addr_range(range: &Range) { diff --git a/ostd/src/arch/riscv/trap/mod.rs b/ostd/src/arch/riscv/trap/mod.rs index e5d8233fa..cc6428509 100644 --- a/ostd/src/arch/riscv/trap/mod.rs +++ b/ostd/src/arch/riscv/trap/mod.rs @@ -7,7 +7,10 @@ mod trap; use core::sync::atomic::Ordering; -use riscv::register::scause::{Interrupt, Trap}; +use riscv::{ + interrupt::supervisor::{Exception, Interrupt}, + register::scause::Trap, +}; use spin::Once; pub use trap::TrapFrame; pub(super) use trap::{RawUserContext, SSTATUS_FS_MASK, SSTATUS_SUM}; @@ -54,14 +57,17 @@ extern "C" fn trap_handler(f: &mut TrapFrame) { } let scause = riscv::register::scause::read(); - let exception = match scause.cause() { + let Ok(cause) = Trap::::try_from(scause.cause()) else { + panic!( + "Cannot handle unknown trap, scause: {:#x}, trapframe: {:#x?}.", + scause.bits(), + f + ); + }; + + let exception = match cause { Trap::Interrupt(interrupt) => { - call_irq_callback_functions_by_scause( - f, - scause.bits(), - interrupt, - PrivilegeLevel::Kernel, - ); + handle_irq(f, interrupt, PrivilegeLevel::Kernel); return; } Trap::Exception(raw_exception) => { @@ -86,13 +92,6 @@ extern "C" fn trap_handler(f: &mut TrapFrame) { panic!("Cannot handle page fault in kernel space, exception: {:#x?}, trapframe: {:#x?}.", exception, f); } } - CpuException::Unknown => { - panic!( - "Cannot handle unknown exception, scause: {:#x}, trapframe: {:#x?}.", - scause.bits(), - f - ); - } _ => { panic!( "Cannot handle kernel exception, exception: {:#x?}, trapframe: {:#x?}.", @@ -103,12 +102,7 @@ extern "C" fn trap_handler(f: &mut TrapFrame) { disable_local_if(was_irq_enabled); } -pub(super) fn call_irq_callback_functions_by_scause( - trap_frame: &TrapFrame, - scause: usize, - interrupt: Interrupt, - priv_level: PrivilegeLevel, -) { +pub(super) fn handle_irq(trap_frame: &TrapFrame, interrupt: Interrupt, priv_level: PrivilegeLevel) { match interrupt { Interrupt::SupervisorTimer => { call_irq_callback_functions( @@ -135,12 +129,6 @@ pub(super) fn call_irq_callback_functions_by_scause( priv_level, ); } - Interrupt::Unknown => { - panic!( - "Cannot handle unknown supervisor interrupt, scause: {:#x}, trapframe: {:#x?}.", - scause, trap_frame - ); - } } }