1
1
use crate :: { clint, hart_id, qemu_hsm:: QemuHsm , Supervisor } ;
2
- use riscv:: register:: { mstatus, mtval, scause, sepc, stval, stvec} ;
2
+ use core:: arch:: asm;
3
+ use riscv:: register:: * ;
3
4
4
5
#[ repr( usize ) ]
5
6
pub ( crate ) enum Operation {
@@ -8,9 +9,6 @@ pub(crate) enum Operation {
8
9
}
9
10
10
11
pub ( crate ) fn execute_supervisor ( hsm : & QemuHsm , supervisor : Supervisor ) -> Operation {
11
- use core:: arch:: asm;
12
- use riscv:: register:: { medeleg, mie} ;
13
-
14
12
unsafe {
15
13
mstatus:: set_mpp ( mstatus:: MPP :: Supervisor ) ;
16
14
mstatus:: set_mie ( ) ;
@@ -24,7 +22,6 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) -> Opera
24
22
asm ! ( "csrw mideleg, {}" , in( reg) usize :: MAX ) ;
25
23
asm ! ( "csrw medeleg, {}" , in( reg) usize :: MAX ) ;
26
24
mstatus:: clear_mie ( ) ;
27
- medeleg:: clear_illegal_instruction ( ) ;
28
25
medeleg:: clear_supervisor_env_call ( ) ;
29
26
medeleg:: clear_machine_env_call ( ) ;
30
27
@@ -35,56 +32,32 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) -> Opera
35
32
36
33
hsm. record_current_start_finished ( ) ;
37
34
loop {
38
- use riscv:: register:: {
39
- mcause:: { self , Exception as E , Interrupt as I , Trap as T } ,
40
- mip,
41
- } ;
35
+ use mcause:: { Exception as E , Interrupt as I , Trap as T } ;
42
36
43
37
unsafe { m_to_s ( & mut ctx) } ;
44
38
45
39
match mcause:: read ( ) . cause ( ) {
46
40
T :: Interrupt ( I :: MachineTimer ) => unsafe {
41
+ // set timer 同时打开中断,响应后即可关闭
47
42
mie:: clear_mtimer ( ) ;
43
+ // 转发给 supervisor
48
44
mip:: clear_mtimer ( ) ;
49
45
mip:: set_stimer ( ) ;
50
46
} ,
51
- T :: Interrupt ( I :: MachineSoft ) => {
47
+ T :: Interrupt ( I :: MachineSoft ) => unsafe {
48
+ // 响应中断,清除中断标记
52
49
crate :: clint:: get ( ) . clear_soft ( hart_id ( ) ) ;
53
- unsafe {
54
- mip:: clear_msoft ( ) ;
55
- mip:: set_ssoft ( ) ;
56
- }
57
- }
50
+ // 转发给 supervisor
51
+ mip:: clear_msoft ( ) ;
52
+ mip:: set_ssoft ( ) ;
53
+ } ,
58
54
T :: Exception ( E :: SupervisorEnvCall ) => {
59
55
if let Some ( op) = ctx. handle_ecall ( ) {
60
56
return op;
61
57
}
62
58
}
63
- T :: Exception ( E :: IllegalInstruction ) => {
64
- use riscv:: register:: scause:: { Exception as E , Trap as T } ;
65
-
66
- // let instruction = mtval::read();
67
- // 尝试修正或代理指令
68
- // TODO 需要排查 qemu 哪些版本需要代理哪些指令?
69
- // TODO 标准 20191213 的表 24.3 列出了一些特殊的 CSR,SBI 软件负责将它们模拟出来,但 Qemu6.0+ 似乎不需要模拟 time
70
- // const OPCODE_MASK: usize = (1 << 7) - 1;
71
- // const REG_MASK: usize = (1 << 5) - 1;
72
- // const OPCODE_CSR: usize = 0b1110011;
73
- // const CSR_TIME: usize = 0xc01;
74
- // if let OPCODE_CSR = instruction & OPCODE_MASK {
75
- // if instruction >> 20 == CSR_TIME {
76
- // match (instruction >> 7) & REG_MASK {
77
- // 0 => {}
78
- // rd => *ctx.x_mut(rd) = crate::clint::get().get_mtime() as _,
79
- // }
80
- // continue;
81
- // }
82
- // }
83
-
84
- ctx. do_transfer_trap ( T :: Exception ( E :: IllegalInstruction ) ) ;
85
- }
86
- // TODO 可以修复非原子的非对齐访存
87
- t => panic ! ( "unsupported trap: {t:?}" ) ,
59
+ // TODO 可以修复非原子的非对齐访存?
60
+ t => ctx. trap_stop ( t) ,
88
61
}
89
62
}
90
63
}
@@ -107,7 +80,7 @@ impl Context {
107
80
mepc : supervisor. start_addr ,
108
81
} ;
109
82
110
- unsafe { core :: arch :: asm!( "csrr {}, mstatus" , out( reg) ctx. mstatus) } ;
83
+ unsafe { asm ! ( "csrr {}, mstatus" , out( reg) ctx. mstatus) } ;
111
84
* ctx. a_mut ( 0 ) = hart_id ( ) ;
112
85
* ctx. a_mut ( 1 ) = supervisor. opaque ;
113
86
@@ -188,6 +161,7 @@ impl Context {
188
161
None
189
162
}
190
163
164
+ #[ allow( unused) ]
191
165
fn do_transfer_trap ( & mut self , cause : scause:: Trap ) {
192
166
unsafe {
193
167
// 向 S 转发陷入
@@ -213,12 +187,29 @@ impl Context {
213
187
mstatus:: set_spie ( ) ;
214
188
mstatus:: clear_sie ( ) ;
215
189
}
216
- core :: arch :: asm!( "csrr {}, mstatus" , out( reg) self . mstatus) ;
190
+ asm ! ( "csrr {}, mstatus" , out( reg) self . mstatus) ;
217
191
// 设置返回地址,返回到 S
218
192
// TODO Vectored stvec?
219
193
self . mepc = stvec:: read ( ) . address ( ) ;
220
194
}
221
195
}
196
+
197
+ fn trap_stop ( & self , trap : mcause:: Trap ) -> ! {
198
+ println ! (
199
+ "
200
+ -----------------------------
201
+ > trap: {trap:?}
202
+ > mstatus: {:#018x}
203
+ > mepc: {:#018x}
204
+ > mtval: {:#018x}
205
+ -----------------------------
206
+ " ,
207
+ self . mstatus,
208
+ self . mepc,
209
+ mtval:: read( )
210
+ ) ;
211
+ panic ! ( "stopped with unsupported trap" )
212
+ }
222
213
}
223
214
224
215
/// M 态转到 S 态。
@@ -230,7 +221,7 @@ impl Context {
230
221
/// 实际 x0(zero) 和 x2(sp) 不需要保存在这里。
231
222
#[ naked]
232
223
unsafe extern "C" fn m_to_s ( ctx : & mut Context ) {
233
- core :: arch :: asm!(
224
+ asm ! (
234
225
r"
235
226
.altmacro
236
227
.macro SAVE_M n
@@ -298,7 +289,7 @@ unsafe extern "C" fn m_to_s(ctx: &mut Context) {
298
289
#[ naked]
299
290
#[ link_section = ".text.trap_handler" ]
300
291
unsafe extern "C" fn s_to_m ( ) {
301
- core :: arch :: asm!(
292
+ asm ! (
302
293
r"
303
294
.altmacro
304
295
.macro SAVE_S n
0 commit comments