mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-22 15:23:23 +00:00
在riscv上实现异常处理,能够进入异常处理程序 (#564)
This commit is contained in:
@ -7,10 +7,13 @@ use crate::{
|
||||
smp::cpu::{ProcessorId, SmpCpuManager},
|
||||
};
|
||||
|
||||
/// 栈对齐
|
||||
pub(super) const STACK_ALIGN: usize = 16;
|
||||
|
||||
/// 获取当前cpu的id
|
||||
#[inline]
|
||||
pub fn current_cpu_id() -> ProcessorId {
|
||||
let ptr: *const LocalContext = riscv::register::sscratch::read() as *const LocalContext;
|
||||
let ptr: *const LocalContext = riscv::register::tp::read() as *const LocalContext;
|
||||
|
||||
if core::intrinsics::unlikely(ptr.is_null()) {
|
||||
return boot_params().read_irqsave().arch.boot_hartid;
|
||||
@ -34,16 +37,29 @@ pub(super) fn local_context() -> &'static PerCpuVar<LocalContext> {
|
||||
|
||||
/// Per cpu的上下文数据
|
||||
///
|
||||
/// 每个CPU的sscratch寄存器指向这个结构体
|
||||
/// 每个CPU的tp寄存器指向这个结构体
|
||||
///
|
||||
/// 注意:
|
||||
///
|
||||
/// - 从用户态进入内核态时,会从sscratch寄存器加载这个结构体的地址到tp寄存器,并把sscratch寄存器清零
|
||||
/// - 从内核态进入用户态时,会将tp寄存器的值保存到sscratch寄存器
|
||||
#[derive(Debug)]
|
||||
pub(super) struct LocalContext {
|
||||
/// 当前cpu的id
|
||||
current_cpu: ProcessorId,
|
||||
pub current_cpu: ProcessorId,
|
||||
// 当前进程的内核栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值)
|
||||
pub kernel_sp: usize,
|
||||
// 当前进程的用户栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值)
|
||||
pub user_sp: usize,
|
||||
}
|
||||
|
||||
impl LocalContext {
|
||||
fn new(cpu: ProcessorId) -> Self {
|
||||
Self { current_cpu: cpu }
|
||||
Self {
|
||||
current_cpu: cpu,
|
||||
kernel_sp: 0,
|
||||
user_sp: 0,
|
||||
}
|
||||
}
|
||||
pub fn current_cpu(&self) -> ProcessorId {
|
||||
self.current_cpu
|
||||
@ -53,16 +69,34 @@ impl LocalContext {
|
||||
self.current_cpu = cpu;
|
||||
}
|
||||
|
||||
pub fn kernel_sp(&self) -> usize {
|
||||
self.kernel_sp
|
||||
}
|
||||
|
||||
pub fn set_kernel_sp(&mut self, sp: usize) {
|
||||
self.kernel_sp = sp;
|
||||
}
|
||||
|
||||
pub fn user_sp(&self) -> usize {
|
||||
self.user_sp
|
||||
}
|
||||
|
||||
pub fn set_user_sp(&mut self, sp: usize) {
|
||||
self.user_sp = sp;
|
||||
}
|
||||
|
||||
fn sync_to_cpu(&self) {
|
||||
let ptr = self as *const Self as usize;
|
||||
riscv::register::sscratch::write(ptr);
|
||||
riscv::register::sscratch::write(0);
|
||||
|
||||
// 写入tp寄存器
|
||||
riscv::register::tp::write(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化本地上下文
|
||||
#[inline(never)]
|
||||
pub(super) fn init_local_context() {
|
||||
kdebug!("init_local_context");
|
||||
let mut data = Vec::new();
|
||||
|
||||
for i in 0..PerCpu::MAX_CPU_NUM {
|
||||
|
Reference in New Issue
Block a user