2
2
3
3
use crate :: result:: { Error , Result } ;
4
4
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 ,
9
9
}
10
10
11
- impl Scounteren {
11
+ read_write_csr_field ! {
12
+ Scounteren ,
12
13
/// User "cycle\[h\]" Enable
13
- #[ inline]
14
- pub fn cy ( & self ) -> bool {
15
- self . bits & ( 1 << 0 ) != 0
16
- }
14
+ cy: 0 ,
15
+ }
17
16
17
+ read_write_csr_field ! {
18
+ Scounteren ,
18
19
/// User "time\[h\]" Enable
19
- #[ inline]
20
- pub fn tm ( & self ) -> bool {
21
- self . bits & ( 1 << 1 ) != 0
22
- }
20
+ tm: 1 ,
21
+ }
23
22
23
+ read_write_csr_field ! {
24
+ Scounteren ,
24
25
/// 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
+ }
36
28
29
+ read_write_csr_field ! {
30
+ Scounteren ,
37
31
/// 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 ,
52
33
}
53
34
54
- read_csr_as ! ( Scounteren , 0x106 ) ;
55
- write_csr ! ( 0x106 ) ;
56
35
set ! ( 0x106 ) ;
57
36
clear ! ( 0x106 ) ;
58
37
@@ -68,12 +47,17 @@ set_clear_csr!(
68
47
/// User instret Enable
69
48
, set_ir, clear_ir, 1 << 2 ) ;
70
49
50
+ /// Sets the "hpm\[x\]" enable (bits 3-31).
51
+ ///
52
+ /// # Note
53
+ ///
54
+ /// Panics if `index` is out-of-bounds.
71
55
#[ inline]
72
56
pub unsafe fn set_hpm ( index : usize ) {
73
- assert ! ( ( 3 ..32 ) . contains( & index) ) ;
74
- _set ( 1 << index) ;
57
+ try_set_hpm ( index) . unwrap ( ) ;
75
58
}
76
59
60
+ /// Attempts to set the "hpm\[x\]" enable (bits 3-31).
77
61
#[ inline]
78
62
pub unsafe fn try_set_hpm ( index : usize ) -> Result < ( ) > {
79
63
if ( 3 ..32 ) . contains ( & index) {
@@ -87,12 +71,17 @@ pub unsafe fn try_set_hpm(index: usize) -> Result<()> {
87
71
}
88
72
}
89
73
74
+ /// Clears the "hpm\[x\]" enable (bits 3-31).
75
+ ///
76
+ /// # Note
77
+ ///
78
+ /// Panics if `index` is out-of-bounds.
90
79
#[ inline]
91
80
pub unsafe fn clear_hpm ( index : usize ) {
92
- assert ! ( ( 3 ..32 ) . contains( & index) ) ;
93
- _clear ( 1 << index) ;
81
+ try_clear_hpm ( index) . unwrap ( )
94
82
}
95
83
84
+ /// Attempts to clear the "hpm\[x\]" enable (bits 3-31).
96
85
#[ inline]
97
86
pub unsafe fn try_clear_hpm ( index : usize ) -> Result < ( ) > {
98
87
if ( 3 ..32 ) . contains ( & index) {
@@ -105,3 +94,35 @@ pub unsafe fn try_clear_hpm(index: usize) -> Result<()> {
105
94
} )
106
95
}
107
96
}
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