1
1
//! mcounteren register
2
2
3
+ use crate :: bits:: { bf_extract, bf_insert} ;
4
+
3
5
/// mcounteren register
4
6
#[ derive( Clone , Copy , Debug ) ]
5
7
pub struct Mcounteren {
@@ -10,31 +12,64 @@ impl Mcounteren {
10
12
/// Supervisor "cycle\[h\]" Enable
11
13
#[ inline]
12
14
pub fn cy ( & self ) -> bool {
13
- self . bits & ( 1 << 0 ) != 0
15
+ bf_extract ( self . bits , 0 , 1 ) != 0
16
+ }
17
+
18
+ /// Sets whether to enable the "cycle\[h\]" counter.
19
+ ///
20
+ /// Only updates the in-memory value, does not modify the `mcounteren` register.
21
+ #[ inline]
22
+ pub fn set_cy ( & mut self , cy : bool ) {
23
+ self . bits = bf_insert ( self . bits , 0 , 1 , cy as usize ) ;
14
24
}
15
25
16
26
/// Supervisor "time\[h\]" Enable
17
27
#[ inline]
18
28
pub fn tm ( & self ) -> bool {
19
- self . bits & ( 1 << 1 ) != 0
29
+ bf_extract ( self . bits , 1 , 1 ) != 0
30
+ }
31
+
32
+ /// Sets whether to enable "time\[h\]".
33
+ ///
34
+ /// Only updates the in-memory value, does not modify the `mcounteren` register.
35
+ #[ inline]
36
+ pub fn set_tm ( & mut self , tm : bool ) {
37
+ self . bits = bf_insert ( self . bits , 1 , 1 , tm as usize ) ;
20
38
}
21
39
22
40
/// Supervisor "instret\[h\]" Enable
23
41
#[ inline]
24
42
pub fn ir ( & self ) -> bool {
25
- self . bits & ( 1 << 2 ) != 0
43
+ bf_extract ( self . bits , 2 , 1 ) != 0
44
+ }
45
+
46
+ /// Sets whether to enable the "instret\[h\]" counter.
47
+ ///
48
+ /// Only updates the in-memory value, does not modify the `mcounteren` register.
49
+ #[ inline]
50
+ pub fn set_ir ( & mut self , ir : bool ) {
51
+ self . bits = bf_insert ( self . bits , 2 , 1 , ir as usize ) ;
26
52
}
27
53
28
54
/// Supervisor "hpm\[x\]" Enable (bits 3-31)
29
55
#[ inline]
30
56
pub fn hpm ( & self , index : usize ) -> bool {
31
57
assert ! ( ( 3 ..32 ) . contains( & index) ) ;
32
- self . bits & ( 1 << index) != 0
58
+ bf_extract ( self . bits , index, 1 ) != 0
59
+ }
60
+
61
+ /// Sets whether to enable the "hpm\[X\]" counter.
62
+ ///
63
+ /// Only updates the in-memory value, does not modify the `mcounteren` register.
64
+ #[ inline]
65
+ pub fn set_hpm ( & mut self , index : usize , hpm : bool ) {
66
+ assert ! ( ( 3 ..32 ) . contains( & index) ) ;
67
+ self . bits = bf_insert ( self . bits , index, 1 , hpm as usize ) ;
33
68
}
34
69
}
35
70
36
71
read_csr_as ! ( Mcounteren , 0x306 ) ;
37
- write_csr ! ( 0x306 ) ;
72
+ write_csr_as ! ( Mcounteren , 0x306 ) ;
38
73
set ! ( 0x306 ) ;
39
74
clear ! ( 0x306 ) ;
40
75
@@ -61,3 +96,47 @@ pub unsafe fn clear_hpm(index: usize) {
61
96
assert ! ( ( 3 ..32 ) . contains( & index) ) ;
62
97
_clear ( 1 << index) ;
63
98
}
99
+
100
+ #[ cfg( test) ]
101
+ mod tests {
102
+ use super :: * ;
103
+
104
+ #[ test]
105
+ fn test_mcounteren ( ) {
106
+ let mut m = Mcounteren { bits : 0 } ;
107
+
108
+ assert ! ( !m. cy( ) ) ;
109
+
110
+ m. set_cy ( true ) ;
111
+ assert ! ( m. cy( ) ) ;
112
+
113
+ m. set_cy ( false ) ;
114
+ assert ! ( !m. cy( ) ) ;
115
+
116
+ assert ! ( !m. tm( ) ) ;
117
+
118
+ m. set_tm ( true ) ;
119
+ assert ! ( m. tm( ) ) ;
120
+
121
+ m. set_tm ( false ) ;
122
+ assert ! ( !m. tm( ) ) ;
123
+
124
+ assert ! ( !m. ir( ) ) ;
125
+
126
+ m. set_ir ( true ) ;
127
+ assert ! ( m. ir( ) ) ;
128
+
129
+ m. set_ir ( false ) ;
130
+ assert ! ( !m. ir( ) ) ;
131
+
132
+ ( 3 ..32 ) . for_each ( |i| {
133
+ assert ! ( !m. hpm( i) ) ;
134
+
135
+ m. set_hpm ( i, true ) ;
136
+ assert ! ( m. hpm( i) ) ;
137
+
138
+ m. set_hpm ( i, false ) ;
139
+ assert ! ( !m. hpm( i) ) ;
140
+ } ) ;
141
+ }
142
+ }
0 commit comments