@@ -7,11 +7,12 @@ use core::{
7
7
arch:: asm,
8
8
mem:: { forget, MaybeUninit } ,
9
9
ptr:: { null, NonNull } ,
10
+ unreachable,
10
11
} ;
11
12
use dtb_walker:: { Dtb , DtbObj , HeaderError , Str , WalkOperation } ;
12
13
use fast_trap:: {
13
- load_direct_trap_entry, reuse_stack_for_trap, trap_entry, FastContext , FastResult , FlowContext ,
14
- FreeTrapStack , TrapStackBlock ,
14
+ load_direct_trap_entry, reuse_stack_for_trap, soft_trap , trap_entry, FastContext , FastResult ,
15
+ FlowContext , FreeTrapStack , TrapStackBlock ,
15
16
} ;
16
17
use rcore_console:: log;
17
18
use riscv:: register:: * ;
@@ -20,6 +21,7 @@ use uart_16550::MmioSerialPort;
20
21
21
22
#[ link_section = ".bss.uninit" ]
22
23
static mut ROOT_STACK : Stack = Stack ( [ 0 ; 4096 ] ) ;
24
+ static mut FREE_STACK : Stack = Stack ( [ 0 ; 4096 ] ) ;
23
25
static mut ROOT_CONTEXT : FlowContext = FlowContext :: ZERO ;
24
26
25
27
#[ naked]
@@ -133,17 +135,30 @@ extern "C" fn rust_main(_hartid: usize, dtb: *const u8) {
133
135
. unwrap ( )
134
136
. load ( ) ;
135
137
138
+ {
139
+ // 叠加一个陷入栈用于临时保护
140
+ let _loaded = FreeTrapStack :: new (
141
+ StackRef ( unsafe { & mut FREE_STACK } ) ,
142
+ context_ptr,
143
+ fast_handler,
144
+ )
145
+ . unwrap ( )
146
+ . load ( ) ;
147
+ // 模拟陷入
148
+ unsafe { soft_trap ( cause:: CALL ) } ;
149
+ }
150
+
136
151
#[ cfg( feature = "m-mode" ) ]
137
152
{
138
153
assert_ne ! ( 0x5050 , mscratch:: read( ) ) ;
139
154
log:: debug!( "mscratch: {:#x}" , mscratch:: read( ) ) ;
140
- unsafe { asm ! ( "csrw mcause, {}" , in( reg) 24 ) } ;
155
+ unsafe { asm ! ( "csrw mcause, {}" , in( reg) cause :: BOOT ) } ;
141
156
}
142
157
#[ cfg( feature = "s-mode" ) ]
143
158
{
144
159
assert_ne ! ( 0x5050 , sscratch:: read( ) ) ;
145
160
log:: debug!( "sscratch: {:#x}" , sscratch:: read( ) ) ;
146
- unsafe { asm ! ( "csrw scause, {}" , in( reg) 24 ) } ;
161
+ unsafe { asm ! ( "csrw scause, {}" , in( reg) cause :: BOOT ) } ;
147
162
}
148
163
149
164
// 忘了它,在汇编里触发陷入还要用
@@ -153,6 +168,11 @@ extern "C" fn rust_main(_hartid: usize, dtb: *const u8) {
153
168
unsafe { load_direct_trap_entry ( ) } ;
154
169
}
155
170
171
+ mod cause {
172
+ pub ( super ) const BOOT : usize = 24 ;
173
+ pub ( super ) const CALL : usize = 25 ;
174
+ }
175
+
156
176
extern "C" fn fast_handler (
157
177
mut ctx : FastContext ,
158
178
a1 : usize ,
@@ -174,10 +194,13 @@ extern "C" fn fast_handler(
174
194
unsafe { & * TEST } . pass ( )
175
195
}
176
196
T :: Exception ( E :: Unknown ) => {
177
- mepc:: write ( exception as _ ) ;
197
+ match cause. bits ( ) {
198
+ cause:: BOOT => mepc:: write ( exception as _ ) ,
199
+ cause:: CALL => log:: warn!( "call fast-trap inline!" ) ,
200
+ _ => unreachable ! ( ) ,
201
+ }
178
202
unsafe { mstatus:: set_mpp ( mstatus:: MPP :: Machine ) } ;
179
- let a0 = ctx. a0 ( ) ;
180
- ctx. regs ( ) . a = [ a0, a1, a2, a3, a4, a5, a6, a7] ;
203
+ ctx. regs ( ) . a = [ ctx. a0 ( ) , a1, a2, a3, a4, a5, a6, a7] ;
181
204
ctx. restore ( )
182
205
}
183
206
T :: Exception ( _) | T :: Interrupt ( _) => unreachable ! ( ) ,
@@ -194,10 +217,13 @@ extern "C" fn fast_handler(
194
217
unsafe { & * TEST } . pass ( )
195
218
}
196
219
T :: Exception ( E :: Unknown ) => {
197
- sepc:: write ( exception as _ ) ;
220
+ match cause. bits ( ) {
221
+ cause:: BOOT => mepc:: write ( exception as _ ) ,
222
+ cause:: CALL => log:: warn!( "call fast-trap inline!" ) ,
223
+ _ => unreachable ! ( ) ,
224
+ }
198
225
unsafe { sstatus:: set_spp ( sstatus:: SPP :: Supervisor ) } ;
199
- let a0 = ctx. a0 ( ) ;
200
- ctx. regs ( ) . a = [ a0, a1, a2, a3, a4, a5, a6, a7] ;
226
+ ctx. regs ( ) . a = [ ctx. a0 ( ) , a1, a2, a3, a4, a5, a6, a7] ;
201
227
ctx. restore ( )
202
228
}
203
229
T :: Exception ( _) | T :: Interrupt ( _) => unreachable ! ( ) ,
0 commit comments