11//! mcounteren register
22
3- use crate :: bits:: bf_extract;
3+ use crate :: bits:: { bf_extract, bf_insert } ;
44
55/// mcounteren register
66#[ derive( Clone , Copy , Debug ) ]
@@ -15,28 +15,61 @@ impl Mcounteren {
1515 bf_extract ( self . bits , 0 , 1 ) != 0
1616 }
1717
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 ) ;
24+ }
25+
1826 /// Supervisor "time\[h\]" Enable
1927 #[ inline]
2028 pub fn tm ( & self ) -> bool {
2129 bf_extract ( self . bits , 1 , 1 ) != 0
2230 }
2331
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 ) ;
38+ }
39+
2440 /// Supervisor "instret\[h\]" Enable
2541 #[ inline]
2642 pub fn ir ( & self ) -> bool {
2743 bf_extract ( self . bits , 2 , 1 ) != 0
2844 }
2945
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 ) ;
52+ }
53+
3054 /// Supervisor "hpm\[x\]" Enable (bits 3-31)
3155 #[ inline]
3256 pub fn hpm ( & self , index : usize ) -> bool {
3357 assert ! ( ( 3 ..32 ) . contains( & index) ) ;
3458 bf_extract ( self . bits , index, 1 ) != 0
3559 }
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 ) ;
68+ }
3669}
3770
3871read_csr_as ! ( Mcounteren , 0x306 ) ;
39- write_csr ! ( 0x306 ) ;
72+ write_csr_as ! ( Mcounteren , 0x306 ) ;
4073set ! ( 0x306 ) ;
4174clear ! ( 0x306 ) ;
4275
@@ -63,3 +96,47 @@ pub unsafe fn clear_hpm(index: usize) {
6396 assert ! ( ( 3 ..32 ) . contains( & index) ) ;
6497 _clear ( 1 << index) ;
6598}
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