1
1
use crate :: { clint, hart_id, Supervisor } ;
2
2
3
- #[ repr( C ) ]
4
- #[ derive( Debug ) ]
5
- struct Context {
6
- msp : usize ,
7
- x : [ usize ; 31 ] ,
8
- mstatus : usize ,
9
- mepc : usize ,
10
- }
11
-
12
- impl Context {
13
- #[ inline]
14
- fn a ( & self , n : usize ) -> usize {
15
- self . x [ n + 9 ]
16
- }
3
+ mod context;
4
+ mod transfer_trap;
17
5
18
- #[ inline]
19
- fn a_mut ( & mut self , n : usize ) -> & mut usize {
20
- & mut self . x [ n + 9 ]
21
- }
22
-
23
- #[ inline]
24
- fn x ( & self , n : usize ) -> usize {
25
- self . x [ n - 1 ]
26
- }
27
-
28
- #[ inline]
29
- fn x_mut ( & mut self , n : usize ) -> & mut usize {
30
- & mut self . x [ n - 1 ]
31
- }
32
- }
6
+ use context:: Context ;
33
7
34
8
pub ( crate ) fn execute_supervisor ( supervisor : Supervisor ) {
35
9
use core:: arch:: asm;
@@ -40,19 +14,10 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
40
14
mstatus:: set_mie ( ) ;
41
15
} ;
42
16
43
- let mut ctx = Context {
44
- msp : 0 ,
45
- x : [ 0 ; 31 ] ,
46
- mstatus : 0 ,
47
- mepc : supervisor. start_addr ,
48
- } ;
49
-
50
- * ctx. a_mut ( 0 ) = hart_id ( ) ;
51
- * ctx. a_mut ( 1 ) = supervisor. opaque ;
17
+ let mut ctx = Context :: new ( supervisor) ;
52
18
53
19
clint:: get ( ) . clear_soft ( hart_id ( ) ) ;
54
20
unsafe {
55
- asm ! ( "csrr {}, mstatus" , out( reg) ctx. mstatus) ;
56
21
asm ! ( "csrw mip, {}" , in( reg) 0 ) ;
57
22
asm ! ( "csrw mideleg, {}" , in( reg) usize :: MAX ) ;
58
23
asm ! ( "csrw medeleg, {}" , in( reg) usize :: MAX ) ;
@@ -73,6 +38,26 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
73
38
unsafe { m_to_s ( & mut ctx) } ;
74
39
75
40
match mcause:: read ( ) . cause ( ) {
41
+ T :: Interrupt ( I :: MachineTimer ) => unsafe {
42
+ use riscv:: register:: mip;
43
+ mip:: clear_mtimer ( ) ;
44
+ mip:: set_stimer ( ) ;
45
+ } ,
46
+ T :: Interrupt ( I :: MachineSoft ) => {
47
+ use riscv:: register:: { mip, scause} ;
48
+
49
+ crate :: clint:: get ( ) . clear_soft ( hart_id ( ) ) ;
50
+ unsafe { mip:: clear_msoft ( ) } ;
51
+ if transfer_trap:: should_transfer_trap ( & ctx) {
52
+ transfer_trap:: do_transfer_trap (
53
+ & mut ctx,
54
+ scause:: Trap :: Interrupt ( scause:: Interrupt :: SupervisorSoft ) ,
55
+ ) ;
56
+ } else {
57
+ println ! ( "{:?}" , I :: MachineSoft ) ;
58
+ break ;
59
+ }
60
+ }
76
61
T :: Exception ( E :: SupervisorEnvCall ) => {
77
62
let param = [ ctx. a ( 0 ) , ctx. a ( 1 ) , ctx. a ( 2 ) , ctx. a ( 3 ) , ctx. a ( 4 ) , ctx. a ( 5 ) ] ;
78
63
let ans = rustsbi:: ecall ( ctx. a ( 7 ) , ctx. a ( 6 ) , param) ;
@@ -88,13 +73,8 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
88
73
* ctx. a_mut ( 1 ) = ans. value ;
89
74
ctx. mepc = ctx. mepc . wrapping_add ( 4 ) ;
90
75
}
91
- T :: Interrupt ( I :: MachineTimer ) => unsafe {
92
- use riscv:: register:: mip;
93
- mip:: clear_mtimer ( ) ;
94
- mip:: set_stimer ( ) ;
95
- } ,
96
76
T :: Exception ( E :: IllegalInstruction ) => {
97
- use riscv:: register:: mtval;
77
+ use riscv:: register:: { mtval, scause } ;
98
78
99
79
const OPCODE_MASK : usize = ( 1 << 7 ) - 1 ;
100
80
const REG_MASK : usize = ( 1 << 5 ) - 1 ;
@@ -113,28 +93,15 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
113
93
}
114
94
// 如果不是可修正的指令,且不是 M 态本身发出的,转交给 S 态处理
115
95
// mpp != machine
116
- if ( ctx. mstatus >> 11 ) & 0b11 != 0b11 {
117
- use riscv:: register:: {
118
- scause:: { self , Exception , Trap } ,
119
- sepc, stval, stvec,
120
- } ;
121
- unsafe {
122
- scause:: set ( Trap :: Exception ( Exception :: IllegalInstruction ) ) ;
123
- stval:: write ( instruction) ;
124
- sepc:: write ( ctx. mepc ) ;
125
- mstatus:: set_mpp ( mstatus:: MPP :: Supervisor ) ;
126
- mstatus:: set_spp ( mstatus:: SPP :: Supervisor ) ;
127
- if mstatus:: read ( ) . sie ( ) {
128
- mstatus:: set_spie ( )
129
- }
130
- mstatus:: clear_sie ( ) ;
131
- core:: arch:: asm!( "csrr {}, mstatus" , out( reg) ctx. mstatus) ;
132
- ctx. mepc = stvec:: read ( ) . address ( ) ;
133
- }
134
- continue ;
96
+ if transfer_trap:: should_transfer_trap ( & ctx) {
97
+ transfer_trap:: do_transfer_trap (
98
+ & mut ctx,
99
+ scause:: Trap :: Exception ( scause:: Exception :: IllegalInstruction ) ,
100
+ ) ;
101
+ } else {
102
+ println ! ( "{:?}" , I :: MachineSoft ) ;
103
+ break ;
135
104
}
136
- println ! ( "{:?}" , E :: IllegalInstruction ) ;
137
- break ;
138
105
}
139
106
t => {
140
107
println ! ( "{t:?}" ) ;
0 commit comments