@@ -36,6 +36,7 @@ use riscv_spec::*;
36
36
use rustsbi:: { spec:: binary:: SbiRet , RustSBI } ;
37
37
use spin:: { Mutex , Once } ;
38
38
use trap_stack:: { local_hsm, local_remote_hsm, remote_hsm} ;
39
+ use trap_vec:: trap_vec;
39
40
use uart_16550:: MmioSerialPort ;
40
41
41
42
/// 入口。
@@ -54,16 +55,11 @@ unsafe extern "C" fn _start() -> ! {
54
55
" ,
55
56
locate_stack = sym trap_stack:: locate,
56
57
rust_main = sym rust_main,
57
- trap = sym trap_vec:: trap_vec ,
58
+ trap = sym trap_vec,
58
59
options( noreturn)
59
60
)
60
61
}
61
62
62
- #[ naked]
63
- unsafe extern "C" fn _stop ( ) -> ! {
64
- asm ! ( "0: wfi" , "j 0b" , options( noreturn) )
65
- }
66
-
67
63
/// rust 入口。
68
64
extern "C" fn rust_main ( hartid : usize , opaque : usize ) {
69
65
static GENESIS : AtomicBool = AtomicBool :: new ( true ) ;
@@ -145,12 +141,13 @@ extern "C" fn rust_main(hartid: usize, opaque: usize) {
145
141
clint:: clear ( ) ;
146
142
// 准备启动调度
147
143
unsafe {
148
- asm ! ( "csrw mcause, {}" , in( reg) cause:: BOOT ) ;
149
144
asm ! ( "csrw mideleg, {}" , in( reg) !0 ) ;
150
145
asm ! ( "csrw medeleg, {}" , in( reg) !0 ) ;
151
146
asm ! ( "csrw mcounteren, {}" , in( reg) !0 ) ;
152
- riscv:: register:: medeleg:: clear_supervisor_env_call ( ) ;
153
- riscv:: register:: medeleg:: clear_machine_env_call ( ) ;
147
+ use riscv:: register:: { medeleg, mtvec} ;
148
+ medeleg:: clear_supervisor_env_call ( ) ;
149
+ medeleg:: clear_machine_env_call ( ) ;
150
+ mtvec:: write ( trap_vec as _ , mtvec:: TrapMode :: Vectored ) ;
154
151
}
155
152
}
156
153
@@ -181,10 +178,6 @@ fn set_pmp(board_info: &BoardInfo) {
181
178
}
182
179
}
183
180
184
- mod cause {
185
- pub ( crate ) const BOOT : usize = 24 ;
186
- }
187
-
188
181
extern "C" fn fast_handler (
189
182
mut ctx : FastContext ,
190
183
a1 : usize ,
@@ -196,123 +189,105 @@ extern "C" fn fast_handler(
196
189
a7 : usize ,
197
190
) -> FastResult {
198
191
use riscv:: register:: {
199
- mcause:: { self , Exception as E , Interrupt as I , Trap as T } ,
200
- mtval,
192
+ mcause:: { self , Exception as E , Trap as T } ,
193
+ mtval, satp , sstatus ,
201
194
} ;
202
195
203
- let cause = mcause:: read ( ) ;
204
- // 启动
205
- if ( cause. cause ( ) == T :: Exception ( E :: Unknown ) && cause. bits ( ) == cause:: BOOT )
206
- || cause. cause ( ) == T :: Interrupt ( I :: MachineSoft )
207
- {
208
- let hart_id = hart_id ( ) ;
196
+ #[ inline]
197
+ fn boot ( mut ctx : FastContext , start_addr : usize , opaque : usize ) -> FastResult {
198
+ unsafe {
199
+ sstatus:: clear_sie ( ) ;
200
+ satp:: write ( 0 ) ;
201
+ }
202
+ ctx. regs ( ) . a [ 0 ] = hart_id ( ) ;
203
+ ctx. regs ( ) . a [ 1 ] = opaque;
204
+ ctx. regs ( ) . pc = start_addr;
205
+ ctx. call ( 2 )
206
+ }
207
+ loop {
209
208
match local_hsm ( ) . start ( ) {
210
209
Ok ( supervisor) => {
211
210
mstatus:: update ( |bits| {
212
211
* bits &= !mstatus:: MPP ;
213
212
* bits |= mstatus:: MPIE | mstatus:: MPP_SUPERVISOR ;
214
213
} ) ;
215
214
mie:: write ( mie:: MSIE | mie:: MTIE ) ;
216
- trap_vec:: load ( true ) ;
217
- unsafe {
218
- riscv:: register:: sstatus:: clear_sie ( ) ;
219
- riscv:: register:: satp:: write ( 0 ) ;
220
- }
221
- ctx. regs ( ) . a [ 0 ] = hart_id;
222
- ctx. regs ( ) . a [ 1 ] = supervisor. opaque ;
223
- ctx. regs ( ) . pc = supervisor. start_addr ;
215
+ break boot ( ctx, supervisor. start_addr , supervisor. opaque ) ;
224
216
}
225
- Err ( _state) => {
226
- mstatus:: update ( |bits| {
227
- * bits &= !mstatus:: MPP ;
228
- * bits |= mstatus:: MPIE | mstatus:: MPP_MACHINE ;
229
- } ) ;
217
+ Err ( sbi_spec:: hsm:: HART_STOP ) => {
230
218
mie:: write ( mie:: MSIE ) ;
231
- trap_vec :: load ( false ) ;
232
- ctx . regs ( ) . pc = _stop as usize ;
219
+ unsafe { riscv :: asm :: wfi ( ) } ;
220
+ clint :: clear_msip ( ) ;
233
221
}
234
- }
235
- return ctx. call ( 2 ) ;
236
- }
237
- match cause. cause ( ) {
238
- // SBI call
239
- T :: Exception ( E :: SupervisorEnvCall ) => {
240
- use rustsbi:: spec:: { base, hsm, legacy} ;
241
- let mut ret = unsafe { SBI . assume_init_mut ( ) } . handle_ecall (
242
- a7,
243
- a6,
244
- [ ctx. a0 ( ) , a1, a2, a3, a4, a5] ,
245
- ) ;
246
- if ret. is_ok ( ) {
247
- match a7 {
248
- hsm:: EID_HSM => {
249
- // 关闭
250
- if a6 == hsm:: HART_STOP {
251
- local_hsm ( ) . stop ( ) ;
252
- mie:: write ( mie:: MSIE ) ;
253
- trap_vec:: load ( false ) ;
254
- ctx. regs ( ) . pc = _stop as _ ;
255
- return ctx. call ( 0 ) ;
222
+ _ => match mcause:: read ( ) . cause ( ) {
223
+ // SBI call
224
+ T :: Exception ( E :: SupervisorEnvCall ) => {
225
+ use rustsbi:: spec:: { base, hsm, legacy} ;
226
+ let mut ret = unsafe { SBI . assume_init_mut ( ) } . handle_ecall (
227
+ a7,
228
+ a6,
229
+ [ ctx. a0 ( ) , a1, a2, a3, a4, a5] ,
230
+ ) ;
231
+ if ret. is_ok ( ) {
232
+ match ( a7, a6) {
233
+ // 关闭
234
+ ( hsm:: EID_HSM , hsm:: HART_STOP ) => continue ,
235
+ // 不可恢复挂起
236
+ ( hsm:: EID_HSM , hsm:: HART_SUSPEND )
237
+ if matches ! (
238
+ ctx. a0( ) as u32 ,
239
+ hsm:: HART_SUSPEND_TYPE_NON_RETENTIVE
240
+ ) =>
241
+ {
242
+ break boot ( ctx, a1, a2) ;
243
+ }
244
+ // legacy console 探测
245
+ ( base:: EID_BASE , base:: PROBE_EXTENSION )
246
+ if matches ! (
247
+ ctx. a0( ) ,
248
+ legacy:: LEGACY_CONSOLE_PUTCHAR | legacy:: LEGACY_CONSOLE_GETCHAR
249
+ ) =>
250
+ {
251
+ ret. value = 1 ;
252
+ }
253
+ _ => { }
256
254
}
257
- // 不可恢复挂起
258
- if a6 == hsm:: HART_SUSPEND
259
- && ctx. a0 ( ) == hsm:: HART_SUSPEND_TYPE_NON_RETENTIVE as usize
260
- {
261
- unsafe {
262
- riscv:: register:: sstatus:: clear_sie ( ) ;
263
- riscv:: register:: satp:: write ( 0 ) ;
255
+ } else {
256
+ match a7 {
257
+ legacy:: LEGACY_CONSOLE_PUTCHAR => {
258
+ print ! ( "{}" , ctx. a0( ) as u8 as char ) ;
259
+ ret. error = 0 ;
260
+ ret. value = a1;
264
261
}
265
- ctx. regs ( ) . a [ 0 ] = hart_id ( ) ;
266
- ctx. regs ( ) . a [ 1 ] = a2;
267
- ctx. regs ( ) . pc = a1;
268
- return ctx. call ( 0 ) ;
262
+ legacy:: LEGACY_CONSOLE_GETCHAR => {
263
+ ret. error = unsafe { UART . lock ( ) . assume_init_mut ( ) } . receive ( ) as _ ;
264
+ ret. value = a1;
265
+ }
266
+ _ => { }
269
267
}
270
268
}
271
- base:: EID_BASE
272
- if a6 == base:: PROBE_EXTENSION
273
- && matches ! (
274
- ctx. a0( ) ,
275
- legacy:: LEGACY_CONSOLE_PUTCHAR | legacy:: LEGACY_CONSOLE_GETCHAR
276
- ) =>
277
- {
278
- ret. value = 1 ;
279
- }
280
- _ => { }
269
+ ctx. regs ( ) . a = [ ret. error , ret. value , a2, a3, a4, a5, a6, a7] ;
270
+ mepc:: next ( ) ;
271
+ break ctx. restore ( ) ;
281
272
}
282
- } else {
283
- match a7 {
284
- legacy:: LEGACY_CONSOLE_PUTCHAR => {
285
- print ! ( "{}" , ctx. a0( ) as u8 as char ) ;
286
- ret. error = 0 ;
287
- ret. value = a1;
288
- }
289
- legacy:: LEGACY_CONSOLE_GETCHAR => {
290
- ret. error = unsafe { UART . lock ( ) . assume_init_mut ( ) } . receive ( ) as _ ;
291
- ret. value = a1;
292
- }
293
- _ => { }
294
- }
295
- }
296
- ctx. regs ( ) . a = [ ret. error , ret. value , a2, a3, a4, a5, a6, a7] ;
297
- mepc:: next ( ) ;
298
- ctx. restore ( )
299
- }
300
- // 其他陷入
301
- trap => {
302
- println ! (
303
- "
273
+ // 其他陷入
274
+ trap => {
275
+ println ! (
276
+ "
304
277
-----------------------------
305
278
> trap: {trap:?}
306
279
> mstatus: {:#018x}
307
280
> mepc: {:#018x}
308
281
> mtval: {:#018x}
309
282
-----------------------------
310
283
" ,
311
- mstatus:: read( ) ,
312
- mepc:: read( ) ,
313
- mtval:: read( )
314
- ) ;
315
- panic ! ( "stopped with unsupported trap" )
284
+ mstatus:: read( ) ,
285
+ mepc:: read( ) ,
286
+ mtval:: read( )
287
+ ) ;
288
+ panic ! ( "stopped with unsupported trap" )
289
+ }
290
+ } ,
316
291
}
317
292
}
318
293
}
@@ -386,7 +361,7 @@ impl rustsbi::Hsm for Hsm {
386
361
387
362
#[ inline]
388
363
fn hart_stop ( & self ) -> SbiRet {
389
- local_hsm ( ) . stop_pending ( ) ;
364
+ local_hsm ( ) . stop ( ) ;
390
365
SbiRet :: success ( 0 )
391
366
}
392
367
0 commit comments