Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ fp-simd = []
tls = []
uspace = []
arm-el2 = []
xuantie-c9xx = ["page_table_entry/xuantie-c9xx"]

[dependencies]
linkme = "0.3"
Expand Down
25 changes: 25 additions & 0 deletions src/riscv/uspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ impl UspaceContext {
{
sstatus.set_fs(FS::Initial); // set the FPU to initial state
}
#[cfg(feature = "xuantie-c9xx")]
// enable vector status bits of sstatus
Self::set_sstatus(&mut sstatus, 0x3 << 23, false);

Self(TrapFrame {
regs: GeneralRegisters {
Expand Down Expand Up @@ -53,6 +56,24 @@ impl UspaceContext {
self.0.regs.sp
}

/// Sets the sstatus register.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this fn be xuantie-specific?

/// Due to the restriction of Sstatus struct, some bits of the sstatus register cannot be effectively set,
/// So this function can effectively set the required bits of sstatus.
pub fn set_sstatus(sstatus: &mut Sstatus, bits: usize, is_clear: bool) {
if bits == 0 {
error!("Invalid parameter: {:x}", bits);
return;
}
unsafe {
let sstatus_ptr = sstatus as *mut Sstatus as *mut usize;
if is_clear {
*sstatus_ptr &= !bits;
} else {
*sstatus_ptr |= bits;
}
}
}

/// Sets the instruction pointer.
pub const fn set_ip(&mut self, pc: usize) {
self.0.sepc = pc;
Expand All @@ -79,8 +100,12 @@ impl UspaceContext {
///
/// This function is unsafe because it changes processor mode and the stack.
pub unsafe fn enter_uspace(&self, kstack_top: VirtAddr) -> ! {
use riscv::asm::fence_i;
use riscv::register::{sepc, sscratch};

// Refresh all instruction caches before entering the user program space to resolve user program errors
fence_i();

crate::asm::disable_irqs();
// Address of the top of the kernel stack after saving the trap frame.
let kernel_trap_addr = kstack_top.as_usize() - core::mem::size_of::<TrapFrame>();
Expand Down
Loading