Skip to content

Commit f2133fd

Browse files
committed
feat(sbi): 重写上下文切换
1 parent a008b8b commit f2133fd

File tree

4 files changed

+33
-24
lines changed

4 files changed

+33
-24
lines changed

rustsbi-qemu/src/execute/mod.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{clint, hart_id, Supervisor};
22

33
#[repr(C)]
4-
#[derive(Default)]
4+
#[derive(Debug)]
55
struct Context {
66
msp: usize,
77
x: [usize; 31],
@@ -11,7 +11,7 @@ struct Context {
1111

1212
pub(crate) fn execute_supervisor(supervisor: Supervisor) {
1313
use core::arch::asm;
14-
use riscv::register::{medeleg, mie, mstatus};
14+
use riscv::register::{medeleg, mie, mip, mstatus};
1515

1616
unsafe {
1717
mstatus::set_mpp(mstatus::MPP::Supervisor);
@@ -46,7 +46,7 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
4646

4747
loop {
4848
use crate::qemu_hsm::{EID_HSM, FID_HART_STOP, FID_HART_SUSPEND, SUSPEND_NON_RETENTIVE};
49-
use riscv::register::mcause::{self, Exception as E, Trap as T};
49+
use riscv::register::mcause::{self, Exception as E, Interrupt as I, Trap as T};
5050

5151
unsafe { m_to_s(&mut ctx) };
5252

@@ -66,14 +66,23 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
6666
*ctx.a_mut(1) = ans.value;
6767
ctx.mepc = ctx.mepc.wrapping_add(4);
6868
}
69+
T::Interrupt(I::MachineTimer) => unsafe {
70+
mip::clear_mtimer();
71+
mip::set_stimer();
72+
},
73+
T::Exception(E::IllegalInstruction) => {
74+
println!("TODO emulate or forward illegal instruction");
75+
break;
76+
}
6977
t => {
7078
println!("{t:?}");
71-
loop {
72-
core::hint::spin_loop();
73-
}
79+
break;
7480
}
7581
}
7682
}
83+
loop {
84+
core::hint::spin_loop();
85+
}
7786
}
7887

7988
impl Context {

rustsbi-qemu/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
170170
}
171171
}
172172

173-
/// 准备好深度休眠或关闭
173+
/// 准备好不可恢复休眠或关闭
174174
extern "C" fn finalize() {
175175
//! 在隔离的环境调用,以确保 main 中使用的堆资源完全释放
176176
HSM.wait().finallize_before_stop();

rustsbi-qemu/src/qemu_hsm.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -99,30 +99,30 @@ impl QemuHsm {
9999
/// 此时核状态必然是不可干预的 Pending 状态,中断业已关闭。
100100
pub fn finallize_before_stop(&self) {
101101
use core::sync::atomic::Ordering::{AcqRel, Acquire};
102-
use riscv::register::{mie, mip};
102+
use riscv::register::mie;
103103

104104
// 检查当前状态是重启前的挂起状态
105105
let state = &self.state[hart_id()];
106106
let current = state.load(Acquire);
107107
let new: u8 = match current {
108-
STOP_PENDING => STOPPED,
109-
SUSPEND_PENDING => SUSPEND,
108+
STOP_PENDING => {
109+
// 一旦关闭,只能通过软件中断重启
110+
unsafe { mie::clear_mext() };
111+
STOPPED
112+
}
113+
SUSPEND_PENDING => {
114+
// 休眠也可以通过外部中断唤醒
115+
unsafe { mie::set_mext() };
116+
SUSPEND
117+
}
110118
s => panic!("wrong state {s:?}!"),
111119
};
112-
113-
// TODO: SBI 在 M 态应该总是处于这样干净的状态,即:
114-
// 1. 所有中断标记清除
115-
// 2. 所有中断已关闭
116-
//
117-
// 这样,发生状态转换时只需要:
118-
// 1. 重设 mtvec
119-
// 2. 开启需要的中断
120-
self.clint.clear_soft(hart_id());
120+
// 通过软件中断重启
121121
unsafe {
122-
mip::clear_msoft();
123122
mie::set_msoft();
124-
set_mtcev(entry as _);
125-
}
123+
set_mtcev(entry as _)
124+
};
125+
// 转移状态
126126
if let Err(unexpected) = state.compare_exchange(current, new, AcqRel, Acquire) {
127127
panic!("failed to reboot for a race {current:?} => {unexpected:?}")
128128
}

test-kernel/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ extern "C" fn primary_rust_main(hartid: usize, dtb_pa: usize) -> ! {
109109
test::base_extension();
110110
test::sbi_ins_emulation();
111111

112-
unsafe { stvec::write(start_trap as usize, TrapMode::Direct) };
113-
test::trap_delegate(hartid);
112+
// unsafe { stvec::write(start_trap as usize, TrapMode::Direct) };
113+
// test::trap_delegate(hartid);
114114

115115
println!();
116116
STARTED.fetch_add(1, Ordering::SeqCst);

0 commit comments

Comments
 (0)