瀏覽代碼

Merge #57

57: Add mcounteren.rs, cycle[h].rs, instret[h].rs, and update mod.rs r=Disasm a=dkhayes117

I'm not sure the set_clear_csr!() macros are correct in mcounteren.rs.  I get a build error that says `cannot find function `_clear` in this scope`

Co-authored-by: dkhayes117 <dkhayes117@yahoo.com>
bors[bot] 4 年之前
父節點
當前提交
4145e4aca0

+ 7 - 0
src/register/cycle.rs

@@ -0,0 +1,7 @@
+//! cycle register
+//! Shadow of mcycle register
+//! must have `scounteren::cy` or `mcounteren::cy` bit enabled depending on whether
+//! S-mode is implemented or not
+
+read_csr_as_usize!(0xC00, __read_cycle);
+read_composite_csr!(super::cycleh::read(), read());

+ 6 - 0
src/register/cycleh.rs

@@ -0,0 +1,6 @@
+//! cycleh register
+//! Shadow of mcycleh register (rv32)
+//! must have `scounteren::cy` or `mcounteren::cy` bit enabled depending on whether
+//! S-mode is implemented or not
+
+read_csr_as_usize_rv32!(0xC80, __read_cycleh);

+ 379 - 60
src/register/hpmcounterx.rs

@@ -7,7 +7,7 @@ macro_rules! reg {
             read_csr_as_usize!($addr, $readf);
             read_composite_csr!(super::$csrh::read(), read());
         }
-    }
+    };
 }
 
 macro_rules! regh {
@@ -18,65 +18,384 @@ macro_rules! regh {
         pub mod $csrh {
             read_csr_as_usize_rv32!($addr, $readf);
         }
-    }
+    };
 }
 
-reg!(0xC03, hpmcounter3,  hpmcounter3h,  __read_hpmcounter3,  __write_hpmcounter3);
-reg!(0xC04, hpmcounter4,  hpmcounter4h,  __read_hpmcounter4,  __write_hpmcounter4);
-reg!(0xC05, hpmcounter5,  hpmcounter5h,  __read_hpmcounter5,  __write_hpmcounter5);
-reg!(0xC06, hpmcounter6,  hpmcounter6h,  __read_hpmcounter6,  __write_hpmcounter6);
-reg!(0xC07, hpmcounter7,  hpmcounter7h,  __read_hpmcounter7,  __write_hpmcounter7);
-reg!(0xC08, hpmcounter8,  hpmcounter8h,  __read_hpmcounter8,  __write_hpmcounter8);
-reg!(0xC09, hpmcounter9,  hpmcounter9h,  __read_hpmcounter9,  __write_hpmcounter9);
-reg!(0xC0A, hpmcounter10, hpmcounter10h, __read_hpmcounter10, __write_hpmcounter10);
-reg!(0xC0B, hpmcounter11, hpmcounter11h, __read_hpmcounter11, __write_hpmcounter11);
-reg!(0xC0C, hpmcounter12, hpmcounter12h, __read_hpmcounter12, __write_hpmcounter12);
-reg!(0xC0D, hpmcounter13, hpmcounter13h, __read_hpmcounter13, __write_hpmcounter13);
-reg!(0xC0E, hpmcounter14, hpmcounter14h, __read_hpmcounter14, __write_hpmcounter14);
-reg!(0xC0F, hpmcounter15, hpmcounter15h, __read_hpmcounter15, __write_hpmcounter15);
-reg!(0xC10, hpmcounter16, hpmcounter16h, __read_hpmcounter16, __write_hpmcounter16);
-reg!(0xC11, hpmcounter17, hpmcounter17h, __read_hpmcounter17, __write_hpmcounter17);
-reg!(0xC12, hpmcounter18, hpmcounter18h, __read_hpmcounter18, __write_hpmcounter18);
-reg!(0xC13, hpmcounter19, hpmcounter19h, __read_hpmcounter19, __write_hpmcounter19);
-reg!(0xC14, hpmcounter20, hpmcounter20h, __read_hpmcounter20, __write_hpmcounter20);
-reg!(0xC15, hpmcounter21, hpmcounter21h, __read_hpmcounter21, __write_hpmcounter21);
-reg!(0xC16, hpmcounter22, hpmcounter22h, __read_hpmcounter22, __write_hpmcounter22);
-reg!(0xC17, hpmcounter23, hpmcounter23h, __read_hpmcounter23, __write_hpmcounter23);
-reg!(0xC18, hpmcounter24, hpmcounter24h, __read_hpmcounter24, __write_hpmcounter24);
-reg!(0xC19, hpmcounter25, hpmcounter25h, __read_hpmcounter25, __write_hpmcounter25);
-reg!(0xC1A, hpmcounter26, hpmcounter26h, __read_hpmcounter26, __write_hpmcounter26);
-reg!(0xC1B, hpmcounter27, hpmcounter27h, __read_hpmcounter27, __write_hpmcounter27);
-reg!(0xC1C, hpmcounter28, hpmcounter28h, __read_hpmcounter28, __write_hpmcounter28);
-reg!(0xC1D, hpmcounter29, hpmcounter29h, __read_hpmcounter29, __write_hpmcounter29);
-reg!(0xC1E, hpmcounter30, hpmcounter30h, __read_hpmcounter30, __write_hpmcounter30);
-reg!(0xC1F, hpmcounter31, hpmcounter31h, __read_hpmcounter31, __write_hpmcounter31);
+reg!(
+    0xC03,
+    hpmcounter3,
+    hpmcounter3h,
+    __read_hpmcounter3,
+    __write_hpmcounter3
+);
+reg!(
+    0xC04,
+    hpmcounter4,
+    hpmcounter4h,
+    __read_hpmcounter4,
+    __write_hpmcounter4
+);
+reg!(
+    0xC05,
+    hpmcounter5,
+    hpmcounter5h,
+    __read_hpmcounter5,
+    __write_hpmcounter5
+);
+reg!(
+    0xC06,
+    hpmcounter6,
+    hpmcounter6h,
+    __read_hpmcounter6,
+    __write_hpmcounter6
+);
+reg!(
+    0xC07,
+    hpmcounter7,
+    hpmcounter7h,
+    __read_hpmcounter7,
+    __write_hpmcounter7
+);
+reg!(
+    0xC08,
+    hpmcounter8,
+    hpmcounter8h,
+    __read_hpmcounter8,
+    __write_hpmcounter8
+);
+reg!(
+    0xC09,
+    hpmcounter9,
+    hpmcounter9h,
+    __read_hpmcounter9,
+    __write_hpmcounter9
+);
+reg!(
+    0xC0A,
+    hpmcounter10,
+    hpmcounter10h,
+    __read_hpmcounter10,
+    __write_hpmcounter10
+);
+reg!(
+    0xC0B,
+    hpmcounter11,
+    hpmcounter11h,
+    __read_hpmcounter11,
+    __write_hpmcounter11
+);
+reg!(
+    0xC0C,
+    hpmcounter12,
+    hpmcounter12h,
+    __read_hpmcounter12,
+    __write_hpmcounter12
+);
+reg!(
+    0xC0D,
+    hpmcounter13,
+    hpmcounter13h,
+    __read_hpmcounter13,
+    __write_hpmcounter13
+);
+reg!(
+    0xC0E,
+    hpmcounter14,
+    hpmcounter14h,
+    __read_hpmcounter14,
+    __write_hpmcounter14
+);
+reg!(
+    0xC0F,
+    hpmcounter15,
+    hpmcounter15h,
+    __read_hpmcounter15,
+    __write_hpmcounter15
+);
+reg!(
+    0xC10,
+    hpmcounter16,
+    hpmcounter16h,
+    __read_hpmcounter16,
+    __write_hpmcounter16
+);
+reg!(
+    0xC11,
+    hpmcounter17,
+    hpmcounter17h,
+    __read_hpmcounter17,
+    __write_hpmcounter17
+);
+reg!(
+    0xC12,
+    hpmcounter18,
+    hpmcounter18h,
+    __read_hpmcounter18,
+    __write_hpmcounter18
+);
+reg!(
+    0xC13,
+    hpmcounter19,
+    hpmcounter19h,
+    __read_hpmcounter19,
+    __write_hpmcounter19
+);
+reg!(
+    0xC14,
+    hpmcounter20,
+    hpmcounter20h,
+    __read_hpmcounter20,
+    __write_hpmcounter20
+);
+reg!(
+    0xC15,
+    hpmcounter21,
+    hpmcounter21h,
+    __read_hpmcounter21,
+    __write_hpmcounter21
+);
+reg!(
+    0xC16,
+    hpmcounter22,
+    hpmcounter22h,
+    __read_hpmcounter22,
+    __write_hpmcounter22
+);
+reg!(
+    0xC17,
+    hpmcounter23,
+    hpmcounter23h,
+    __read_hpmcounter23,
+    __write_hpmcounter23
+);
+reg!(
+    0xC18,
+    hpmcounter24,
+    hpmcounter24h,
+    __read_hpmcounter24,
+    __write_hpmcounter24
+);
+reg!(
+    0xC19,
+    hpmcounter25,
+    hpmcounter25h,
+    __read_hpmcounter25,
+    __write_hpmcounter25
+);
+reg!(
+    0xC1A,
+    hpmcounter26,
+    hpmcounter26h,
+    __read_hpmcounter26,
+    __write_hpmcounter26
+);
+reg!(
+    0xC1B,
+    hpmcounter27,
+    hpmcounter27h,
+    __read_hpmcounter27,
+    __write_hpmcounter27
+);
+reg!(
+    0xC1C,
+    hpmcounter28,
+    hpmcounter28h,
+    __read_hpmcounter28,
+    __write_hpmcounter28
+);
+reg!(
+    0xC1D,
+    hpmcounter29,
+    hpmcounter29h,
+    __read_hpmcounter29,
+    __write_hpmcounter29
+);
+reg!(
+    0xC1E,
+    hpmcounter30,
+    hpmcounter30h,
+    __read_hpmcounter30,
+    __write_hpmcounter30
+);
+reg!(
+    0xC1F,
+    hpmcounter31,
+    hpmcounter31h,
+    __read_hpmcounter31,
+    __write_hpmcounter31
+);
 
-regh!(0xC83, hpmcounter3h,  __read_hpmcounter3h,  __write_hpmcounter3h);
-regh!(0xC84, hpmcounter4h,  __read_hpmcounter4h,  __write_hpmcounter4h);
-regh!(0xC85, hpmcounter5h,  __read_hpmcounter5h,  __write_hpmcounter5h);
-regh!(0xC86, hpmcounter6h,  __read_hpmcounter6h,  __write_hpmcounter6h);
-regh!(0xC87, hpmcounter7h,  __read_hpmcounter7h,  __write_hpmcounter7h);
-regh!(0xC88, hpmcounter8h,  __read_hpmcounter8h,  __write_hpmcounter8h);
-regh!(0xC89, hpmcounter9h,  __read_hpmcounter9h,  __write_hpmcounter9h);
-regh!(0xC8A, hpmcounter10h, __read_hpmcounter10h, __write_hpmcounter10h);
-regh!(0xC8B, hpmcounter11h, __read_hpmcounter11h, __write_hpmcounter11h);
-regh!(0xC8C, hpmcounter12h, __read_hpmcounter12h, __write_hpmcounter12h);
-regh!(0xC8D, hpmcounter13h, __read_hpmcounter13h, __write_hpmcounter13h);
-regh!(0xC8E, hpmcounter14h, __read_hpmcounter14h, __write_hpmcounter14h);
-regh!(0xC8F, hpmcounter15h, __read_hpmcounter15h, __write_hpmcounter15h);
-regh!(0xC90, hpmcounter16h, __read_hpmcounter16h, __write_hpmcounter16h);
-regh!(0xC91, hpmcounter17h, __read_hpmcounter17h, __write_hpmcounter17h);
-regh!(0xC92, hpmcounter18h, __read_hpmcounter18h, __write_hpmcounter18h);
-regh!(0xC93, hpmcounter19h, __read_hpmcounter19h, __write_hpmcounter19h);
-regh!(0xC94, hpmcounter20h, __read_hpmcounter20h, __write_hpmcounter20h);
-regh!(0xC95, hpmcounter21h, __read_hpmcounter21h, __write_hpmcounter21h);
-regh!(0xC96, hpmcounter22h, __read_hpmcounter22h, __write_hpmcounter22h);
-regh!(0xC97, hpmcounter23h, __read_hpmcounter23h, __write_hpmcounter23h);
-regh!(0xC98, hpmcounter24h, __read_hpmcounter24h, __write_hpmcounter24h);
-regh!(0xC99, hpmcounter25h, __read_hpmcounter25h, __write_hpmcounter25h);
-regh!(0xC9A, hpmcounter26h, __read_hpmcounter26h, __write_hpmcounter26h);
-regh!(0xC9B, hpmcounter27h, __read_hpmcounter27h, __write_hpmcounter27h);
-regh!(0xC9C, hpmcounter28h, __read_hpmcounter28h, __write_hpmcounter28h);
-regh!(0xC9D, hpmcounter29h, __read_hpmcounter29h, __write_hpmcounter29h);
-regh!(0xC9E, hpmcounter30h, __read_hpmcounter30h, __write_hpmcounter30h);
-regh!(0xC9F, hpmcounter31h, __read_hpmcounter31h, __write_hpmcounter31h);
+regh!(
+    0xC83,
+    hpmcounter3h,
+    __read_hpmcounter3h,
+    __write_hpmcounter3h
+);
+regh!(
+    0xC84,
+    hpmcounter4h,
+    __read_hpmcounter4h,
+    __write_hpmcounter4h
+);
+regh!(
+    0xC85,
+    hpmcounter5h,
+    __read_hpmcounter5h,
+    __write_hpmcounter5h
+);
+regh!(
+    0xC86,
+    hpmcounter6h,
+    __read_hpmcounter6h,
+    __write_hpmcounter6h
+);
+regh!(
+    0xC87,
+    hpmcounter7h,
+    __read_hpmcounter7h,
+    __write_hpmcounter7h
+);
+regh!(
+    0xC88,
+    hpmcounter8h,
+    __read_hpmcounter8h,
+    __write_hpmcounter8h
+);
+regh!(
+    0xC89,
+    hpmcounter9h,
+    __read_hpmcounter9h,
+    __write_hpmcounter9h
+);
+regh!(
+    0xC8A,
+    hpmcounter10h,
+    __read_hpmcounter10h,
+    __write_hpmcounter10h
+);
+regh!(
+    0xC8B,
+    hpmcounter11h,
+    __read_hpmcounter11h,
+    __write_hpmcounter11h
+);
+regh!(
+    0xC8C,
+    hpmcounter12h,
+    __read_hpmcounter12h,
+    __write_hpmcounter12h
+);
+regh!(
+    0xC8D,
+    hpmcounter13h,
+    __read_hpmcounter13h,
+    __write_hpmcounter13h
+);
+regh!(
+    0xC8E,
+    hpmcounter14h,
+    __read_hpmcounter14h,
+    __write_hpmcounter14h
+);
+regh!(
+    0xC8F,
+    hpmcounter15h,
+    __read_hpmcounter15h,
+    __write_hpmcounter15h
+);
+regh!(
+    0xC90,
+    hpmcounter16h,
+    __read_hpmcounter16h,
+    __write_hpmcounter16h
+);
+regh!(
+    0xC91,
+    hpmcounter17h,
+    __read_hpmcounter17h,
+    __write_hpmcounter17h
+);
+regh!(
+    0xC92,
+    hpmcounter18h,
+    __read_hpmcounter18h,
+    __write_hpmcounter18h
+);
+regh!(
+    0xC93,
+    hpmcounter19h,
+    __read_hpmcounter19h,
+    __write_hpmcounter19h
+);
+regh!(
+    0xC94,
+    hpmcounter20h,
+    __read_hpmcounter20h,
+    __write_hpmcounter20h
+);
+regh!(
+    0xC95,
+    hpmcounter21h,
+    __read_hpmcounter21h,
+    __write_hpmcounter21h
+);
+regh!(
+    0xC96,
+    hpmcounter22h,
+    __read_hpmcounter22h,
+    __write_hpmcounter22h
+);
+regh!(
+    0xC97,
+    hpmcounter23h,
+    __read_hpmcounter23h,
+    __write_hpmcounter23h
+);
+regh!(
+    0xC98,
+    hpmcounter24h,
+    __read_hpmcounter24h,
+    __write_hpmcounter24h
+);
+regh!(
+    0xC99,
+    hpmcounter25h,
+    __read_hpmcounter25h,
+    __write_hpmcounter25h
+);
+regh!(
+    0xC9A,
+    hpmcounter26h,
+    __read_hpmcounter26h,
+    __write_hpmcounter26h
+);
+regh!(
+    0xC9B,
+    hpmcounter27h,
+    __read_hpmcounter27h,
+    __write_hpmcounter27h
+);
+regh!(
+    0xC9C,
+    hpmcounter28h,
+    __read_hpmcounter28h,
+    __write_hpmcounter28h
+);
+regh!(
+    0xC9D,
+    hpmcounter29h,
+    __read_hpmcounter29h,
+    __write_hpmcounter29h
+);
+regh!(
+    0xC9E,
+    hpmcounter30h,
+    __read_hpmcounter30h,
+    __write_hpmcounter30h
+);
+regh!(
+    0xC9F,
+    hpmcounter31h,
+    __read_hpmcounter31h,
+    __write_hpmcounter31h
+);

+ 7 - 0
src/register/instret.rs

@@ -0,0 +1,7 @@
+//! instret register
+//! Shadow of minstret register
+//! must have `scounteren::ir` or `mcounteren::ir` bit enabled depending on whether
+//! S-mode is implemented or not
+
+read_csr_as_usize!(0xC02, __read_instret);
+read_composite_csr!(super::instreth::read(), read());

+ 6 - 0
src/register/instreth.rs

@@ -0,0 +1,6 @@
+//! instreth register
+//! Shadow of minstreth register (rv32)
+//! must have `scounteren::ir` or `mcounteren::ir` bit enabled depending on whether
+//! S-mode is implemented or not
+
+read_csr_as_usize!(0xC82, __read_instreth);

+ 65 - 0
src/register/mcounteren.rs

@@ -0,0 +1,65 @@
+//! mcounteren register
+
+use bit_field::BitField;
+
+/// mcounteren register
+#[derive(Clone, Copy, Debug)]
+pub struct Mcounteren {
+    bits: usize,
+}
+
+impl Mcounteren {
+    /// Supervisor "cycle[h]" Enable
+    #[inline]
+    pub fn cy(&self) -> bool {
+        self.bits.get_bit(0)
+    }
+
+    /// Supervisor "time[h]" Enable
+    #[inline]
+    pub fn tm(&self) -> bool {
+        self.bits.get_bit(1)
+    }
+
+    /// Supervisor "instret[h]" Enable
+    #[inline]
+    pub fn ir(&self) -> bool {
+        self.bits.get_bit(2)
+    }
+
+    /// Supervisor "hpm[x]" Enable (bits 3-31)
+    #[inline]
+    pub fn hpm(&self, index: usize) -> bool {
+        assert!(3 <= index && index < 32);
+        self.bits.get_bit(index)
+    }
+}
+
+read_csr_as!(Mcounteren, 0x306, __read_mcounteren);
+write_csr!(0x306, __write_mcounteren);
+set!(0x306, __set_mcounteren);
+clear!(0x306, __clear_mcounteren);
+
+set_clear_csr!(
+/// Supervisor cycle Enable
+    , set_cy, clear_cy, 1 << 0);
+
+set_clear_csr!(
+/// Supervisor time Enable
+    , set_tm, clear_tm, 1 << 1);
+
+set_clear_csr!(
+/// Supervisor instret Enable
+    , set_ir, clear_ir, 1 << 2);
+
+#[inline]
+pub unsafe fn set_hpm(index: usize) {
+    assert!(3 <= index && index < 32);
+    _set(1 << index);
+}
+
+#[inline]
+pub unsafe fn clear_hpm(index: usize) {
+    assert!(3 <= index && index < 32);
+    _clear(1 << index);
+}

+ 379 - 60
src/register/mhpmcounterx.rs

@@ -8,7 +8,7 @@ macro_rules! reg {
             write_csr_as_usize!($addr, $writef);
             read_composite_csr!(super::$csrh::read(), read());
         }
-    }
+    };
 }
 
 macro_rules! regh {
@@ -20,65 +20,384 @@ macro_rules! regh {
             read_csr_as_usize_rv32!($addr, $readf);
             write_csr_as_usize_rv32!($addr, $writef);
         }
-    }
+    };
 }
 
-reg!(0xB03, mhpmcounter3,  mhpmcounter3h,  __read_mhpmcounter3,  __write_mhpmcounter3);
-reg!(0xB04, mhpmcounter4,  mhpmcounter4h,  __read_mhpmcounter4,  __write_mhpmcounter4);
-reg!(0xB05, mhpmcounter5,  mhpmcounter5h,  __read_mhpmcounter5,  __write_mhpmcounter5);
-reg!(0xB06, mhpmcounter6,  mhpmcounter6h,  __read_mhpmcounter6,  __write_mhpmcounter6);
-reg!(0xB07, mhpmcounter7,  mhpmcounter7h,  __read_mhpmcounter7,  __write_mhpmcounter7);
-reg!(0xB08, mhpmcounter8,  mhpmcounter8h,  __read_mhpmcounter8,  __write_mhpmcounter8);
-reg!(0xB09, mhpmcounter9,  mhpmcounter9h,  __read_mhpmcounter9,  __write_mhpmcounter9);
-reg!(0xB0A, mhpmcounter10, mhpmcounter10h, __read_mhpmcounter10, __write_mhpmcounter10);
-reg!(0xB0B, mhpmcounter11, mhpmcounter11h, __read_mhpmcounter11, __write_mhpmcounter11);
-reg!(0xB0C, mhpmcounter12, mhpmcounter12h, __read_mhpmcounter12, __write_mhpmcounter12);
-reg!(0xB0D, mhpmcounter13, mhpmcounter13h, __read_mhpmcounter13, __write_mhpmcounter13);
-reg!(0xB0E, mhpmcounter14, mhpmcounter14h, __read_mhpmcounter14, __write_mhpmcounter14);
-reg!(0xB0F, mhpmcounter15, mhpmcounter15h, __read_mhpmcounter15, __write_mhpmcounter15);
-reg!(0xB10, mhpmcounter16, mhpmcounter16h, __read_mhpmcounter16, __write_mhpmcounter16);
-reg!(0xB11, mhpmcounter17, mhpmcounter17h, __read_mhpmcounter17, __write_mhpmcounter17);
-reg!(0xB12, mhpmcounter18, mhpmcounter18h, __read_mhpmcounter18, __write_mhpmcounter18);
-reg!(0xB13, mhpmcounter19, mhpmcounter19h, __read_mhpmcounter19, __write_mhpmcounter19);
-reg!(0xB14, mhpmcounter20, mhpmcounter20h, __read_mhpmcounter20, __write_mhpmcounter20);
-reg!(0xB15, mhpmcounter21, mhpmcounter21h, __read_mhpmcounter21, __write_mhpmcounter21);
-reg!(0xB16, mhpmcounter22, mhpmcounter22h, __read_mhpmcounter22, __write_mhpmcounter22);
-reg!(0xB17, mhpmcounter23, mhpmcounter23h, __read_mhpmcounter23, __write_mhpmcounter23);
-reg!(0xB18, mhpmcounter24, mhpmcounter24h, __read_mhpmcounter24, __write_mhpmcounter24);
-reg!(0xB19, mhpmcounter25, mhpmcounter25h, __read_mhpmcounter25, __write_mhpmcounter25);
-reg!(0xB1A, mhpmcounter26, mhpmcounter26h, __read_mhpmcounter26, __write_mhpmcounter26);
-reg!(0xB1B, mhpmcounter27, mhpmcounter27h, __read_mhpmcounter27, __write_mhpmcounter27);
-reg!(0xB1C, mhpmcounter28, mhpmcounter28h, __read_mhpmcounter28, __write_mhpmcounter28);
-reg!(0xB1D, mhpmcounter29, mhpmcounter29h, __read_mhpmcounter29, __write_mhpmcounter29);
-reg!(0xB1E, mhpmcounter30, mhpmcounter30h, __read_mhpmcounter30, __write_mhpmcounter30);
-reg!(0xB1F, mhpmcounter31, mhpmcounter31h, __read_mhpmcounter31, __write_mhpmcounter31);
+reg!(
+    0xB03,
+    mhpmcounter3,
+    mhpmcounter3h,
+    __read_mhpmcounter3,
+    __write_mhpmcounter3
+);
+reg!(
+    0xB04,
+    mhpmcounter4,
+    mhpmcounter4h,
+    __read_mhpmcounter4,
+    __write_mhpmcounter4
+);
+reg!(
+    0xB05,
+    mhpmcounter5,
+    mhpmcounter5h,
+    __read_mhpmcounter5,
+    __write_mhpmcounter5
+);
+reg!(
+    0xB06,
+    mhpmcounter6,
+    mhpmcounter6h,
+    __read_mhpmcounter6,
+    __write_mhpmcounter6
+);
+reg!(
+    0xB07,
+    mhpmcounter7,
+    mhpmcounter7h,
+    __read_mhpmcounter7,
+    __write_mhpmcounter7
+);
+reg!(
+    0xB08,
+    mhpmcounter8,
+    mhpmcounter8h,
+    __read_mhpmcounter8,
+    __write_mhpmcounter8
+);
+reg!(
+    0xB09,
+    mhpmcounter9,
+    mhpmcounter9h,
+    __read_mhpmcounter9,
+    __write_mhpmcounter9
+);
+reg!(
+    0xB0A,
+    mhpmcounter10,
+    mhpmcounter10h,
+    __read_mhpmcounter10,
+    __write_mhpmcounter10
+);
+reg!(
+    0xB0B,
+    mhpmcounter11,
+    mhpmcounter11h,
+    __read_mhpmcounter11,
+    __write_mhpmcounter11
+);
+reg!(
+    0xB0C,
+    mhpmcounter12,
+    mhpmcounter12h,
+    __read_mhpmcounter12,
+    __write_mhpmcounter12
+);
+reg!(
+    0xB0D,
+    mhpmcounter13,
+    mhpmcounter13h,
+    __read_mhpmcounter13,
+    __write_mhpmcounter13
+);
+reg!(
+    0xB0E,
+    mhpmcounter14,
+    mhpmcounter14h,
+    __read_mhpmcounter14,
+    __write_mhpmcounter14
+);
+reg!(
+    0xB0F,
+    mhpmcounter15,
+    mhpmcounter15h,
+    __read_mhpmcounter15,
+    __write_mhpmcounter15
+);
+reg!(
+    0xB10,
+    mhpmcounter16,
+    mhpmcounter16h,
+    __read_mhpmcounter16,
+    __write_mhpmcounter16
+);
+reg!(
+    0xB11,
+    mhpmcounter17,
+    mhpmcounter17h,
+    __read_mhpmcounter17,
+    __write_mhpmcounter17
+);
+reg!(
+    0xB12,
+    mhpmcounter18,
+    mhpmcounter18h,
+    __read_mhpmcounter18,
+    __write_mhpmcounter18
+);
+reg!(
+    0xB13,
+    mhpmcounter19,
+    mhpmcounter19h,
+    __read_mhpmcounter19,
+    __write_mhpmcounter19
+);
+reg!(
+    0xB14,
+    mhpmcounter20,
+    mhpmcounter20h,
+    __read_mhpmcounter20,
+    __write_mhpmcounter20
+);
+reg!(
+    0xB15,
+    mhpmcounter21,
+    mhpmcounter21h,
+    __read_mhpmcounter21,
+    __write_mhpmcounter21
+);
+reg!(
+    0xB16,
+    mhpmcounter22,
+    mhpmcounter22h,
+    __read_mhpmcounter22,
+    __write_mhpmcounter22
+);
+reg!(
+    0xB17,
+    mhpmcounter23,
+    mhpmcounter23h,
+    __read_mhpmcounter23,
+    __write_mhpmcounter23
+);
+reg!(
+    0xB18,
+    mhpmcounter24,
+    mhpmcounter24h,
+    __read_mhpmcounter24,
+    __write_mhpmcounter24
+);
+reg!(
+    0xB19,
+    mhpmcounter25,
+    mhpmcounter25h,
+    __read_mhpmcounter25,
+    __write_mhpmcounter25
+);
+reg!(
+    0xB1A,
+    mhpmcounter26,
+    mhpmcounter26h,
+    __read_mhpmcounter26,
+    __write_mhpmcounter26
+);
+reg!(
+    0xB1B,
+    mhpmcounter27,
+    mhpmcounter27h,
+    __read_mhpmcounter27,
+    __write_mhpmcounter27
+);
+reg!(
+    0xB1C,
+    mhpmcounter28,
+    mhpmcounter28h,
+    __read_mhpmcounter28,
+    __write_mhpmcounter28
+);
+reg!(
+    0xB1D,
+    mhpmcounter29,
+    mhpmcounter29h,
+    __read_mhpmcounter29,
+    __write_mhpmcounter29
+);
+reg!(
+    0xB1E,
+    mhpmcounter30,
+    mhpmcounter30h,
+    __read_mhpmcounter30,
+    __write_mhpmcounter30
+);
+reg!(
+    0xB1F,
+    mhpmcounter31,
+    mhpmcounter31h,
+    __read_mhpmcounter31,
+    __write_mhpmcounter31
+);
 
-regh!(0xB83, mhpmcounter3h,  __read_mhpmcounter3h,  __write_mhpmcounter3h);
-regh!(0xB84, mhpmcounter4h,  __read_mhpmcounter4h,  __write_mhpmcounter4h);
-regh!(0xB85, mhpmcounter5h,  __read_mhpmcounter5h,  __write_mhpmcounter5h);
-regh!(0xB86, mhpmcounter6h,  __read_mhpmcounter6h,  __write_mhpmcounter6h);
-regh!(0xB87, mhpmcounter7h,  __read_mhpmcounter7h,  __write_mhpmcounter7h);
-regh!(0xB88, mhpmcounter8h,  __read_mhpmcounter8h,  __write_mhpmcounter8h);
-regh!(0xB89, mhpmcounter9h,  __read_mhpmcounter9h,  __write_mhpmcounter9h);
-regh!(0xB8A, mhpmcounter10h, __read_mhpmcounter10h, __write_mhpmcounter10h);
-regh!(0xB8B, mhpmcounter11h, __read_mhpmcounter11h, __write_mhpmcounter11h);
-regh!(0xB8C, mhpmcounter12h, __read_mhpmcounter12h, __write_mhpmcounter12h);
-regh!(0xB8D, mhpmcounter13h, __read_mhpmcounter13h, __write_mhpmcounter13h);
-regh!(0xB8E, mhpmcounter14h, __read_mhpmcounter14h, __write_mhpmcounter14h);
-regh!(0xB8F, mhpmcounter15h, __read_mhpmcounter15h, __write_mhpmcounter15h);
-regh!(0xB90, mhpmcounter16h, __read_mhpmcounter16h, __write_mhpmcounter16h);
-regh!(0xB91, mhpmcounter17h, __read_mhpmcounter17h, __write_mhpmcounter17h);
-regh!(0xB92, mhpmcounter18h, __read_mhpmcounter18h, __write_mhpmcounter18h);
-regh!(0xB93, mhpmcounter19h, __read_mhpmcounter19h, __write_mhpmcounter19h);
-regh!(0xB94, mhpmcounter20h, __read_mhpmcounter20h, __write_mhpmcounter20h);
-regh!(0xB95, mhpmcounter21h, __read_mhpmcounter21h, __write_mhpmcounter21h);
-regh!(0xB96, mhpmcounter22h, __read_mhpmcounter22h, __write_mhpmcounter22h);
-regh!(0xB97, mhpmcounter23h, __read_mhpmcounter23h, __write_mhpmcounter23h);
-regh!(0xB98, mhpmcounter24h, __read_mhpmcounter24h, __write_mhpmcounter24h);
-regh!(0xB99, mhpmcounter25h, __read_mhpmcounter25h, __write_mhpmcounter25h);
-regh!(0xB9A, mhpmcounter26h, __read_mhpmcounter26h, __write_mhpmcounter26h);
-regh!(0xB9B, mhpmcounter27h, __read_mhpmcounter27h, __write_mhpmcounter27h);
-regh!(0xB9C, mhpmcounter28h, __read_mhpmcounter28h, __write_mhpmcounter28h);
-regh!(0xB9D, mhpmcounter29h, __read_mhpmcounter29h, __write_mhpmcounter29h);
-regh!(0xB9E, mhpmcounter30h, __read_mhpmcounter30h, __write_mhpmcounter30h);
-regh!(0xB9F, mhpmcounter31h, __read_mhpmcounter31h, __write_mhpmcounter31h);
+regh!(
+    0xB83,
+    mhpmcounter3h,
+    __read_mhpmcounter3h,
+    __write_mhpmcounter3h
+);
+regh!(
+    0xB84,
+    mhpmcounter4h,
+    __read_mhpmcounter4h,
+    __write_mhpmcounter4h
+);
+regh!(
+    0xB85,
+    mhpmcounter5h,
+    __read_mhpmcounter5h,
+    __write_mhpmcounter5h
+);
+regh!(
+    0xB86,
+    mhpmcounter6h,
+    __read_mhpmcounter6h,
+    __write_mhpmcounter6h
+);
+regh!(
+    0xB87,
+    mhpmcounter7h,
+    __read_mhpmcounter7h,
+    __write_mhpmcounter7h
+);
+regh!(
+    0xB88,
+    mhpmcounter8h,
+    __read_mhpmcounter8h,
+    __write_mhpmcounter8h
+);
+regh!(
+    0xB89,
+    mhpmcounter9h,
+    __read_mhpmcounter9h,
+    __write_mhpmcounter9h
+);
+regh!(
+    0xB8A,
+    mhpmcounter10h,
+    __read_mhpmcounter10h,
+    __write_mhpmcounter10h
+);
+regh!(
+    0xB8B,
+    mhpmcounter11h,
+    __read_mhpmcounter11h,
+    __write_mhpmcounter11h
+);
+regh!(
+    0xB8C,
+    mhpmcounter12h,
+    __read_mhpmcounter12h,
+    __write_mhpmcounter12h
+);
+regh!(
+    0xB8D,
+    mhpmcounter13h,
+    __read_mhpmcounter13h,
+    __write_mhpmcounter13h
+);
+regh!(
+    0xB8E,
+    mhpmcounter14h,
+    __read_mhpmcounter14h,
+    __write_mhpmcounter14h
+);
+regh!(
+    0xB8F,
+    mhpmcounter15h,
+    __read_mhpmcounter15h,
+    __write_mhpmcounter15h
+);
+regh!(
+    0xB90,
+    mhpmcounter16h,
+    __read_mhpmcounter16h,
+    __write_mhpmcounter16h
+);
+regh!(
+    0xB91,
+    mhpmcounter17h,
+    __read_mhpmcounter17h,
+    __write_mhpmcounter17h
+);
+regh!(
+    0xB92,
+    mhpmcounter18h,
+    __read_mhpmcounter18h,
+    __write_mhpmcounter18h
+);
+regh!(
+    0xB93,
+    mhpmcounter19h,
+    __read_mhpmcounter19h,
+    __write_mhpmcounter19h
+);
+regh!(
+    0xB94,
+    mhpmcounter20h,
+    __read_mhpmcounter20h,
+    __write_mhpmcounter20h
+);
+regh!(
+    0xB95,
+    mhpmcounter21h,
+    __read_mhpmcounter21h,
+    __write_mhpmcounter21h
+);
+regh!(
+    0xB96,
+    mhpmcounter22h,
+    __read_mhpmcounter22h,
+    __write_mhpmcounter22h
+);
+regh!(
+    0xB97,
+    mhpmcounter23h,
+    __read_mhpmcounter23h,
+    __write_mhpmcounter23h
+);
+regh!(
+    0xB98,
+    mhpmcounter24h,
+    __read_mhpmcounter24h,
+    __write_mhpmcounter24h
+);
+regh!(
+    0xB99,
+    mhpmcounter25h,
+    __read_mhpmcounter25h,
+    __write_mhpmcounter25h
+);
+regh!(
+    0xB9A,
+    mhpmcounter26h,
+    __read_mhpmcounter26h,
+    __write_mhpmcounter26h
+);
+regh!(
+    0xB9B,
+    mhpmcounter27h,
+    __read_mhpmcounter27h,
+    __write_mhpmcounter27h
+);
+regh!(
+    0xB9C,
+    mhpmcounter28h,
+    __read_mhpmcounter28h,
+    __write_mhpmcounter28h
+);
+regh!(
+    0xB9D,
+    mhpmcounter29h,
+    __read_mhpmcounter29h,
+    __write_mhpmcounter29h
+);
+regh!(
+    0xB9E,
+    mhpmcounter30h,
+    __read_mhpmcounter30h,
+    __write_mhpmcounter30h
+);
+regh!(
+    0xB9F,
+    mhpmcounter31h,
+    __read_mhpmcounter31h,
+    __write_mhpmcounter31h
+);

+ 9 - 8
src/register/mod.rs

@@ -30,19 +30,21 @@ pub mod utval;
 pub mod fcsr;
 
 // User Counter/Timers
-// TODO: cycle[h], instret[h]
-pub mod time;
-#[rustfmt::skip] // long macro use
+pub mod cycle;
+pub mod cycleh;
 mod hpmcounterx;
 pub use self::hpmcounterx::*;
+pub mod instret;
+pub mod instreth;
+pub mod time;
 pub mod timeh;
 
 // Supervisor Trap Setup
 // TODO: sedeleg, sideleg
+pub mod scounteren;
 pub mod sie;
 pub mod sstatus;
 pub mod stvec;
-// TODO: scounteren
 
 // Supervisor Trap Handling
 pub mod scause;
@@ -61,13 +63,13 @@ pub mod mimpid;
 pub mod mvendorid;
 
 // Machine Trap Setup
+pub mod mcounteren;
 pub mod medeleg;
 pub mod mideleg;
 pub mod mie;
 pub mod misa;
 pub mod mstatus;
 pub mod mtvec;
-// TODO: mcounteren
 
 // Machine Trap Handling
 pub mod mcause;
@@ -84,11 +86,10 @@ pub use self::pmpaddrx::*;
 
 // Machine Counter/Timers
 pub mod mcycle;
-#[rustfmt::skip] // long macro use
+pub mod mcycleh;
 mod mhpmcounterx;
-pub mod minstret;
 pub use self::mhpmcounterx::*;
-pub mod mcycleh;
+pub mod minstret;
 pub mod minstreth;
 
 // Machine Counter Setup

+ 65 - 0
src/register/scounteren.rs

@@ -0,0 +1,65 @@
+//! scounteren register
+
+use bit_field::BitField;
+
+/// scounteren register
+#[derive(Clone, Copy, Debug)]
+pub struct Scounteren {
+    bits: usize,
+}
+
+impl Scounteren {
+    /// User "cycle[h]" Enable
+    #[inline]
+    pub fn cy(&self) -> bool {
+        self.bits.get_bit(0)
+    }
+
+    /// User "time[h]" Enable
+    #[inline]
+    pub fn tm(&self) -> bool {
+        self.bits.get_bit(1)
+    }
+
+    /// User "instret[h]" Enable
+    #[inline]
+    pub fn ir(&self) -> bool {
+        self.bits.get_bit(2)
+    }
+
+    /// User "hpm[x]" Enable (bits 3-31)
+    #[inline]
+    pub fn hpm(&self, index: usize) -> bool {
+        assert!(3 <= index && index < 32);
+        self.bits.get_bit(index)
+    }
+}
+
+read_csr_as!(Scounteren, 0x106, __read_scounteren);
+write_csr!(0x106, __write_scounteren);
+set!(0x106, __set_scounteren);
+clear!(0x106, __clear_scounteren);
+
+set_clear_csr!(
+/// User cycle Enable
+    , set_cy, clear_cy, 1 << 0);
+
+set_clear_csr!(
+/// User time Enable
+    , set_tm, clear_tm, 1 << 1);
+
+set_clear_csr!(
+/// User instret Enable
+    , set_ir, clear_ir, 1 << 2);
+
+#[inline]
+pub unsafe fn set_hpm(index: usize) {
+    assert!(3 <= index && index < 32);
+    _set(1 << index);
+}
+
+#[inline]
+pub unsafe fn clear_hpm(index: usize) {
+    assert!(3 <= index && index < 32);
+    _clear(1 << index);
+}