22
33use crate :: result:: { Error , Result } ;
44
5- /// scounteren register
6- # [ derive ( Clone , Copy , Debug ) ]
7- pub struct Scounteren {
8- bits : usize ,
5+ read_write_csr ! {
6+ /// scounteren register
7+ Scounteren : 0x106 ,
8+ mask : 0xffff_ffff ,
99}
1010
11- impl Scounteren {
11+ read_write_csr_field ! {
12+ Scounteren ,
1213 /// User "cycle\[h\]" Enable
13- #[ inline]
14- pub fn cy ( & self ) -> bool {
15- self . bits & ( 1 << 0 ) != 0
16- }
14+ cy: 0 ,
15+ }
1716
17+ read_write_csr_field ! {
18+ Scounteren ,
1819 /// User "time\[h\]" Enable
19- #[ inline]
20- pub fn tm ( & self ) -> bool {
21- self . bits & ( 1 << 1 ) != 0
22- }
20+ tm: 1 ,
21+ }
2322
23+ read_write_csr_field ! {
24+ Scounteren ,
2425 /// User "instret\[h]\" Enable
25- #[ inline]
26- pub fn ir ( & self ) -> bool {
27- self . bits & ( 1 << 2 ) != 0
28- }
29-
30- /// User "hpm\[x\]" Enable (bits 3-31)
31- #[ inline]
32- pub fn hpm ( & self , index : usize ) -> bool {
33- assert ! ( ( 3 ..32 ) . contains( & index) ) ;
34- self . bits & ( 1 << index) != 0
35- }
26+ ir: 2 ,
27+ }
3628
29+ read_write_csr_field ! {
30+ Scounteren ,
3731 /// User "hpm\[x\]" Enable (bits 3-31)
38- ///
39- /// Attempts to read the "hpm\[x\]" value, and returns an error if the index is invalid.
40- #[ inline]
41- pub fn try_hpm ( & self , index : usize ) -> Result < bool > {
42- if ( 3 ..32 ) . contains ( & index) {
43- Ok ( self . bits & ( 1 << index) != 0 )
44- } else {
45- Err ( Error :: IndexOutOfBounds {
46- index,
47- min : 3 ,
48- max : 31 ,
49- } )
50- }
51- }
32+ hpm: 3 ..=31 ,
5233}
5334
54- read_csr_as ! ( Scounteren , 0x106 ) ;
55- write_csr ! ( 0x106 ) ;
5635set ! ( 0x106 ) ;
5736clear ! ( 0x106 ) ;
5837
@@ -68,12 +47,17 @@ set_clear_csr!(
6847/// User instret Enable
6948 , set_ir, clear_ir, 1 << 2 ) ;
7049
50+ /// Sets the "hpm\[x\]" enable (bits 3-31).
51+ ///
52+ /// # Note
53+ ///
54+ /// Panics if `index` is out-of-bounds.
7155#[ inline]
7256pub unsafe fn set_hpm ( index : usize ) {
73- assert ! ( ( 3 ..32 ) . contains( & index) ) ;
74- _set ( 1 << index) ;
57+ try_set_hpm ( index) . unwrap ( ) ;
7558}
7659
60+ /// Attempts to set the "hpm\[x\]" enable (bits 3-31).
7761#[ inline]
7862pub unsafe fn try_set_hpm ( index : usize ) -> Result < ( ) > {
7963 if ( 3 ..32 ) . contains ( & index) {
@@ -87,12 +71,17 @@ pub unsafe fn try_set_hpm(index: usize) -> Result<()> {
8771 }
8872}
8973
74+ /// Clears the "hpm\[x\]" enable (bits 3-31).
75+ ///
76+ /// # Note
77+ ///
78+ /// Panics if `index` is out-of-bounds.
9079#[ inline]
9180pub unsafe fn clear_hpm ( index : usize ) {
92- assert ! ( ( 3 ..32 ) . contains( & index) ) ;
93- _clear ( 1 << index) ;
81+ try_clear_hpm ( index) . unwrap ( )
9482}
9583
84+ /// Attempts to clear the "hpm\[x\]" enable (bits 3-31).
9685#[ inline]
9786pub unsafe fn try_clear_hpm ( index : usize ) -> Result < ( ) > {
9887 if ( 3 ..32 ) . contains ( & index) {
@@ -105,3 +94,35 @@ pub unsafe fn try_clear_hpm(index: usize) -> Result<()> {
10594 } )
10695 }
10796}
97+
98+ #[ cfg( test) ]
99+ mod tests {
100+ use super :: * ;
101+
102+ #[ test]
103+ fn test_scounteren ( ) {
104+ const HPM_MIN : usize = 3 ;
105+ const HPM_MAX : usize = 31 ;
106+
107+ let mut scounteren = Scounteren :: from_bits ( 0 ) ;
108+
109+ test_csr_field ! ( scounteren, cy) ;
110+ test_csr_field ! ( scounteren, tm) ;
111+ test_csr_field ! ( scounteren, ir) ;
112+
113+ ( HPM_MIN ..=HPM_MAX ) . for_each ( |index| {
114+ test_csr_field ! ( scounteren, hpm, index) ;
115+ } ) ;
116+
117+ ( 0 ..usize:: BITS as usize )
118+ . filter ( |& i| !( HPM_MIN ..=HPM_MAX ) . any ( |idx| idx == i) )
119+ . for_each ( |index| {
120+ let err = Error :: IndexOutOfBounds {
121+ index,
122+ min : 3 ,
123+ max : 31 ,
124+ } ;
125+ test_csr_field ! ( scounteren, hpm, index, err)
126+ } ) ;
127+ }
128+ }
0 commit comments