Skip to content

Commit f37ab22

Browse files
committed
Implement hpmcounter*[h], mhpmcounter*[h], mhpmevent* CSRs
1 parent 298a8b6 commit f37ab22

File tree

5 files changed

+253
-4
lines changed

5 files changed

+253
-4
lines changed

src/register/hpmcounterx.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
macro_rules! reg {
2+
(
3+
$addr:expr, $csrl:ident, $csrh:ident, $readf:ident, $writef:ident
4+
) => {
5+
/// Performance-monitoring counter
6+
pub mod $csrl {
7+
read_csr_as_usize!($addr, $readf);
8+
read_composite_csr!(super::$csrh::read(), read());
9+
}
10+
}
11+
}
12+
13+
macro_rules! regh {
14+
(
15+
$addr:expr, $csrh:ident, $readf:ident, $writef:ident
16+
) => {
17+
/// Upper 32 bits of performance-monitoring counter (RV32I only)
18+
pub mod $csrh {
19+
read_csr_as_usize_rv32!($addr, $readf);
20+
}
21+
}
22+
}
23+
24+
reg!(0xC03, hpmcounter3, hpmcounter3h, __read_hpmcounter3, __write_hpmcounter3);
25+
reg!(0xC04, hpmcounter4, hpmcounter4h, __read_hpmcounter4, __write_hpmcounter4);
26+
reg!(0xC05, hpmcounter5, hpmcounter5h, __read_hpmcounter5, __write_hpmcounter5);
27+
reg!(0xC06, hpmcounter6, hpmcounter6h, __read_hpmcounter6, __write_hpmcounter6);
28+
reg!(0xC07, hpmcounter7, hpmcounter7h, __read_hpmcounter7, __write_hpmcounter7);
29+
reg!(0xC08, hpmcounter8, hpmcounter8h, __read_hpmcounter8, __write_hpmcounter8);
30+
reg!(0xC09, hpmcounter9, hpmcounter9h, __read_hpmcounter9, __write_hpmcounter9);
31+
reg!(0xC0A, hpmcounter10, hpmcounter10h, __read_hpmcounter10, __write_hpmcounter10);
32+
reg!(0xC0B, hpmcounter11, hpmcounter11h, __read_hpmcounter11, __write_hpmcounter11);
33+
reg!(0xC0C, hpmcounter12, hpmcounter12h, __read_hpmcounter12, __write_hpmcounter12);
34+
reg!(0xC0D, hpmcounter13, hpmcounter13h, __read_hpmcounter13, __write_hpmcounter13);
35+
reg!(0xC0E, hpmcounter14, hpmcounter14h, __read_hpmcounter14, __write_hpmcounter14);
36+
reg!(0xC0F, hpmcounter15, hpmcounter15h, __read_hpmcounter15, __write_hpmcounter15);
37+
reg!(0xC10, hpmcounter16, hpmcounter16h, __read_hpmcounter16, __write_hpmcounter16);
38+
reg!(0xC11, hpmcounter17, hpmcounter17h, __read_hpmcounter17, __write_hpmcounter17);
39+
reg!(0xC12, hpmcounter18, hpmcounter18h, __read_hpmcounter18, __write_hpmcounter18);
40+
reg!(0xC13, hpmcounter19, hpmcounter19h, __read_hpmcounter19, __write_hpmcounter19);
41+
reg!(0xC14, hpmcounter20, hpmcounter20h, __read_hpmcounter20, __write_hpmcounter20);
42+
reg!(0xC15, hpmcounter21, hpmcounter21h, __read_hpmcounter21, __write_hpmcounter21);
43+
reg!(0xC16, hpmcounter22, hpmcounter22h, __read_hpmcounter22, __write_hpmcounter22);
44+
reg!(0xC17, hpmcounter23, hpmcounter23h, __read_hpmcounter23, __write_hpmcounter23);
45+
reg!(0xC18, hpmcounter24, hpmcounter24h, __read_hpmcounter24, __write_hpmcounter24);
46+
reg!(0xC19, hpmcounter25, hpmcounter25h, __read_hpmcounter25, __write_hpmcounter25);
47+
reg!(0xC1A, hpmcounter26, hpmcounter26h, __read_hpmcounter26, __write_hpmcounter26);
48+
reg!(0xC1B, hpmcounter27, hpmcounter27h, __read_hpmcounter27, __write_hpmcounter27);
49+
reg!(0xC1C, hpmcounter28, hpmcounter28h, __read_hpmcounter28, __write_hpmcounter28);
50+
reg!(0xC1D, hpmcounter29, hpmcounter29h, __read_hpmcounter29, __write_hpmcounter29);
51+
reg!(0xC1E, hpmcounter30, hpmcounter30h, __read_hpmcounter30, __write_hpmcounter30);
52+
reg!(0xC1F, hpmcounter31, hpmcounter31h, __read_hpmcounter31, __write_hpmcounter31);
53+
54+
regh!(0xC83, hpmcounter3h, __read_hpmcounter3h, __write_hpmcounter3h);
55+
regh!(0xC84, hpmcounter4h, __read_hpmcounter4h, __write_hpmcounter4h);
56+
regh!(0xC85, hpmcounter5h, __read_hpmcounter5h, __write_hpmcounter5h);
57+
regh!(0xC86, hpmcounter6h, __read_hpmcounter6h, __write_hpmcounter6h);
58+
regh!(0xC87, hpmcounter7h, __read_hpmcounter7h, __write_hpmcounter7h);
59+
regh!(0xC88, hpmcounter8h, __read_hpmcounter8h, __write_hpmcounter8h);
60+
regh!(0xC89, hpmcounter9h, __read_hpmcounter9h, __write_hpmcounter9h);
61+
regh!(0xC8A, hpmcounter10h, __read_hpmcounter10h, __write_hpmcounter10h);
62+
regh!(0xC8B, hpmcounter11h, __read_hpmcounter11h, __write_hpmcounter11h);
63+
regh!(0xC8C, hpmcounter12h, __read_hpmcounter12h, __write_hpmcounter12h);
64+
regh!(0xC8D, hpmcounter13h, __read_hpmcounter13h, __write_hpmcounter13h);
65+
regh!(0xC8E, hpmcounter14h, __read_hpmcounter14h, __write_hpmcounter14h);
66+
regh!(0xC8F, hpmcounter15h, __read_hpmcounter15h, __write_hpmcounter15h);
67+
regh!(0xC90, hpmcounter16h, __read_hpmcounter16h, __write_hpmcounter16h);
68+
regh!(0xC91, hpmcounter17h, __read_hpmcounter17h, __write_hpmcounter17h);
69+
regh!(0xC92, hpmcounter18h, __read_hpmcounter18h, __write_hpmcounter18h);
70+
regh!(0xC93, hpmcounter19h, __read_hpmcounter19h, __write_hpmcounter19h);
71+
regh!(0xC94, hpmcounter20h, __read_hpmcounter20h, __write_hpmcounter20h);
72+
regh!(0xC95, hpmcounter21h, __read_hpmcounter21h, __write_hpmcounter21h);
73+
regh!(0xC96, hpmcounter22h, __read_hpmcounter22h, __write_hpmcounter22h);
74+
regh!(0xC97, hpmcounter23h, __read_hpmcounter23h, __write_hpmcounter23h);
75+
regh!(0xC98, hpmcounter24h, __read_hpmcounter24h, __write_hpmcounter24h);
76+
regh!(0xC99, hpmcounter25h, __read_hpmcounter25h, __write_hpmcounter25h);
77+
regh!(0xC9A, hpmcounter26h, __read_hpmcounter26h, __write_hpmcounter26h);
78+
regh!(0xC9B, hpmcounter27h, __read_hpmcounter27h, __write_hpmcounter27h);
79+
regh!(0xC9C, hpmcounter28h, __read_hpmcounter28h, __write_hpmcounter28h);
80+
regh!(0xC9D, hpmcounter29h, __read_hpmcounter29h, __write_hpmcounter29h);
81+
regh!(0xC9E, hpmcounter30h, __read_hpmcounter30h, __write_hpmcounter30h);
82+
regh!(0xC9F, hpmcounter31h, __read_hpmcounter31h, __write_hpmcounter31h);

src/register/macros.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,32 @@ macro_rules! write_csr {
118118
};
119119
}
120120

121+
macro_rules! write_csr_rv32 {
122+
($csr_number:expr, $asm_fn: ident) => {
123+
/// Writes the CSR
124+
#[inline]
125+
#[allow(unused_variables)]
126+
unsafe fn _write(bits: usize) {
127+
match () {
128+
#[cfg(all(riscv32, feature = "inline-asm"))]
129+
() => asm!("csrrw x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"),
130+
131+
#[cfg(all(riscv32, not(feature = "inline-asm")))]
132+
() => {
133+
extern "C" {
134+
fn $asm_fn(bits: usize);
135+
}
136+
137+
$asm_fn(bits);
138+
}
139+
140+
#[cfg(not(riscv32))]
141+
() => unimplemented!(),
142+
}
143+
}
144+
};
145+
}
146+
121147
macro_rules! write_csr_as_usize {
122148
($csr_number:expr, $asm_fn: ident) => {
123149
write_csr!($csr_number, $asm_fn);
@@ -130,6 +156,18 @@ macro_rules! write_csr_as_usize {
130156
};
131157
}
132158

159+
macro_rules! write_csr_as_usize_rv32 {
160+
($csr_number:expr, $asm_fn: ident) => {
161+
write_csr_rv32!($csr_number, $asm_fn);
162+
163+
/// Writes the CSR
164+
#[inline]
165+
pub fn write(bits: usize) {
166+
unsafe{ _write(bits) }
167+
}
168+
};
169+
}
170+
133171
macro_rules! set {
134172
($csr_number:expr, $asm_fn: ident) => {
135173
/// Set the CSR

src/register/mhpmcounterx.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
macro_rules! reg {
2+
(
3+
$addr:expr, $csrl:ident, $csrh:ident, $readf:ident, $writef:ident
4+
) => {
5+
/// Machine performance-monitoring counter
6+
pub mod $csrl {
7+
read_csr_as_usize!($addr, $readf);
8+
write_csr_as_usize!($addr, $writef);
9+
read_composite_csr!(super::$csrh::read(), read());
10+
}
11+
}
12+
}
13+
14+
macro_rules! regh {
15+
(
16+
$addr:expr, $csrh:ident, $readf:ident, $writef:ident
17+
) => {
18+
/// Upper 32 bits of machine performance-monitoring counter (RV32I only)
19+
pub mod $csrh {
20+
read_csr_as_usize_rv32!($addr, $readf);
21+
write_csr_as_usize_rv32!($addr, $writef);
22+
}
23+
}
24+
}
25+
26+
reg!(0xB03, mhpmcounter3, mhpmcounter3h, __read_mhpmcounter3, __write_mhpmcounter3);
27+
reg!(0xB04, mhpmcounter4, mhpmcounter4h, __read_mhpmcounter4, __write_mhpmcounter4);
28+
reg!(0xB05, mhpmcounter5, mhpmcounter5h, __read_mhpmcounter5, __write_mhpmcounter5);
29+
reg!(0xB06, mhpmcounter6, mhpmcounter6h, __read_mhpmcounter6, __write_mhpmcounter6);
30+
reg!(0xB07, mhpmcounter7, mhpmcounter7h, __read_mhpmcounter7, __write_mhpmcounter7);
31+
reg!(0xB08, mhpmcounter8, mhpmcounter8h, __read_mhpmcounter8, __write_mhpmcounter8);
32+
reg!(0xB09, mhpmcounter9, mhpmcounter9h, __read_mhpmcounter9, __write_mhpmcounter9);
33+
reg!(0xB0A, mhpmcounter10, mhpmcounter10h, __read_mhpmcounter10, __write_mhpmcounter10);
34+
reg!(0xB0B, mhpmcounter11, mhpmcounter11h, __read_mhpmcounter11, __write_mhpmcounter11);
35+
reg!(0xB0C, mhpmcounter12, mhpmcounter12h, __read_mhpmcounter12, __write_mhpmcounter12);
36+
reg!(0xB0D, mhpmcounter13, mhpmcounter13h, __read_mhpmcounter13, __write_mhpmcounter13);
37+
reg!(0xB0E, mhpmcounter14, mhpmcounter14h, __read_mhpmcounter14, __write_mhpmcounter14);
38+
reg!(0xB0F, mhpmcounter15, mhpmcounter15h, __read_mhpmcounter15, __write_mhpmcounter15);
39+
reg!(0xB10, mhpmcounter16, mhpmcounter16h, __read_mhpmcounter16, __write_mhpmcounter16);
40+
reg!(0xB11, mhpmcounter17, mhpmcounter17h, __read_mhpmcounter17, __write_mhpmcounter17);
41+
reg!(0xB12, mhpmcounter18, mhpmcounter18h, __read_mhpmcounter18, __write_mhpmcounter18);
42+
reg!(0xB13, mhpmcounter19, mhpmcounter19h, __read_mhpmcounter19, __write_mhpmcounter19);
43+
reg!(0xB14, mhpmcounter20, mhpmcounter20h, __read_mhpmcounter20, __write_mhpmcounter20);
44+
reg!(0xB15, mhpmcounter21, mhpmcounter21h, __read_mhpmcounter21, __write_mhpmcounter21);
45+
reg!(0xB16, mhpmcounter22, mhpmcounter22h, __read_mhpmcounter22, __write_mhpmcounter22);
46+
reg!(0xB17, mhpmcounter23, mhpmcounter23h, __read_mhpmcounter23, __write_mhpmcounter23);
47+
reg!(0xB18, mhpmcounter24, mhpmcounter24h, __read_mhpmcounter24, __write_mhpmcounter24);
48+
reg!(0xB19, mhpmcounter25, mhpmcounter25h, __read_mhpmcounter25, __write_mhpmcounter25);
49+
reg!(0xB1A, mhpmcounter26, mhpmcounter26h, __read_mhpmcounter26, __write_mhpmcounter26);
50+
reg!(0xB1B, mhpmcounter27, mhpmcounter27h, __read_mhpmcounter27, __write_mhpmcounter27);
51+
reg!(0xB1C, mhpmcounter28, mhpmcounter28h, __read_mhpmcounter28, __write_mhpmcounter28);
52+
reg!(0xB1D, mhpmcounter29, mhpmcounter29h, __read_mhpmcounter29, __write_mhpmcounter29);
53+
reg!(0xB1E, mhpmcounter30, mhpmcounter30h, __read_mhpmcounter30, __write_mhpmcounter30);
54+
reg!(0xB1F, mhpmcounter31, mhpmcounter31h, __read_mhpmcounter31, __write_mhpmcounter31);
55+
56+
regh!(0xB83, mhpmcounter3h, __read_mhpmcounter3h, __write_mhpmcounter3h);
57+
regh!(0xB84, mhpmcounter4h, __read_mhpmcounter4h, __write_mhpmcounter4h);
58+
regh!(0xB85, mhpmcounter5h, __read_mhpmcounter5h, __write_mhpmcounter5h);
59+
regh!(0xB86, mhpmcounter6h, __read_mhpmcounter6h, __write_mhpmcounter6h);
60+
regh!(0xB87, mhpmcounter7h, __read_mhpmcounter7h, __write_mhpmcounter7h);
61+
regh!(0xB88, mhpmcounter8h, __read_mhpmcounter8h, __write_mhpmcounter8h);
62+
regh!(0xB89, mhpmcounter9h, __read_mhpmcounter9h, __write_mhpmcounter9h);
63+
regh!(0xB8A, mhpmcounter10h, __read_mhpmcounter10h, __write_mhpmcounter10h);
64+
regh!(0xB8B, mhpmcounter11h, __read_mhpmcounter11h, __write_mhpmcounter11h);
65+
regh!(0xB8C, mhpmcounter12h, __read_mhpmcounter12h, __write_mhpmcounter12h);
66+
regh!(0xB8D, mhpmcounter13h, __read_mhpmcounter13h, __write_mhpmcounter13h);
67+
regh!(0xB8E, mhpmcounter14h, __read_mhpmcounter14h, __write_mhpmcounter14h);
68+
regh!(0xB8F, mhpmcounter15h, __read_mhpmcounter15h, __write_mhpmcounter15h);
69+
regh!(0xB90, mhpmcounter16h, __read_mhpmcounter16h, __write_mhpmcounter16h);
70+
regh!(0xB91, mhpmcounter17h, __read_mhpmcounter17h, __write_mhpmcounter17h);
71+
regh!(0xB92, mhpmcounter18h, __read_mhpmcounter18h, __write_mhpmcounter18h);
72+
regh!(0xB93, mhpmcounter19h, __read_mhpmcounter19h, __write_mhpmcounter19h);
73+
regh!(0xB94, mhpmcounter20h, __read_mhpmcounter20h, __write_mhpmcounter20h);
74+
regh!(0xB95, mhpmcounter21h, __read_mhpmcounter21h, __write_mhpmcounter21h);
75+
regh!(0xB96, mhpmcounter22h, __read_mhpmcounter22h, __write_mhpmcounter22h);
76+
regh!(0xB97, mhpmcounter23h, __read_mhpmcounter23h, __write_mhpmcounter23h);
77+
regh!(0xB98, mhpmcounter24h, __read_mhpmcounter24h, __write_mhpmcounter24h);
78+
regh!(0xB99, mhpmcounter25h, __read_mhpmcounter25h, __write_mhpmcounter25h);
79+
regh!(0xB9A, mhpmcounter26h, __read_mhpmcounter26h, __write_mhpmcounter26h);
80+
regh!(0xB9B, mhpmcounter27h, __read_mhpmcounter27h, __write_mhpmcounter27h);
81+
regh!(0xB9C, mhpmcounter28h, __read_mhpmcounter28h, __write_mhpmcounter28h);
82+
regh!(0xB9D, mhpmcounter29h, __read_mhpmcounter29h, __write_mhpmcounter29h);
83+
regh!(0xB9E, mhpmcounter30h, __read_mhpmcounter30h, __write_mhpmcounter30h);
84+
regh!(0xB9F, mhpmcounter31h, __read_mhpmcounter31h, __write_mhpmcounter31h);

src/register/mhpmeventx.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
macro_rules! reg {
2+
(
3+
$addr:expr, $csr:ident, $readf:ident, $writef:ident
4+
) => {
5+
/// Machine performance-monitoring event selector
6+
pub mod $csr {
7+
read_csr_as_usize!($addr, $readf);
8+
write_csr_as_usize!($addr, $writef);
9+
}
10+
}
11+
}
12+
13+
reg!(0x323, mhpmevent3, __read_mhpmevent3, __write_mhpmevent3);
14+
reg!(0x324, mhpmevent4, __read_mhpmevent4, __write_mhpmevent4);
15+
reg!(0x325, mhpmevent5, __read_mhpmevent5, __write_mhpmevent5);
16+
reg!(0x326, mhpmevent6, __read_mhpmevent6, __write_mhpmevent6);
17+
reg!(0x327, mhpmevent7, __read_mhpmevent7, __write_mhpmevent7);
18+
reg!(0x328, mhpmevent8, __read_mhpmevent8, __write_mhpmevent8);
19+
reg!(0x329, mhpmevent9, __read_mhpmevent9, __write_mhpmevent9);
20+
reg!(0x32A, mhpmevent10, __read_mhpmevent10, __write_mhpmevent10);
21+
reg!(0x32B, mhpmevent11, __read_mhpmevent11, __write_mhpmevent11);
22+
reg!(0x32C, mhpmevent12, __read_mhpmevent12, __write_mhpmevent12);
23+
reg!(0x32D, mhpmevent13, __read_mhpmevent13, __write_mhpmevent13);
24+
reg!(0x32E, mhpmevent14, __read_mhpmevent14, __write_mhpmevent14);
25+
reg!(0x32F, mhpmevent15, __read_mhpmevent15, __write_mhpmevent15);
26+
reg!(0x330, mhpmevent16, __read_mhpmevent16, __write_mhpmevent16);
27+
reg!(0x331, mhpmevent17, __read_mhpmevent17, __write_mhpmevent17);
28+
reg!(0x332, mhpmevent18, __read_mhpmevent18, __write_mhpmevent18);
29+
reg!(0x333, mhpmevent19, __read_mhpmevent19, __write_mhpmevent19);
30+
reg!(0x334, mhpmevent20, __read_mhpmevent20, __write_mhpmevent20);
31+
reg!(0x335, mhpmevent21, __read_mhpmevent21, __write_mhpmevent21);
32+
reg!(0x336, mhpmevent22, __read_mhpmevent22, __write_mhpmevent22);
33+
reg!(0x337, mhpmevent23, __read_mhpmevent23, __write_mhpmevent23);
34+
reg!(0x338, mhpmevent24, __read_mhpmevent24, __write_mhpmevent24);
35+
reg!(0x339, mhpmevent25, __read_mhpmevent25, __write_mhpmevent25);
36+
reg!(0x33A, mhpmevent26, __read_mhpmevent26, __write_mhpmevent26);
37+
reg!(0x33B, mhpmevent27, __read_mhpmevent27, __write_mhpmevent27);
38+
reg!(0x33C, mhpmevent28, __read_mhpmevent28, __write_mhpmevent28);
39+
reg!(0x33D, mhpmevent29, __read_mhpmevent29, __write_mhpmevent29);
40+
reg!(0x33E, mhpmevent30, __read_mhpmevent30, __write_mhpmevent30);
41+
reg!(0x33F, mhpmevent31, __read_mhpmevent31, __write_mhpmevent31);

src/register/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ pub mod fcsr;
2525

2626

2727
// User Counter/Timers
28-
// TODO: cycle[h], instret[h], hpmcounter*[h]
28+
// TODO: cycle[h], instret[h]
2929
pub mod time;
30+
mod hpmcounterx;
31+
pub use self::hpmcounterx::*;
3032
pub mod timeh;
3133

3234

@@ -79,13 +81,15 @@ pub mod mip;
7981
// Machine Counter/Timers
8082
pub mod mcycle;
8183
pub mod minstret;
82-
// TODO: mhpmcounter*
84+
mod mhpmcounterx;
85+
pub use self::mhpmcounterx::*;
8386
pub mod mcycleh;
8487
pub mod minstreth;
85-
// TODO: mhpmcounter*h
8688

8789

88-
// TODO: Machine Counter Setup
90+
// Machine Counter Setup
91+
mod mhpmeventx;
92+
pub use self::mhpmeventx::*;
8993

9094

9195
// TODO: Debug/Trace Registers (shared with Debug Mode)

0 commit comments

Comments
 (0)