Skip to content

Commit e8d7db6

Browse files
committed
cleanup
1 parent 3ee4acd commit e8d7db6

File tree

3 files changed

+88
-112
lines changed

3 files changed

+88
-112
lines changed

rustsbi-qemu/src/execute/mod.rs renamed to rustsbi-qemu/src/execute.rs

Lines changed: 88 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,11 @@ use crate::{
33
qemu_hsm::{QemuHsm, SUSPEND_NON_RETENTIVE},
44
Supervisor,
55
};
6-
7-
mod context;
8-
mod transfer_trap;
9-
10-
use context::Context;
6+
use riscv::register::{mstatus, mtval, scause, sepc, stval, stvec};
117

128
pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
139
use core::arch::asm;
14-
use riscv::register::{medeleg, mie, mstatus};
10+
use riscv::register::{medeleg, mie};
1511

1612
unsafe {
1713
mstatus::set_mpp(mstatus::MPP::Supervisor);
@@ -73,15 +69,16 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
7369
ctx.mepc = ctx.mepc.wrapping_add(4);
7470
}
7571
T::Exception(E::IllegalInstruction) => {
76-
use riscv::register::scause;
72+
use riscv::register::scause::{Exception as E, Trap as T};
7773

74+
// let instruction = mtval::read();
75+
// 尝试修正或代理指令
76+
// TODO 需要排查 qemu 哪些版本需要代理哪些指令?
77+
// TODO 标准 20191213 的表 24.3 列出了一些特殊的 CSR,SBI 软件负责将它们模拟出来,但 Qemu6.0+ 似乎不需要模拟 time
7878
// const OPCODE_MASK: usize = (1 << 7) - 1;
7979
// const REG_MASK: usize = (1 << 5) - 1;
8080
// const OPCODE_CSR: usize = 0b1110011;
8181
// const CSR_TIME: usize = 0xc01;
82-
// let instruction = mtval::read();
83-
// 标准 20191213 的表 24.3 列出了一些特殊的 CSR,SBI 软件负责将它们模拟出来
84-
// Qemu 似乎不需要模拟 time
8582
// if let OPCODE_CSR = instruction & OPCODE_MASK {
8683
// if instruction >> 20 == CSR_TIME {
8784
// match (instruction >> 7) & REG_MASK {
@@ -91,26 +88,90 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
9188
// continue;
9289
// }
9390
// }
94-
// 如果不是可修正的指令,且不是 M 态本身发出的,转交给 S 态处理
95-
// mpp != machine
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;
104-
}
105-
}
106-
t => {
107-
println!("{t:?}");
108-
break;
91+
92+
ctx.do_transfer_trap(T::Exception(E::IllegalInstruction));
10993
}
94+
// TODO 可以修复非原子的非对称访存
95+
t => panic!("unsupported trap: {t:?}"),
11096
}
11197
}
112-
loop {
113-
core::hint::spin_loop();
98+
}
99+
100+
#[repr(C)]
101+
#[derive(Debug)]
102+
struct Context {
103+
msp: usize,
104+
x: [usize; 31],
105+
mstatus: usize,
106+
mepc: usize,
107+
}
108+
109+
impl Context {
110+
fn new(supervisor: Supervisor) -> Self {
111+
let mut ctx = Self {
112+
msp: 0,
113+
x: [0; 31],
114+
mstatus: 0,
115+
mepc: supervisor.start_addr,
116+
};
117+
118+
unsafe { core::arch::asm!("csrr {}, mstatus", out(reg) ctx.mstatus) };
119+
*ctx.a_mut(0) = hart_id();
120+
*ctx.a_mut(1) = supervisor.opaque;
121+
122+
ctx
123+
}
124+
125+
#[inline]
126+
fn x(&self, n: usize) -> usize {
127+
self.x[n - 1]
128+
}
129+
130+
#[inline]
131+
fn x_mut(&mut self, n: usize) -> &mut usize {
132+
&mut self.x[n - 1]
133+
}
134+
135+
#[inline]
136+
fn a(&self, n: usize) -> usize {
137+
self.x(n + 10)
138+
}
139+
140+
#[inline]
141+
fn a_mut(&mut self, n: usize) -> &mut usize {
142+
self.x_mut(n + 10)
143+
}
144+
145+
pub(super) fn do_transfer_trap(&mut self, cause: scause::Trap) {
146+
unsafe {
147+
// 向 S 转发陷入
148+
mstatus::set_mpp(mstatus::MPP::Supervisor);
149+
// 转发陷入源状态
150+
let spp = match (self.mstatus >> 11) & 0b11 {
151+
// U
152+
0b00 => mstatus::SPP::User,
153+
// S
154+
0b01 => mstatus::SPP::Supervisor,
155+
// H/M
156+
mpp => unreachable!("invalid mpp: {mpp:#x} to delegate"),
157+
};
158+
mstatus::set_spp(spp);
159+
// 转发陷入原因
160+
scause::set(cause);
161+
// 转发陷入附加信息
162+
stval::write(mtval::read());
163+
// 转发陷入地址
164+
sepc::write(self.mepc);
165+
// 设置 S 中断状态
166+
if mstatus::read().sie() {
167+
mstatus::set_spie();
168+
mstatus::clear_sie();
169+
}
170+
core::arch::asm!("csrr {}, mstatus", out(reg) self.mstatus);
171+
// 设置返回地址,返回到 S
172+
// TODO Vectored stvec?
173+
self.mepc = stvec::read().address();
174+
}
114175
}
115176
}
116177

rustsbi-qemu/src/execute/context.rs

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

rustsbi-qemu/src/execute/transfer_trap.rs

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

0 commit comments

Comments
 (0)