Skip to content

Commit 90b5c52

Browse files
committed
feat(riscv): Add an extended setting function for the sstatus register;
And, before entering the user program space, refresh all instruction caches to resolve user program errors that occur on xuantie-c9xx platform; Add feature of T-Head CPU xuantie-c9xx;
1 parent 02ee47a commit 90b5c52

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ fp-simd = []
2828
tls = []
2929
uspace = []
3030
arm-el2 = []
31+
xuantie-c9xx = ["page_table_entry/xuantie-c9xx"]
3132

3233
[dependencies]
3334
linkme = "0.3"

src/riscv/uspace.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ impl UspaceContext {
2626
{
2727
sstatus.set_fs(FS::Initial); // set the FPU to initial state
2828
}
29+
#[cfg(feature = "xuantie-c9xx")]
30+
// enable vector status bits of sstatus
31+
Self::set_sstatus(&mut sstatus, 0x3 << 23, false);
2932

3033
Self(TrapFrame {
3134
regs: GeneralRegisters {
@@ -53,6 +56,24 @@ impl UspaceContext {
5356
self.0.regs.sp
5457
}
5558

59+
/// Sets the sstatus register.
60+
/// Due to the restriction of Sstatus struct, some bits of the sstatus register cannot be effectively set,
61+
/// So this function can effectively set the required bits of sstatus.
62+
pub fn set_sstatus(sstatus: &mut Sstatus, bits: usize, is_clear: bool) {
63+
if bits == 0 {
64+
error!("Invalid parameter: {:x}", bits);
65+
return;
66+
}
67+
unsafe {
68+
let sstatus_ptr = sstatus as *mut Sstatus as *mut usize;
69+
if is_clear {
70+
*sstatus_ptr &= !bits;
71+
} else {
72+
*sstatus_ptr |= bits;
73+
}
74+
}
75+
}
76+
5677
/// Sets the instruction pointer.
5778
pub const fn set_ip(&mut self, pc: usize) {
5879
self.0.sepc = pc;
@@ -79,8 +100,12 @@ impl UspaceContext {
79100
///
80101
/// This function is unsafe because it changes processor mode and the stack.
81102
pub unsafe fn enter_uspace(&self, kstack_top: VirtAddr) -> ! {
103+
use riscv::asm::fence_i;
82104
use riscv::register::{sepc, sscratch};
83105

106+
// Refresh all instruction caches before entering the user program space to resolve user program errors
107+
fence_i();
108+
84109
crate::asm::disable_irqs();
85110
// Address of the top of the kernel stack after saving the trap frame.
86111
let kernel_trap_addr = kstack_top.as_usize() - core::mem::size_of::<TrapFrame>();

0 commit comments

Comments
 (0)