@@ -9,9 +9,31 @@ struct Context {
9
9
mepc : usize ,
10
10
}
11
11
12
+ impl Context {
13
+ #[ inline]
14
+ fn a ( & self , n : usize ) -> usize {
15
+ self . x [ n + 9 ]
16
+ }
17
+
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
+ }
33
+
12
34
pub ( crate ) fn execute_supervisor ( supervisor : Supervisor ) {
13
35
use core:: arch:: asm;
14
- use riscv:: register:: { medeleg, mie, mip , mstatus} ;
36
+ use riscv:: register:: { medeleg, mie, mstatus} ;
15
37
16
38
unsafe {
17
39
mstatus:: set_mpp ( mstatus:: MPP :: Supervisor ) ;
@@ -67,11 +89,51 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
67
89
ctx. mepc = ctx. mepc . wrapping_add ( 4 ) ;
68
90
}
69
91
T :: Interrupt ( I :: MachineTimer ) => unsafe {
92
+ use riscv:: register:: mip;
70
93
mip:: clear_mtimer ( ) ;
71
94
mip:: set_stimer ( ) ;
72
95
} ,
73
96
T :: Exception ( E :: IllegalInstruction ) => {
74
- println ! ( "TODO emulate or forward illegal instruction" ) ;
97
+ use riscv:: register:: mtval;
98
+
99
+ const OPCODE_MASK : usize = ( 1 << 7 ) - 1 ;
100
+ const REG_MASK : usize = ( 1 << 5 ) - 1 ;
101
+ const OPCODE_CSR : usize = 0b1110011 ;
102
+ const CSR_TIME : usize = 0xc01 ;
103
+ let instruction = mtval:: read ( ) ;
104
+ // 标准 20191213 的表 24.3 列出了一些特殊的 CSR,SBI 软件负责将它们模拟出来
105
+ if let OPCODE_CSR = instruction & OPCODE_MASK {
106
+ if instruction >> 20 == CSR_TIME {
107
+ match ( instruction >> 7 ) & REG_MASK {
108
+ 0 => { }
109
+ rd => * ctx. x_mut ( rd) = crate :: clint:: get ( ) . get_mtime ( ) as _ ,
110
+ }
111
+ continue ;
112
+ }
113
+ }
114
+ // 如果不是可修正的指令,且不是 M 态本身发出的,转交给 S 态处理
115
+ // 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 ;
135
+ }
136
+ println ! ( "{:?}" , E :: IllegalInstruction ) ;
75
137
break ;
76
138
}
77
139
t => {
@@ -85,18 +147,6 @@ pub(crate) fn execute_supervisor(supervisor: Supervisor) {
85
147
}
86
148
}
87
149
88
- impl Context {
89
- #[ inline]
90
- fn a ( & self , n : usize ) -> usize {
91
- self . x [ 9 + n]
92
- }
93
-
94
- #[ inline]
95
- fn a_mut ( & mut self , n : usize ) -> & mut usize {
96
- & mut self . x [ 9 + n]
97
- }
98
- }
99
-
100
150
/// M 态转到 S 态。
101
151
///
102
152
/// # Safety
0 commit comments