@@ -87,6 +87,7 @@ unsafe extern "C" fn _stop() -> ! {
87
87
/// rust 入口。
88
88
extern "C" fn rust_main ( _hartid : usize , opaque : usize ) {
89
89
static GENESIS : AtomicBool = AtomicBool :: new ( true ) ;
90
+ static DONE : AtomicBool = AtomicBool :: new ( true ) ;
90
91
static BOARD_INFO : Once < BoardInfo > = Once :: new ( ) ;
91
92
92
93
// 全局初始化过程
@@ -134,6 +135,7 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
134
135
rustsbi:: Builder :: new_machine ( )
135
136
. with_ipi ( & clint:: Clint )
136
137
. with_timer ( & clint:: Clint )
138
+ . with_hsm ( Hsm )
137
139
. with_reset ( qemu_test:: get ( ) )
138
140
. build ( ) ,
139
141
) ;
@@ -154,11 +156,15 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
154
156
opaque,
155
157
} ) ;
156
158
}
159
+ DONE . store ( false , Ordering :: SeqCst ) ;
157
160
} else {
158
161
// 设置 pmp
159
162
set_pmp ( BOARD_INFO . wait ( ) ) ;
160
163
// 设置陷入栈
161
164
unsafe { ROOT_STACK [ hart_id ( ) ] . load_as_stack ( ) } ;
165
+ while DONE . load ( Ordering :: SeqCst ) {
166
+ core:: hint:: spin_loop ( ) ;
167
+ }
162
168
}
163
169
// 清理 clint
164
170
clint:: msip:: clear ( ) ;
@@ -171,9 +177,6 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
171
177
asm ! ( "csrw mcounteren, {}" , in( reg) !0 ) ;
172
178
medeleg:: clear_supervisor_env_call ( ) ;
173
179
medeleg:: clear_machine_env_call ( ) ;
174
- mie:: set_mext ( ) ;
175
- mie:: set_msoft ( ) ;
176
- mie:: set_mtimer ( ) ;
177
180
}
178
181
}
179
182
@@ -232,6 +235,7 @@ extern "C" fn fast_handler(
232
235
mtvec:: write ( trap_vec:: trap_vec as _ , mtvec:: TrapMode :: Vectored ) ;
233
236
mstatus:: set_mpie ( ) ;
234
237
mstatus:: set_mpp ( mstatus:: MPP :: Supervisor ) ;
238
+ asm ! ( "csrw mie, {}" , in( reg) ( 1 <<3 ) |( 1 <<7 ) |( 1 <<11 ) ) ;
235
239
}
236
240
hart_ctx. trap . a [ 0 ] = hart_id;
237
241
hart_ctx. trap . a [ 1 ] = supervisor. opaque ;
@@ -240,6 +244,9 @@ extern "C" fn fast_handler(
240
244
Err ( _state) => {
241
245
unsafe {
242
246
mtvec:: write ( trap_vec:: trap_vec as _ , mtvec:: TrapMode :: Direct ) ;
247
+ mstatus:: set_mpie ( ) ;
248
+ mstatus:: set_mpp ( mstatus:: MPP :: Machine ) ;
249
+ asm ! ( "csrw mie, {}" , in( reg) 1 <<3 ) ;
243
250
} ;
244
251
hart_ctx. trap . pc = _stop as usize ;
245
252
}
@@ -249,20 +256,31 @@ extern "C" fn fast_handler(
249
256
match cause. cause ( ) {
250
257
// SBI call
251
258
T :: Exception ( E :: SupervisorEnvCall ) => {
259
+ use sbi_spec:: hsm;
252
260
let ret = unsafe { SBI . assume_init_mut ( ) } . handle_ecall (
253
261
a7,
254
262
a6,
255
263
[ ctx. a0 ( ) , a1, a2, a3, a4, a5] ,
256
264
) ;
257
- if ret. is_ok ( ) && a7 == sbi_spec :: hsm:: EID_HSM {
258
- match a6 {
259
- sbi_spec :: hsm :: HART_STOP => unsafe {
265
+ if ret. is_ok ( ) && a7 == hsm:: EID_HSM {
266
+ if a6 == hsm :: HART_STOP {
267
+ unsafe {
260
268
mtvec:: write ( trap_vec:: trap_vec as _ , mtvec:: TrapMode :: Direct ) ;
261
269
mstatus:: set_mpp ( mstatus:: MPP :: Machine ) ;
270
+ asm ! ( "csrw mie, {}" , in( reg) 1 <<3 ) ;
262
271
ROOT_STACK [ hart_id ( ) ] . hart_context ( ) . trap . pc = _stop as usize ;
263
- return ctx. call ( 0 ) ;
264
- } ,
265
- _ => { }
272
+ }
273
+ return ctx. call ( 0 ) ;
274
+ }
275
+ if a6 == hsm:: HART_SUSPEND
276
+ && ctx. a0 ( ) == hsm:: HART_SUSPEND_TYPE_NON_RETENTIVE as usize
277
+ {
278
+ unsafe {
279
+ mtvec:: write ( trap_vec:: trap_vec as _ , mtvec:: TrapMode :: Direct ) ;
280
+ mstatus:: set_mpp ( mstatus:: MPP :: Machine ) ;
281
+ ROOT_STACK [ hart_id ( ) ] . hart_context ( ) . trap . pc = _stop as usize ;
282
+ }
283
+ return ctx. call ( 0 ) ;
266
284
}
267
285
}
268
286
mepc:: write ( mepc:: read ( ) + 4 ) ;
@@ -399,7 +417,7 @@ type FixedRustSBI<'a> = RustSBI<
399
417
& ' a clint:: Clint ,
400
418
& ' a clint:: Clint ,
401
419
Infallible ,
402
- Infallible ,
420
+ Hsm ,
403
421
& ' a qemu_test:: QemuTest ,
404
422
Infallible ,
405
423
> ;
@@ -435,9 +453,40 @@ impl rustsbi::Hsm for Hsm {
435
453
}
436
454
}
437
455
438
- #[ inline]
439
456
fn hart_suspend ( & self , suspend_type : u32 , resume_addr : usize , opaque : usize ) -> SbiRet {
440
- let _ = ( suspend_type, resume_addr, opaque) ;
441
- SbiRet :: not_supported ( )
457
+ use sbi_spec:: hsm as spec;
458
+ match suspend_type {
459
+ spec:: HART_SUSPEND_TYPE_NON_RETENTIVE => unsafe {
460
+ ROOT_STACK [ hart_id ( ) ]
461
+ . hart_context ( )
462
+ . hsm
463
+ . local ( )
464
+ . suspend_non_retentive ( Supervisor {
465
+ start_addr : resume_addr,
466
+ opaque,
467
+ } ) ;
468
+ SbiRet :: success ( 0 )
469
+ } ,
470
+ spec:: HART_SUSPEND_TYPE_RETENTIVE => unsafe {
471
+ ROOT_STACK [ hart_id ( ) ] . hart_context ( ) . hsm . local ( ) . suspend ( ) ;
472
+ asm ! (
473
+ " la {0}, 1f
474
+ csrrw {0}, mtvec, {0}
475
+ csrrw {1}, mepc, {1}
476
+ csrrw {2}, mstatus, {2}
477
+ wfi
478
+ 1: csrrw {2}, mstatus, {2}
479
+ csrrw {1}, mepc, {1}
480
+ csrrw {0}, mtvec, {0}
481
+ " ,
482
+ out( reg) _,
483
+ out( reg) _,
484
+ out( reg) _,
485
+ ) ;
486
+ ROOT_STACK [ hart_id ( ) ] . hart_context ( ) . hsm . local ( ) . resume ( ) ;
487
+ SbiRet :: success ( 0 )
488
+ } ,
489
+ _ => SbiRet :: not_supported ( ) ,
490
+ }
442
491
}
443
492
}
0 commit comments