11//! mcounteren register
22
3+ use crate :: bits:: { bf_extract, bf_insert} ;
4+
35/// mcounteren register
46#[ derive( Clone , Copy , Debug ) ]
57pub struct Mcounteren {
@@ -10,31 +12,64 @@ impl Mcounteren {
1012 /// Supervisor "cycle\[h\]" Enable
1113 #[ inline]
1214 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 ) ;
1424 }
1525
1626 /// Supervisor "time\[h\]" Enable
1727 #[ inline]
1828 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 ) ;
2038 }
2139
2240 /// Supervisor "instret\[h\]" Enable
2341 #[ inline]
2442 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 ) ;
2652 }
2753
2854 /// Supervisor "hpm\[x\]" Enable (bits 3-31)
2955 #[ inline]
3056 pub fn hpm ( & self , index : usize ) -> bool {
3157 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 ) ;
3368 }
3469}
3570
3671read_csr_as ! ( Mcounteren , 0x306 ) ;
37- write_csr ! ( 0x306 ) ;
72+ write_csr_as ! ( Mcounteren , 0x306 ) ;
3873set ! ( 0x306 ) ;
3974clear ! ( 0x306 ) ;
4075
@@ -61,3 +96,47 @@ pub unsafe fn clear_hpm(index: usize) {
6196 assert ! ( ( 3 ..32 ) . contains( & index) ) ;
6297 _clear ( 1 << index) ;
6398}
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