7
7
use core:: arch:: asm;
8
8
use core:: panic:: PanicInfo ;
9
9
10
- use riscv:: register:: {
11
- scause:: { self , Exception , Trap } ,
12
- sepc,
13
- stvec:: { self , TrapMode } ,
14
- } ;
10
+ use riscv:: register:: { scause:: { self , Exception , Trap } , sepc, /*sie, sstatus, */ stvec:: { self , TrapMode } } ;
11
+ use riscv:: register:: scause:: Interrupt ;
15
12
16
13
#[ macro_use]
17
14
mod console;
18
15
mod mm;
19
16
mod sbi;
20
17
21
18
pub extern "C" fn rust_main ( hartid : usize , dtb_pa : usize ) -> ! {
19
+ unsafe { asm ! ( "mv tp, {}" , in( reg) hartid, options( nomem, nostack) ) } ; // tp == hartid
20
+ let mut start_trap_addr = start_trap as usize ;
21
+ if start_trap_addr & 0b10 != 0 {
22
+ start_trap_addr += 0b10 ;
23
+ }
22
24
if hartid == 0 {
23
25
// initialization
24
26
mm:: init_heap ( ) ;
@@ -30,14 +32,14 @@ pub extern "C" fn rust_main(hartid: usize, dtb_pa: usize) -> ! {
30
32
) ;
31
33
test_base_extension ( ) ;
32
34
test_sbi_ins_emulation ( ) ;
33
- unsafe { stvec:: write ( start_trap as usize , TrapMode :: Direct ) } ;
35
+ unsafe { stvec:: write ( start_trap_addr , TrapMode :: Direct ) } ;
34
36
println ! ( ">> Test-kernel: Trigger illegal exception" ) ;
35
37
unsafe { asm ! ( "csrw mcycle, x0" ) } ; // mcycle cannot be written, this is always a 4-byte illegal instruction
36
38
}
37
39
if hartid == 0 {
38
40
let sbi_ret = sbi:: hart_stop ( 3 ) ;
39
41
println ! ( ">> Stop hart 3, return value {:?}" , sbi_ret) ;
40
- for i in 0 ..4 {
42
+ for i in 0 ..5 {
41
43
let sbi_ret = sbi:: hart_get_status ( i) ;
42
44
println ! ( ">> Hart {} state return value: {:?}" , i, sbi_ret) ;
43
45
}
@@ -52,6 +54,14 @@ pub extern "C" fn rust_main(hartid: usize, dtb_pa: usize) -> ! {
52
54
let sbi_ret = sbi:: hart_suspend ( 0x80000000 , hart_2_resume as usize , 0x4567890a ) ;
53
55
println ! ( ">> Error for non-retentive suspend: {:?}" , sbi_ret) ;
54
56
loop { }
57
+ } else if hartid == 4 {
58
+ // unsafe { stvec::write(start_trap_addr, TrapMode::Direct) };
59
+ // unsafe { sstatus::set_sie() };
60
+ // unsafe { sie::set_ssoft() };
61
+ // loop {} // wait for S-IPI
62
+ // println!(">> Test-kernel: SBI S-IPI delegation success");
63
+ // println!("<< Test-kernel: All hart SBI test SUCCESS, shutdown");
64
+ loop { } // todo: S-IPI
55
65
} else {
56
66
// hartid == 3
57
67
loop { }
@@ -70,7 +80,7 @@ pub extern "C" fn rust_main(hartid: usize, dtb_pa: usize) -> ! {
70
80
println ! ( ">> Wake hart 2, sbi return value {:?}" , sbi_ret) ;
71
81
loop { }
72
82
} else {
73
- // hartid == 2 || hartid == 3
83
+ // hartid == 2 || hartid == 3 || hartid == 4
74
84
unreachable ! ( )
75
85
}
76
86
}
@@ -95,6 +105,10 @@ extern "C" fn hart_3_start(hart_id: usize, param: usize) {
95
105
) ;
96
106
println ! ( "<< Test-kernel: All hart SBI test SUCCESS, shutdown" ) ;
97
107
sbi:: shutdown ( )
108
+ // todo: S-IPI
109
+ // println!(">> Send IPI to hart 4, should delegate IPI to S-level");
110
+ // let _ = sbi::send_ipi(0b1, 4); // IPI to hart 4
111
+ // loop {} // wait for machine shutdown
98
112
}
99
113
100
114
fn test_base_extension ( ) {
@@ -142,15 +156,26 @@ fn test_sbi_ins_emulation() {
142
156
}
143
157
}
144
158
145
- pub extern "C" fn rust_trap_exception ( ) {
146
- let cause = scause:: read ( ) . cause ( ) ;
147
- println ! ( "<< Test-kernel: Value of scause: {:?}" , cause) ;
148
- if cause != Trap :: Exception ( Exception :: IllegalInstruction ) {
149
- println ! ( "!! Test-kernel: Wrong cause associated to illegal instruction" ) ;
159
+ extern "C" fn rust_trap_exception ( trap_frame : & mut TrapFrame ) {
160
+ if trap_frame. tp == 0 {
161
+ let cause = scause:: read ( ) . cause ( ) ;
162
+ println ! ( "<< Test-kernel: Value of scause: {:?}" , cause) ;
163
+ if cause != Trap :: Exception ( Exception :: IllegalInstruction ) {
164
+ println ! ( "!! Test-kernel: Wrong cause associated to illegal instruction" ) ;
165
+ sbi:: shutdown ( )
166
+ }
167
+ println ! ( "<< Test-kernel: Illegal exception delegate success" ) ;
168
+ sepc:: write ( sepc:: read ( ) . wrapping_add ( 4 ) ) ;
169
+ } else if trap_frame. tp == 4 {
170
+ if scause:: read ( ) . cause ( ) != Trap :: Interrupt ( Interrupt :: SupervisorSoft ) {
171
+ println ! ( "!! Test-kernel: Wrong cause associated to S-IPI delegation" ) ;
172
+ sbi:: shutdown ( )
173
+ }
174
+ } else {
175
+ println ! ( "!! Test-kernel: hart {} should not trap" , trap_frame. tp) ;
176
+ println ! ( "!! Test-kernel: SBI test FAILED for this hart should not trap" ) ;
150
177
sbi:: shutdown ( )
151
178
}
152
- println ! ( "<< Test-kernel: Illegal exception delegate success" ) ;
153
- sepc:: write ( sepc:: read ( ) . wrapping_add ( 4 ) ) ;
154
179
}
155
180
156
181
#[ cfg_attr( not( test) , panic_handler) ]
@@ -233,7 +258,7 @@ macro_rules! define_store_load {
233
258
unsafe extern "C" fn start_trap ( ) {
234
259
asm ! ( define_store_load!( ) , "
235
260
.p2align 2
236
- addi sp, sp, -16 * {REGBYTES}
261
+ addi sp, sp, -17 * {REGBYTES}
237
262
STORE ra, 0
238
263
STORE t0, 1
239
264
STORE t1, 2
@@ -250,6 +275,7 @@ unsafe extern "C" fn start_trap() {
250
275
STORE a5, 13
251
276
STORE a6, 14
252
277
STORE a7, 15
278
+ STORE tp, 16
253
279
mv a0, sp
254
280
call {rust_trap_exception}
255
281
LOAD ra, 0
@@ -268,10 +294,32 @@ unsafe extern "C" fn start_trap() {
268
294
LOAD a5, 13
269
295
LOAD a6, 14
270
296
LOAD a7, 15
271
- addi sp, sp, 16 * {REGBYTES}
297
+ LOAD tp, 16
298
+ addi sp, sp, 17 * {REGBYTES}
272
299
sret
273
300
" ,
274
301
REGBYTES = const core:: mem:: size_of:: <usize >( ) ,
275
302
rust_trap_exception = sym rust_trap_exception,
276
303
options( noreturn) )
277
304
}
305
+
306
+ #[ repr( C ) ]
307
+ struct TrapFrame {
308
+ ra : usize ,
309
+ t0 : usize ,
310
+ t1 : usize ,
311
+ t2 : usize ,
312
+ t3 : usize ,
313
+ t4 : usize ,
314
+ t5 : usize ,
315
+ t6 : usize ,
316
+ a0 : usize ,
317
+ a1 : usize ,
318
+ a2 : usize ,
319
+ a3 : usize ,
320
+ a4 : usize ,
321
+ a5 : usize ,
322
+ a6 : usize ,
323
+ a7 : usize ,
324
+ tp : usize ,
325
+ }
0 commit comments