1
1
//! mstatus register
2
2
// TODO: Virtualization, Memory Privilege and Extension Context Fields
3
3
4
+ use bit_field:: BitField ;
5
+
4
6
/// mstatus register
5
7
#[ derive( Clone , Copy , Debug ) ]
6
8
pub struct Mstatus {
7
9
bits : usize ,
8
10
}
9
11
12
+ /// Additional extension state
13
+ pub enum XS {
14
+ /// All off
15
+ AllOff = 0 ,
16
+
17
+ /// None dirty or clean, some on
18
+ NoneDirtyOrClean = 1 ,
19
+
20
+ /// None dirty, some clean
21
+ NoneDirtySomeClean = 2 ,
22
+
23
+ /// Some dirty
24
+ SomeDirty = 3 ,
25
+ }
26
+
27
+ /// Floating-point extension state
28
+ pub enum FS {
29
+ Off = 0 ,
30
+ Initial = 1 ,
31
+ Clean = 2 ,
32
+ Dirty = 3 ,
33
+ }
34
+
10
35
/// Machine Previous Privilege Mode
11
36
pub enum MPP {
12
37
Machine = 3 ,
@@ -24,43 +49,43 @@ impl Mstatus {
24
49
/// User Interrupt Enable
25
50
#[ inline]
26
51
pub fn uie ( & self ) -> bool {
27
- self . bits & ( 1 << 0 ) == 1 << 0
52
+ self . bits . get_bit ( 0 )
28
53
}
29
54
30
55
/// Supervisor Interrupt Enable
31
56
#[ inline]
32
57
pub fn sie ( & self ) -> bool {
33
- self . bits & ( 1 << 1 ) == 1 << 1
58
+ self . bits . get_bit ( 1 )
34
59
}
35
60
36
61
/// Machine Interrupt Enable
37
62
#[ inline]
38
63
pub fn mie ( & self ) -> bool {
39
- self . bits & ( 1 << 3 ) == 1 << 3
64
+ self . bits . get_bit ( 3 )
40
65
}
41
66
42
67
/// User Previous Interrupt Enable
43
68
#[ inline]
44
69
pub fn upie ( & self ) -> bool {
45
- self . bits & ( 1 << 4 ) == 1 << 4
70
+ self . bits . get_bit ( 4 )
46
71
}
47
72
48
73
/// Supervisor Previous Interrupt Enable
49
74
#[ inline]
50
75
pub fn spie ( & self ) -> bool {
51
- self . bits & ( 1 << 5 ) == 1 << 5
76
+ self . bits . get_bit ( 5 )
52
77
}
53
78
54
79
/// User Previous Interrupt Enable
55
80
#[ inline]
56
81
pub fn mpie ( & self ) -> bool {
57
- self . bits & ( 1 << 7 ) == 1 << 7
82
+ self . bits . get_bit ( 7 )
58
83
}
59
84
60
85
/// Supervisor Previous Privilege Mode
61
86
#[ inline]
62
87
pub fn spp ( & self ) -> SPP {
63
- match self . bits & ( 1 << 8 ) == ( 1 << 8 ) {
88
+ match self . bits . get_bit ( 8 ) {
64
89
true => SPP :: Supervisor ,
65
90
false => SPP :: User ,
66
91
}
@@ -69,45 +94,95 @@ impl Mstatus {
69
94
/// Machine Previous Privilege Mode
70
95
#[ inline]
71
96
pub fn mpp ( & self ) -> MPP {
72
- match ( self . bits & ( 0b11 << 11 ) ) >> 11 {
97
+ match self . bits . get_bits ( 11 .. 13 ) {
73
98
0b00 => MPP :: User ,
74
99
0b01 => MPP :: Supervisor ,
75
100
0b11 => MPP :: Machine ,
76
101
_ => unreachable ! ( ) ,
77
102
}
78
103
}
104
+
105
+ /// Floating-point extension state
106
+ ///
107
+ /// Encodes the status of the floating-point unit,
108
+ /// including the CSR `fcsr` and floating-point data registers `f0–f31`.
109
+ #[ inline]
110
+ pub fn fs ( & self ) -> FS {
111
+ match self . bits . get_bits ( 13 ..15 ) {
112
+ 0b00 => FS :: Off ,
113
+ 0b01 => FS :: Initial ,
114
+ 0b10 => FS :: Clean ,
115
+ 0b11 => FS :: Dirty ,
116
+ _ => unreachable ! ( ) ,
117
+ }
118
+ }
119
+
120
+ /// Additional extension state
121
+ ///
122
+ /// Encodes the status of additional user-mode extensions and associated state.
123
+ #[ inline]
124
+ pub fn xs ( & self ) -> XS {
125
+ match self . bits . get_bits ( 15 ..17 ) {
126
+ 0b00 => XS :: AllOff ,
127
+ 0b01 => XS :: NoneDirtyOrClean ,
128
+ 0b10 => XS :: NoneDirtySomeClean ,
129
+ 0b11 => XS :: SomeDirty ,
130
+ _ => unreachable ! ( ) ,
131
+ }
132
+ }
79
133
}
80
134
81
135
82
136
read_csr_as ! ( Mstatus , 0x300 , __read_mstatus) ;
137
+ write_csr ! ( 0x300 , __write_mstatus) ;
83
138
set ! ( 0x300 , __set_mstatus) ;
84
139
clear ! ( 0x300 , __clear_mstatus) ;
85
140
86
141
set_clear_csr ! (
87
142
/// User Interrupt Enable
88
143
, set_uie, clear_uie, 1 << 0 ) ;
144
+
89
145
set_clear_csr ! (
90
146
/// Supervisor Interrupt Enable
91
147
, set_sie, clear_sie, 1 << 1 ) ;
148
+
92
149
set_clear_csr ! (
93
150
/// Machine Interrupt Enable
94
151
, set_mie, clear_mie, 1 << 3 ) ;
152
+
95
153
set_csr ! (
96
154
/// User Previous Interrupt Enable
97
155
, set_upie, 1 << 4 ) ;
156
+
98
157
set_csr ! (
99
158
/// Supervisor Previous Interrupt Enable
100
159
, set_spie, 1 << 5 ) ;
160
+
101
161
set_csr ! (
102
162
/// Machine Previous Interrupt Enable
103
163
, set_mpie, 1 << 7 ) ;
164
+
104
165
/// Supervisor Previous Privilege Mode
105
166
#[ inline]
106
167
pub unsafe fn set_spp ( spp : SPP ) {
107
- _set ( ( spp as usize ) << 8 ) ;
168
+ match spp {
169
+ SPP :: Supervisor => _set ( 1 << 8 ) ,
170
+ SPP :: User => _clear ( 1 << 8 ) ,
171
+ }
108
172
}
173
+
109
174
/// Machine Previous Privilege Mode
110
175
#[ inline]
111
176
pub unsafe fn set_mpp ( mpp : MPP ) {
112
- _set ( ( mpp as usize ) << 11 ) ;
177
+ let mut value = _read ( ) ;
178
+ value. set_bits ( 11 ..13 , mpp as usize ) ;
179
+ _write ( value) ;
180
+ }
181
+
182
+ /// Floating-point extension state
183
+ #[ inline]
184
+ pub unsafe fn set_fs ( fs : FS ) {
185
+ let mut value = _read ( ) ;
186
+ value. set_bits ( 13 ..15 , fs as usize ) ;
187
+ _write ( value) ;
113
188
}
0 commit comments