Skip to content

Commit 4f7c6a8

Browse files
committed
feat(sbi): 恢复软中断处理
1 parent ff79ee0 commit 4f7c6a8

File tree

6 files changed

+108
-127
lines changed

6 files changed

+108
-127
lines changed

rustsbi-qemu/src/execute/context.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use crate::{hart_id, Supervisor};
2+
3+
#[repr(C)]
4+
#[derive(Debug)]
5+
pub(super) struct Context {
6+
msp: usize,
7+
x: [usize; 31],
8+
pub mstatus: usize,
9+
pub mepc: usize,
10+
}
11+
12+
impl Context {
13+
pub fn new(supervisor: Supervisor) -> Self {
14+
let mut ctx = Context {
15+
msp: 0,
16+
x: [0; 31],
17+
mstatus: 0,
18+
mepc: supervisor.start_addr,
19+
};
20+
21+
unsafe { core::arch::asm!("csrr {}, mstatus", out(reg) ctx.mstatus) };
22+
*ctx.a_mut(0) = hart_id();
23+
*ctx.a_mut(1) = supervisor.opaque;
24+
25+
ctx
26+
}
27+
28+
#[inline]
29+
pub fn a(&self, n: usize) -> usize {
30+
self.x[n + 9]
31+
}
32+
33+
#[inline]
34+
pub fn a_mut(&mut self, n: usize) -> &mut usize {
35+
&mut self.x[n + 9]
36+
}
37+
38+
// #[inline]
39+
// pub fn x(&self, n: usize) -> usize {
40+
// self.x[n - 1]
41+
// }
42+
43+
#[inline]
44+
pub fn x_mut(&mut self, n: usize) -> &mut usize {
45+
&mut self.x[n - 1]
46+
}
47+
}

rustsbi-qemu/src/execute/feature/emulate_rdtime.rs

Lines changed: 0 additions & 25 deletions
This file was deleted.

rustsbi-qemu/src/execute/feature/mod.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.

rustsbi-qemu/src/execute/feature/transfer_trap.rs

Lines changed: 0 additions & 31 deletions
This file was deleted.

rustsbi-qemu/src/execute/mod.rs

Lines changed: 33 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,9 @@
11
use crate::{clint, hart_id, Supervisor};
22

3-
#[repr(C)]
4-
#[derive(Debug)]
5-
struct Context {
6-
msp: usize,
7-
x: [usize; 31],
8-
mstatus: usize,
9-
mepc: usize,
10-
}
11-
12-
impl Context {
13-
#[inline]
14-
fn a(&self, n: usize) -> usize {
15-
self.x[n + 9]
16-
}
3+
mod context;
4+
mod transfer_trap;
175

18-
#[inline]
19-
fn a_mut(&mut self, n: usize) -> &mut usize {
20-
&mut self.x[n + 9]
21-
}
22-
23-
#[inline]
24-
fn x(&self, n: usize) -> usize {
25-
self.x[n - 1]
26-
}
27-
28-
#[inline]
29-
fn x_mut(&mut self, n: usize) -> &mut usize {
30-
&mut self.x[n - 1]
31-
}
32-
}
6+
use context::Context;
337

348
pub(crate) fn execute_supervisor(supervisor: Supervisor) {
359
use core::arch::asm;
@@ -40,19 +14,10 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
4014
mstatus::set_mie();
4115
};
4216

43-
let mut ctx = Context {
44-
msp: 0,
45-
x: [0; 31],
46-
mstatus: 0,
47-
mepc: supervisor.start_addr,
48-
};
49-
50-
*ctx.a_mut(0) = hart_id();
51-
*ctx.a_mut(1) = supervisor.opaque;
17+
let mut ctx = Context::new(supervisor);
5218

5319
clint::get().clear_soft(hart_id());
5420
unsafe {
55-
asm!("csrr {}, mstatus", out(reg) ctx.mstatus);
5621
asm!("csrw mip, {}", in(reg) 0);
5722
asm!("csrw mideleg, {}", in(reg) usize::MAX);
5823
asm!("csrw medeleg, {}", in(reg) usize::MAX);
@@ -73,6 +38,26 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
7338
unsafe { m_to_s(&mut ctx) };
7439

7540
match mcause::read().cause() {
41+
T::Interrupt(I::MachineTimer) => unsafe {
42+
use riscv::register::mip;
43+
mip::clear_mtimer();
44+
mip::set_stimer();
45+
},
46+
T::Interrupt(I::MachineSoft) => {
47+
use riscv::register::{mip, scause};
48+
49+
crate::clint::get().clear_soft(hart_id());
50+
unsafe { mip::clear_msoft() };
51+
if transfer_trap::should_transfer_trap(&ctx) {
52+
transfer_trap::do_transfer_trap(
53+
&mut ctx,
54+
scause::Trap::Interrupt(scause::Interrupt::SupervisorSoft),
55+
);
56+
} else {
57+
println!("{:?}", I::MachineSoft);
58+
break;
59+
}
60+
}
7661
T::Exception(E::SupervisorEnvCall) => {
7762
let param = [ctx.a(0), ctx.a(1), ctx.a(2), ctx.a(3), ctx.a(4), ctx.a(5)];
7863
let ans = rustsbi::ecall(ctx.a(7), ctx.a(6), param);
@@ -88,13 +73,8 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
8873
*ctx.a_mut(1) = ans.value;
8974
ctx.mepc = ctx.mepc.wrapping_add(4);
9075
}
91-
T::Interrupt(I::MachineTimer) => unsafe {
92-
use riscv::register::mip;
93-
mip::clear_mtimer();
94-
mip::set_stimer();
95-
},
9676
T::Exception(E::IllegalInstruction) => {
97-
use riscv::register::mtval;
77+
use riscv::register::{mtval, scause};
9878

9979
const OPCODE_MASK: usize = (1 << 7) - 1;
10080
const REG_MASK: usize = (1 << 5) - 1;
@@ -113,28 +93,15 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
11393
}
11494
// 如果不是可修正的指令,且不是 M 态本身发出的,转交给 S 态处理
11595
// mpp != machine
116-
if (ctx.mstatus >> 11) & 0b11 != 0b11 {
117-
use riscv::register::{
118-
scause::{self, Exception, Trap},
119-
sepc, stval, stvec,
120-
};
121-
unsafe {
122-
scause::set(Trap::Exception(Exception::IllegalInstruction));
123-
stval::write(instruction);
124-
sepc::write(ctx.mepc);
125-
mstatus::set_mpp(mstatus::MPP::Supervisor);
126-
mstatus::set_spp(mstatus::SPP::Supervisor);
127-
if mstatus::read().sie() {
128-
mstatus::set_spie()
129-
}
130-
mstatus::clear_sie();
131-
core::arch::asm!("csrr {}, mstatus", out(reg) ctx.mstatus);
132-
ctx.mepc = stvec::read().address();
133-
}
134-
continue;
96+
if transfer_trap::should_transfer_trap(&ctx) {
97+
transfer_trap::do_transfer_trap(
98+
&mut ctx,
99+
scause::Trap::Exception(scause::Exception::IllegalInstruction),
100+
);
101+
} else {
102+
println!("{:?}", I::MachineSoft);
103+
break;
135104
}
136-
println!("{:?}", E::IllegalInstruction);
137-
break;
138105
}
139106
t => {
140107
println!("{t:?}");
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use super::Context;
2+
use riscv::register::{mstatus, mtval, scause, sepc, stval, stvec};
3+
4+
pub(super) fn should_transfer_trap(ctx: &Context) -> bool {
5+
(ctx.mstatus >> 11) & 0b11 != 0b11
6+
}
7+
8+
pub(super) fn do_transfer_trap(ctx: &mut Context, cause: scause::Trap) {
9+
unsafe {
10+
// 填写陷入原因
11+
scause::set(cause);
12+
// 填写陷入附加信息
13+
stval::write(mtval::read());
14+
// 填写 S 态层需要返回到的地址
15+
sepc::write(ctx.mepc);
16+
// 设置中断位
17+
mstatus::set_mpp(mstatus::MPP::Supervisor);
18+
mstatus::set_spp(mstatus::SPP::Supervisor);
19+
if mstatus::read().sie() {
20+
mstatus::set_spie()
21+
}
22+
mstatus::clear_sie();
23+
core::arch::asm!("csrr {}, mstatus", out(reg) ctx.mstatus);
24+
// 设置返回地址,返回到S层
25+
// TODO Vectored stvec?
26+
ctx.mepc = stvec::read().address();
27+
}
28+
}

0 commit comments

Comments
 (0)