1
1
#![ no_std]
2
2
#![ no_main]
3
3
#![ feature( naked_functions, asm_const) ]
4
- #![ deny( warnings) ]
4
+ // #![deny(warnings)]
5
5
6
6
mod clint;
7
7
mod device_tree;
8
- mod execute;
9
8
mod hart_csr_utils;
10
- mod qemu_hsm;
11
9
mod qemu_test;
12
10
13
11
mod constants {
@@ -31,9 +29,8 @@ use core::{
31
29
sync:: atomic:: { AtomicBool , Ordering } ,
32
30
} ;
33
31
use device_tree:: BoardInfo ;
34
- use execute:: Operation ;
35
32
use fast_trap:: {
36
- load_direct_trap_entry, reuse_stack_for_trap, FastContext , FastResult , FlowContext ,
33
+ load_direct_trap_entry, reuse_stack_for_trap, trap_entry , FastContext , FastResult , FlowContext ,
37
34
FreeTrapStack , TrapStackBlock ,
38
35
} ;
39
36
use hsm_cell:: HsmCell ;
@@ -61,29 +58,24 @@ static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX];
61
58
unsafe extern "C" fn _start ( ) -> ! {
62
59
asm ! (
63
60
// 关中断
64
- " csrw mie, zero" ,
61
+ " csrw mie, zero" ,
65
62
// 设置栈
66
- " la sp, {stack}
67
- li t0, {per_hart_stack_size}
68
- csrr t1, mhartid
69
- addi t1, t1, 1
70
- 1: add sp, sp, t0
71
- addi t1, t1, -1
72
- bnez t1, 1b
73
- call {move_stack}
74
- " ,
75
- " call {rust_main}" ,
76
- // 清理,然后重启或等待
77
- " call {finalize}
78
- bnez a0, _start
79
- 1: wfi
80
- j 1b
63
+ " la sp, {stack}
64
+ li t0, {per_hart_stack_size}
65
+ csrr t1, mhartid
66
+ addi t1, t1, 1
67
+ 1: add sp, sp, t0
68
+ addi t1, t1, -1
69
+ bnez t1, 1b
70
+ call {move_stack}
81
71
" ,
72
+ " call {rust_main}" ,
73
+ " j {trap}" ,
82
74
per_hart_stack_size = const LEN_STACK_PER_HART ,
83
75
stack = sym ROOT_STACK ,
84
76
move_stack = sym reuse_stack_for_trap,
85
77
rust_main = sym rust_main,
86
- finalize = sym finalize ,
78
+ trap = sym trap_entry ,
87
79
options( noreturn)
88
80
)
89
81
}
@@ -93,19 +85,19 @@ unsafe extern "C" fn _stop() -> ! {
93
85
asm ! ( "wfi" , options( noreturn) )
94
86
}
95
87
96
- static HSM : Once < qemu_hsm :: QemuHsm > = Once :: new ( ) ;
88
+ static mut SBI : MaybeUninit < FixedRustSBI > = MaybeUninit :: uninit ( ) ;
97
89
98
90
type FixedRustSBI < ' a > = RustSBI <
99
91
& ' a clint:: Clint ,
100
92
& ' a clint:: Clint ,
101
93
Infallible ,
102
- & ' a qemu_hsm :: QemuHsm ,
94
+ Infallible ,
103
95
& ' a qemu_test:: QemuTest ,
104
96
Infallible ,
105
97
> ;
106
98
107
99
/// rust 入口。
108
- extern "C" fn rust_main ( _hartid : usize , opaque : usize ) -> Operation {
100
+ extern "C" fn rust_main ( _hartid : usize , opaque : usize ) {
109
101
static GENESIS : AtomicBool = AtomicBool :: new ( true ) ;
110
102
static BOARD_INFO : Once < BoardInfo > = Once :: new ( ) ;
111
103
@@ -124,7 +116,6 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) -> Operation {
124
116
rcore_console:: set_log_level ( option_env ! ( "LOG" ) ) ;
125
117
clint:: init ( board_info. clint . start ) ;
126
118
qemu_test:: init ( board_info. test . start ) ;
127
- HSM . call_once ( || qemu_hsm:: QemuHsm :: new ( NUM_HART_MAX , opaque) ) ;
128
119
// 打印启动信息
129
120
print ! (
130
121
"\
@@ -149,6 +140,16 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) -> Operation {
149
140
dtb = board_info. dtb,
150
141
firmware = _start as usize ,
151
142
) ;
143
+ // 初始化 SBI
144
+ unsafe {
145
+ SBI = MaybeUninit :: new (
146
+ rustsbi:: Builder :: new_machine ( )
147
+ . with_ipi ( & clint:: Clint )
148
+ . with_timer ( & clint:: Clint )
149
+ . with_reset ( qemu_test:: get ( ) )
150
+ . build ( ) ,
151
+ ) ;
152
+ } ;
152
153
// 设置并打印 pmp
153
154
set_pmp ( board_info) ;
154
155
hart_csr_utils:: print_pmps ( ) ;
@@ -165,6 +166,9 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) -> Operation {
165
166
opaque,
166
167
} ) ;
167
168
}
169
+ // 清理 clint
170
+ clint:: msip:: clear ( ) ;
171
+ clint:: mtimecmp:: clear ( ) ;
168
172
} else {
169
173
// 设置 pmp
170
174
set_pmp ( BOARD_INFO . wait ( ) ) ;
@@ -184,42 +188,6 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) -> Operation {
184
188
mie:: set_mtimer ( ) ;
185
189
load_direct_trap_entry ( ) ;
186
190
}
187
-
188
- let hsm = HSM . wait ( ) ;
189
- if let Some ( supervisor) = hsm. take_supervisor ( ) {
190
- // 初始化 SBI 服务
191
- let sbi = rustsbi:: Builder :: new_machine ( )
192
- . with_ipi ( & clint:: Clint )
193
- . with_timer ( & clint:: Clint )
194
- . with_reset ( qemu_test:: get ( ) )
195
- . with_hsm ( hsm)
196
- . build ( ) ;
197
- execute:: execute_supervisor ( sbi, hsm, supervisor)
198
- } else {
199
- Operation :: Stop
200
- }
201
- }
202
-
203
- /// 准备好不可恢复休眠或关闭
204
- ///
205
- /// 在隔离的环境(汇编)调用,以确保 main 中使用的堆资源完全释放。
206
- /// (只是作为示例,因为这个版本完全不使用堆)
207
- unsafe extern "C" fn finalize ( op : Operation ) -> ! {
208
- match op {
209
- Operation :: Stop => {
210
- HSM . wait ( ) . finalize_before_stop ( ) ;
211
- riscv:: interrupt:: enable ( ) ;
212
- // 从中断响应直接回 entry
213
- loop {
214
- riscv:: asm:: wfi ( ) ;
215
- }
216
- }
217
- Operation :: SystemReset => {
218
- // TODO 等待其他硬件线程关闭
219
- // 直接回 entry
220
- _start ( )
221
- }
222
- }
223
191
}
224
192
225
193
#[ inline( always) ]
@@ -253,14 +221,14 @@ mod cause {
253
221
}
254
222
255
223
extern "C" fn fast_handler (
256
- ctx : FastContext ,
257
- _a1 : usize ,
258
- _a2 : usize ,
259
- _a3 : usize ,
260
- _a4 : usize ,
261
- _a5 : usize ,
262
- _a6 : usize ,
263
- _a7 : usize ,
224
+ mut ctx : FastContext ,
225
+ a1 : usize ,
226
+ a2 : usize ,
227
+ a3 : usize ,
228
+ a4 : usize ,
229
+ a5 : usize ,
230
+ a6 : usize ,
231
+ a7 : usize ,
264
232
) -> FastResult {
265
233
use mcause:: { Exception as E , Trap as T } ;
266
234
@@ -279,17 +247,30 @@ extern "C" fn fast_handler(
279
247
hart_ctx. trap . a [ 0 ] = hart_id;
280
248
hart_ctx. trap . a [ 1 ] = supervisor. opaque ;
281
249
hart_ctx. trap . pc = supervisor. start_addr ;
250
+ println ! ( "trap = {:?}" , ( & hart_ctx. trap) as * const _) ;
282
251
}
283
- // TODO 检查状态,设置启动参数
284
252
Err ( _state) => {
285
253
hart_ctx. trap . pc = _stop as usize ;
254
+ println ! ( "{_state:#x}" ) ;
286
255
}
287
256
}
288
257
ctx. call ( 2 )
289
258
}
290
259
_ => unreachable ! ( ) ,
291
260
} ,
292
- T :: Exception ( _) | T :: Interrupt ( _) => todo ! ( ) ,
261
+ T :: Exception ( E :: SupervisorEnvCall ) => {
262
+ let ret = unsafe { SBI . assume_init_mut ( ) } . handle_ecall (
263
+ a7,
264
+ a6,
265
+ [ ctx. a0 ( ) , a1, a2, a3, a4, a5] ,
266
+ ) ;
267
+ mepc:: write ( mepc:: read ( ) + 4 ) ;
268
+ ctx. save_args ( ret. value , a2, a3, a4, a5, a6, a7) ;
269
+ ctx. write_a ( 0 , ret. error ) ;
270
+ ctx. restore ( )
271
+ }
272
+ T :: Exception ( e) => todo ! ( "{e:?}" ) ,
273
+ T :: Interrupt ( i) => todo ! ( "{i:?}" ) ,
293
274
}
294
275
}
295
276
@@ -325,7 +306,9 @@ impl Stack {
325
306
}
326
307
327
308
fn load_as_stack ( & ' static mut self ) {
328
- let ptr = unsafe { NonNull :: new_unchecked ( & mut self . hart_context ( ) . trap ) } ;
309
+ let hart = self . hart_context ( ) ;
310
+ hart. hsm = HsmCell :: new ( ) ;
311
+ let ptr = unsafe { NonNull :: new_unchecked ( & mut hart. trap ) } ;
329
312
forget (
330
313
FreeTrapStack :: new ( StackRef ( self ) , ptr, fast_handler)
331
314
. unwrap ( )
0 commit comments