@@ -8,6 +8,7 @@ mod device_tree;
8
8
mod hart_csr_utils;
9
9
mod qemu_test;
10
10
mod riscv_spec;
11
+ mod trap_stack;
11
12
mod trap_vec;
12
13
13
14
mod constants {
@@ -26,24 +27,18 @@ use constants::*;
26
27
use core:: {
27
28
arch:: asm,
28
29
convert:: Infallible ,
29
- mem:: { forget, size_of, MaybeUninit } ,
30
- ptr:: NonNull ,
30
+ mem:: MaybeUninit ,
31
31
sync:: atomic:: { AtomicBool , Ordering } ,
32
32
} ;
33
33
use device_tree:: BoardInfo ;
34
- use fast_trap:: { FastContext , FastResult , FlowContext , FreeTrapStack , TrapStackBlock } ;
35
- use hsm_cell:: HsmCell ;
34
+ use fast_trap:: { FastContext , FastResult } ;
36
35
use riscv_spec:: * ;
37
36
use rustsbi:: RustSBI ;
38
37
use sbi_spec:: binary:: SbiRet ;
39
38
use spin:: { Mutex , Once } ;
40
- use trap_vec :: { load_trap_vec , trap_vec } ;
39
+ use trap_stack :: { local_hsm , local_remote_hsm , remote_hsm } ;
41
40
use uart_16550:: MmioSerialPort ;
42
41
43
- /// 栈空间。
44
- #[ link_section = ".bss.uninit" ]
45
- static mut ROOT_STACK : [ Stack ; NUM_HART_MAX ] = [ Stack :: ZERO ; NUM_HART_MAX ] ;
46
-
47
42
/// 入口。
48
43
///
49
44
/// # Safety
@@ -54,22 +49,13 @@ static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX];
54
49
#[ link_section = ".text.entry" ]
55
50
unsafe extern "C" fn _start ( ) -> ! {
56
51
asm ! (
57
- " la sp, {stack}
58
- li t0, {per_hart_stack_size}
59
- csrr t1, mhartid
60
- addi t1, t1, 1
61
- 1: add sp, sp, t0
62
- addi t1, t1, -1
63
- bnez t1, 1b
64
- call {move_stack}
52
+ " call {locate_stack}
65
53
call {rust_main}
66
54
j {trap}
67
55
" ,
68
- per_hart_stack_size = const LEN_STACK_PER_HART ,
69
- stack = sym ROOT_STACK ,
70
- move_stack = sym fast_trap:: reuse_stack_for_trap,
71
- rust_main = sym rust_main,
72
- trap = sym trap_vec,
56
+ locate_stack = sym trap_stack:: locate,
57
+ rust_main = sym rust_main,
58
+ trap = sym trap_vec:: trap_vec,
73
59
options( noreturn)
74
60
)
75
61
}
@@ -139,24 +125,18 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
139
125
set_pmp ( board_info) ;
140
126
hart_csr_utils:: print_pmps ( ) ;
141
127
// 设置陷入栈
142
- unsafe { ROOT_STACK [ hart_id ( ) ] . load_as_stack ( ) } ;
128
+ trap_stack :: load ( ) ;
143
129
// 设置内核入口
144
- unsafe {
145
- ROOT_STACK [ hart_id ( ) ]
146
- . hart_context ( )
147
- . hsm
148
- . remote ( )
149
- . start ( Supervisor {
150
- start_addr : SUPERVISOR_ENTRY ,
151
- opaque,
152
- } ) ;
153
- }
130
+ local_remote_hsm ( ) . start ( Supervisor {
131
+ start_addr : SUPERVISOR_ENTRY ,
132
+ opaque,
133
+ } ) ;
154
134
DONE . store ( false , Ordering :: SeqCst ) ;
155
135
} else {
156
136
// 设置 pmp
157
137
set_pmp ( BOARD_INFO . wait ( ) ) ;
158
138
// 设置陷入栈
159
- unsafe { ROOT_STACK [ hart_id ( ) ] . load_as_stack ( ) } ;
139
+ trap_stack :: load ( ) ;
160
140
while DONE . load ( Ordering :: SeqCst ) {
161
141
core:: hint:: spin_loop ( ) ;
162
142
}
@@ -227,30 +207,25 @@ extern "C" fn fast_handler(
227
207
|| cause. cause ( ) == T :: Interrupt ( I :: MachineSoft )
228
208
{
229
209
let hart_id = hart_id ( ) ;
230
- let hart_ctx = unsafe { ROOT_STACK [ hart_id] . hart_context ( ) } ;
231
- match unsafe { hart_ctx. hsm . local ( ) } . start ( ) {
210
+ match local_hsm ( ) . start ( ) {
232
211
Ok ( supervisor) => {
233
- unsafe {
234
- let mut status = mstatus:: read ( ) ;
235
- status &= !mstatus:: MPP ;
236
- status |= mstatus:: MPIE | mstatus:: MPP_SUPERVISOR ;
237
- mstatus:: write ( status) ;
238
- mie:: write ( mie:: MSIE | mie:: MTIE | mie:: MEIE ) ;
239
- load_trap_vec ( true ) ;
240
- }
212
+ mstatus:: update ( |bits| {
213
+ * bits &= !mstatus:: MPP ;
214
+ * bits |= mstatus:: MPIE | mstatus:: MPP_SUPERVISOR ;
215
+ } ) ;
216
+ mie:: write ( mie:: MSIE | mie:: MTIE | mie:: MEIE ) ;
217
+ trap_vec:: load ( true ) ;
241
218
ctx. regs ( ) . a [ 0 ] = hart_id;
242
219
ctx. regs ( ) . a [ 1 ] = supervisor. opaque ;
243
220
ctx. regs ( ) . pc = supervisor. start_addr ;
244
221
}
245
222
Err ( _state) => {
246
- unsafe {
247
- let mut status = mstatus:: read ( ) ;
248
- status &= !mstatus:: MPP ;
249
- status |= mstatus:: MPIE | mstatus:: MPP_MACHINE ;
250
- mstatus:: write ( status) ;
251
- mie:: write ( mie:: MSIE ) ;
252
- load_trap_vec ( false ) ;
253
- } ;
223
+ mstatus:: update ( |bits| {
224
+ * bits &= !mstatus:: MPP ;
225
+ * bits |= mstatus:: MPIE | mstatus:: MPP_MACHINE ;
226
+ } ) ;
227
+ mie:: write ( mie:: MSIE ) ;
228
+ trap_vec:: load ( false ) ;
254
229
ctx. regs ( ) . pc = _stop as usize ;
255
230
}
256
231
}
@@ -268,22 +243,18 @@ extern "C" fn fast_handler(
268
243
if ret. is_ok ( ) && a7 == hsm:: EID_HSM {
269
244
// 关闭
270
245
if a6 == hsm:: HART_STOP {
271
- unsafe {
272
- load_trap_vec ( false ) ;
273
- mie:: write ( mie:: MSIE ) ;
274
- ROOT_STACK [ hart_id ( ) ] . hart_context ( ) . hsm . local ( ) . stop ( ) ;
275
- ctx. regs ( ) . pc = _stop as usize ;
276
- }
246
+ local_hsm ( ) . stop ( ) ;
247
+ mie:: write ( mie:: MSIE ) ;
248
+ trap_vec:: load ( false ) ;
249
+ ctx. regs ( ) . pc = _stop as _ ;
277
250
return ctx. call ( 0 ) ;
278
251
}
279
252
// 不可恢复挂起
280
253
if a6 == hsm:: HART_SUSPEND
281
254
&& ctx. a0 ( ) == hsm:: HART_SUSPEND_TYPE_NON_RETENTIVE as usize
282
255
{
283
- unsafe {
284
- load_trap_vec ( false ) ;
285
- ctx. regs ( ) . pc = _stop as usize ;
286
- }
256
+ trap_vec:: load ( false ) ;
257
+ ctx. regs ( ) . pc = _stop as _ ;
287
258
return ctx. call ( 0 ) ;
288
259
}
289
260
}
@@ -325,69 +296,6 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
325
296
unreachable ! ( )
326
297
}
327
298
328
- /// 类型化栈。
329
- ///
330
- /// 每个硬件线程拥有一个满足这样条件的内存块。
331
- /// 这个内存块的底部放着硬件线程状态 [`HartContext`],顶部用于陷入处理,中间是这个硬件线程的栈空间。
332
- /// 不需要 M 态线程,每个硬件线程只有这一个栈。
333
- #[ repr( C , align( 128 ) ) ]
334
- struct Stack ( [ u8 ; LEN_STACK_PER_HART ] ) ;
335
-
336
- impl Stack {
337
- /// 零初始化以避免加载。
338
- const ZERO : Self = Self ( [ 0 ; LEN_STACK_PER_HART ] ) ;
339
-
340
- /// 从栈上取出硬件线程状态。
341
- #[ inline]
342
- fn hart_context ( & mut self ) -> & mut HartContext {
343
- unsafe { & mut * self . 0 . as_mut_ptr ( ) . cast ( ) }
344
- }
345
-
346
- fn load_as_stack ( & ' static mut self ) {
347
- let hart = self . hart_context ( ) ;
348
- hart. hsm = HsmCell :: new ( ) ;
349
- let ptr = unsafe { NonNull :: new_unchecked ( & mut hart. trap ) } ;
350
- forget (
351
- FreeTrapStack :: new ( StackRef ( self ) , ptr, fast_handler)
352
- . unwrap ( )
353
- . load ( ) ,
354
- ) ;
355
- }
356
- }
357
-
358
- #[ repr( transparent) ]
359
- struct StackRef ( & ' static mut Stack ) ;
360
-
361
- impl AsRef < [ u8 ] > for StackRef {
362
- #[ inline]
363
- fn as_ref ( & self ) -> & [ u8 ] {
364
- & self . 0 . 0 [ size_of :: < HartContext > ( ) ..]
365
- }
366
- }
367
-
368
- impl AsMut < [ u8 ] > for StackRef {
369
- #[ inline]
370
- fn as_mut ( & mut self ) -> & mut [ u8 ] {
371
- & mut self . 0 . 0 [ size_of :: < HartContext > ( ) ..]
372
- }
373
- }
374
-
375
- impl TrapStackBlock for StackRef { }
376
-
377
- impl Drop for StackRef {
378
- fn drop ( & mut self ) {
379
- panic ! ( "Root stack cannot be dropped" )
380
- }
381
- }
382
-
383
- /// 硬件线程上下文。
384
- #[ repr( C ) ]
385
- struct HartContext {
386
- /// 陷入上下文。
387
- trap : FlowContext ,
388
- hsm : HsmCell < Supervisor > ,
389
- }
390
-
391
299
/// 特权软件信息。
392
300
#[ derive( Debug ) ]
393
301
struct Supervisor {
@@ -429,9 +337,9 @@ struct Hsm;
429
337
430
338
impl rustsbi:: Hsm for Hsm {
431
339
fn hart_start ( & self , hartid : usize , start_addr : usize , opaque : usize ) -> SbiRet {
432
- match unsafe { ROOT_STACK . get_mut ( hartid) . map ( |s| s . hart_context ( ) ) } {
433
- Some ( hart ) => {
434
- if hart . hsm . remote ( ) . start ( Supervisor { start_addr, opaque } ) {
340
+ match remote_hsm ( hartid) {
341
+ Some ( remote ) => {
342
+ if remote. start ( Supervisor { start_addr, opaque } ) {
435
343
clint:: msip:: send ( hartid) ;
436
344
SbiRet :: success ( 0 )
437
345
} else {
@@ -444,40 +352,30 @@ impl rustsbi::Hsm for Hsm {
444
352
445
353
#[ inline]
446
354
fn hart_stop ( & self ) -> SbiRet {
447
- unsafe {
448
- ROOT_STACK [ hart_id ( ) ]
449
- . hart_context ( )
450
- . hsm
451
- . local ( )
452
- . stop_pending ( )
453
- } ;
355
+ local_hsm ( ) . stop_pending ( ) ;
454
356
SbiRet :: success ( 0 )
455
357
}
456
358
457
359
#[ inline]
458
360
fn hart_get_status ( & self , hartid : usize ) -> SbiRet {
459
- match unsafe { ROOT_STACK . get_mut ( hartid) . map ( |s| s . hart_context ( ) ) } {
460
- Some ( hart ) => SbiRet :: success ( hart . hsm . remote ( ) . sbi_get_status ( ) ) ,
361
+ match remote_hsm ( hartid) {
362
+ Some ( remote ) => SbiRet :: success ( remote. sbi_get_status ( ) ) ,
461
363
None => SbiRet :: invalid_param ( ) ,
462
364
}
463
365
}
464
366
465
367
fn hart_suspend ( & self , suspend_type : u32 , resume_addr : usize , opaque : usize ) -> SbiRet {
466
368
use sbi_spec:: hsm as spec;
467
369
match suspend_type {
468
- spec:: HART_SUSPEND_TYPE_NON_RETENTIVE => unsafe {
469
- ROOT_STACK [ hart_id ( ) ]
470
- . hart_context ( )
471
- . hsm
472
- . local ( )
473
- . suspend_non_retentive ( Supervisor {
474
- start_addr : resume_addr,
475
- opaque,
476
- } ) ;
370
+ spec:: HART_SUSPEND_TYPE_NON_RETENTIVE => {
371
+ local_hsm ( ) . suspend_non_retentive ( Supervisor {
372
+ start_addr : resume_addr,
373
+ opaque,
374
+ } ) ;
477
375
SbiRet :: success ( 0 )
478
- } ,
376
+ }
479
377
spec:: HART_SUSPEND_TYPE_RETENTIVE => unsafe {
480
- ROOT_STACK [ hart_id ( ) ] . hart_context ( ) . hsm . local ( ) . suspend ( ) ;
378
+ local_hsm ( ) . suspend ( ) ;
481
379
asm ! (
482
380
" la {0}, 1f
483
381
csrrw {0}, mtvec, {0}
@@ -493,7 +391,7 @@ impl rustsbi::Hsm for Hsm {
493
391
out( reg) _,
494
392
mie = const mstatus:: MIE ,
495
393
) ;
496
- ROOT_STACK [ hart_id ( ) ] . hart_context ( ) . hsm . local ( ) . resume ( ) ;
394
+ local_hsm ( ) . resume ( ) ;
497
395
SbiRet :: success ( 0 )
498
396
} ,
499
397
_ => SbiRet :: not_supported ( ) ,
0 commit comments