@@ -3,15 +3,11 @@ use crate::{
3
3
qemu_hsm:: { QemuHsm , SUSPEND_NON_RETENTIVE } ,
4
4
Supervisor ,
5
5
} ;
6
-
7
- mod context;
8
- mod transfer_trap;
9
-
10
- use context:: Context ;
6
+ use riscv:: register:: { mstatus, mtval, scause, sepc, stval, stvec} ;
11
7
12
8
pub ( crate ) fn execute_supervisor ( hsm : & QemuHsm , supervisor : Supervisor ) {
13
9
use core:: arch:: asm;
14
- use riscv:: register:: { medeleg, mie, mstatus } ;
10
+ use riscv:: register:: { medeleg, mie} ;
15
11
16
12
unsafe {
17
13
mstatus:: set_mpp ( mstatus:: MPP :: Supervisor ) ;
@@ -73,15 +69,16 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
73
69
ctx. mepc = ctx. mepc . wrapping_add ( 4 ) ;
74
70
}
75
71
T :: Exception ( E :: IllegalInstruction ) => {
76
- use riscv:: register:: scause;
72
+ use riscv:: register:: scause:: { Exception as E , Trap as T } ;
77
73
74
+ // let instruction = mtval::read();
75
+ // 尝试修正或代理指令
76
+ // TODO 需要排查 qemu 哪些版本需要代理哪些指令?
77
+ // TODO 标准 20191213 的表 24.3 列出了一些特殊的 CSR,SBI 软件负责将它们模拟出来,但 Qemu6.0+ 似乎不需要模拟 time
78
78
// const OPCODE_MASK: usize = (1 << 7) - 1;
79
79
// const REG_MASK: usize = (1 << 5) - 1;
80
80
// const OPCODE_CSR: usize = 0b1110011;
81
81
// const CSR_TIME: usize = 0xc01;
82
- // let instruction = mtval::read();
83
- // 标准 20191213 的表 24.3 列出了一些特殊的 CSR,SBI 软件负责将它们模拟出来
84
- // Qemu 似乎不需要模拟 time
85
82
// if let OPCODE_CSR = instruction & OPCODE_MASK {
86
83
// if instruction >> 20 == CSR_TIME {
87
84
// match (instruction >> 7) & REG_MASK {
@@ -91,26 +88,90 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
91
88
// continue;
92
89
// }
93
90
// }
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 ) ) ;
109
93
}
94
+ // TODO 可以修复非原子的非对称访存
95
+ t => panic ! ( "unsupported trap: {t:?}" ) ,
110
96
}
111
97
}
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
+ }
114
175
}
115
176
}
116
177
0 commit comments