4
0
Эх сурвалжийг харах

Implement hpmcounter*[h], mhpmcounter*[h], mhpmevent* CSRs

Vadim Kaushan 5 жил өмнө
parent
commit
f37ab221c8

+ 82 - 0
src/register/hpmcounterx.rs

@@ -0,0 +1,82 @@
+macro_rules! reg {
+    (
+        $addr:expr, $csrl:ident, $csrh:ident, $readf:ident, $writef:ident
+    ) => {
+        /// Performance-monitoring counter
+        pub mod $csrl {
+            read_csr_as_usize!($addr, $readf);
+            read_composite_csr!(super::$csrh::read(), read());
+        }
+    }
+}
+
+macro_rules! regh {
+    (
+        $addr:expr, $csrh:ident, $readf:ident, $writef:ident
+    ) => {
+        /// Upper 32 bits of performance-monitoring counter (RV32I only)
+        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);
+
+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);

+ 38 - 0
src/register/macros.rs

@@ -118,6 +118,32 @@ macro_rules! write_csr {
     };
 }
 
+macro_rules! write_csr_rv32 {
+    ($csr_number:expr, $asm_fn: ident) => {
+        /// Writes the CSR
+        #[inline]
+        #[allow(unused_variables)]
+        unsafe fn _write(bits: usize) {
+            match () {
+                #[cfg(all(riscv32, feature = "inline-asm"))]
+                () => asm!("csrrw x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"),
+
+                #[cfg(all(riscv32, not(feature = "inline-asm")))]
+                () => {
+                    extern "C" {
+                        fn $asm_fn(bits: usize);
+                    }
+
+                    $asm_fn(bits);
+                }
+
+                #[cfg(not(riscv32))]
+                () => unimplemented!(),
+            }
+        }
+    };
+}
+
 macro_rules! write_csr_as_usize {
     ($csr_number:expr, $asm_fn: ident) => {
         write_csr!($csr_number, $asm_fn);
@@ -130,6 +156,18 @@ macro_rules! write_csr_as_usize {
     };
 }
 
+macro_rules! write_csr_as_usize_rv32 {
+    ($csr_number:expr, $asm_fn: ident) => {
+        write_csr_rv32!($csr_number, $asm_fn);
+
+        /// Writes the CSR
+        #[inline]
+        pub fn write(bits: usize) {
+            unsafe{ _write(bits) }
+        }
+    };
+}
+
 macro_rules! set {
     ($csr_number:expr, $asm_fn: ident) => {
         /// Set the CSR

+ 84 - 0
src/register/mhpmcounterx.rs

@@ -0,0 +1,84 @@
+macro_rules! reg {
+    (
+        $addr:expr, $csrl:ident, $csrh:ident, $readf:ident, $writef:ident
+    ) => {
+        /// Machine performance-monitoring counter
+        pub mod $csrl {
+            read_csr_as_usize!($addr, $readf);
+            write_csr_as_usize!($addr, $writef);
+            read_composite_csr!(super::$csrh::read(), read());
+        }
+    }
+}
+
+macro_rules! regh {
+    (
+        $addr:expr, $csrh:ident, $readf:ident, $writef:ident
+    ) => {
+        /// Upper 32 bits of machine performance-monitoring counter (RV32I only)
+        pub mod $csrh {
+            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);
+
+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);

+ 41 - 0
src/register/mhpmeventx.rs

@@ -0,0 +1,41 @@
+macro_rules! reg {
+    (
+        $addr:expr, $csr:ident, $readf:ident, $writef:ident
+    ) => {
+        /// Machine performance-monitoring event selector
+        pub mod $csr {
+            read_csr_as_usize!($addr, $readf);
+            write_csr_as_usize!($addr, $writef);
+        }
+    }
+}
+
+reg!(0x323, mhpmevent3,  __read_mhpmevent3,  __write_mhpmevent3);
+reg!(0x324, mhpmevent4,  __read_mhpmevent4,  __write_mhpmevent4);
+reg!(0x325, mhpmevent5,  __read_mhpmevent5,  __write_mhpmevent5);
+reg!(0x326, mhpmevent6,  __read_mhpmevent6,  __write_mhpmevent6);
+reg!(0x327, mhpmevent7,  __read_mhpmevent7,  __write_mhpmevent7);
+reg!(0x328, mhpmevent8,  __read_mhpmevent8,  __write_mhpmevent8);
+reg!(0x329, mhpmevent9,  __read_mhpmevent9,  __write_mhpmevent9);
+reg!(0x32A, mhpmevent10, __read_mhpmevent10, __write_mhpmevent10);
+reg!(0x32B, mhpmevent11, __read_mhpmevent11, __write_mhpmevent11);
+reg!(0x32C, mhpmevent12, __read_mhpmevent12, __write_mhpmevent12);
+reg!(0x32D, mhpmevent13, __read_mhpmevent13, __write_mhpmevent13);
+reg!(0x32E, mhpmevent14, __read_mhpmevent14, __write_mhpmevent14);
+reg!(0x32F, mhpmevent15, __read_mhpmevent15, __write_mhpmevent15);
+reg!(0x330, mhpmevent16, __read_mhpmevent16, __write_mhpmevent16);
+reg!(0x331, mhpmevent17, __read_mhpmevent17, __write_mhpmevent17);
+reg!(0x332, mhpmevent18, __read_mhpmevent18, __write_mhpmevent18);
+reg!(0x333, mhpmevent19, __read_mhpmevent19, __write_mhpmevent19);
+reg!(0x334, mhpmevent20, __read_mhpmevent20, __write_mhpmevent20);
+reg!(0x335, mhpmevent21, __read_mhpmevent21, __write_mhpmevent21);
+reg!(0x336, mhpmevent22, __read_mhpmevent22, __write_mhpmevent22);
+reg!(0x337, mhpmevent23, __read_mhpmevent23, __write_mhpmevent23);
+reg!(0x338, mhpmevent24, __read_mhpmevent24, __write_mhpmevent24);
+reg!(0x339, mhpmevent25, __read_mhpmevent25, __write_mhpmevent25);
+reg!(0x33A, mhpmevent26, __read_mhpmevent26, __write_mhpmevent26);
+reg!(0x33B, mhpmevent27, __read_mhpmevent27, __write_mhpmevent27);
+reg!(0x33C, mhpmevent28, __read_mhpmevent28, __write_mhpmevent28);
+reg!(0x33D, mhpmevent29, __read_mhpmevent29, __write_mhpmevent29);
+reg!(0x33E, mhpmevent30, __read_mhpmevent30, __write_mhpmevent30);
+reg!(0x33F, mhpmevent31, __read_mhpmevent31, __write_mhpmevent31);

+ 8 - 4
src/register/mod.rs

@@ -25,8 +25,10 @@ pub mod fcsr;
 
 
 // User Counter/Timers
-// TODO: cycle[h], instret[h], hpmcounter*[h]
+// TODO: cycle[h], instret[h]
 pub mod time;
+mod hpmcounterx;
+pub use self::hpmcounterx::*;
 pub mod timeh;
 
 
@@ -79,13 +81,15 @@ pub mod mip;
 // Machine Counter/Timers
 pub mod mcycle;
 pub mod minstret;
-// TODO: mhpmcounter*
+mod mhpmcounterx;
+pub use self::mhpmcounterx::*;
 pub mod mcycleh;
 pub mod minstreth;
-// TODO: mhpmcounter*h
 
 
-// TODO: Machine Counter Setup
+// Machine Counter Setup
+mod mhpmeventx;
+pub use self::mhpmeventx::*;
 
 
 // TODO: Debug/Trace Registers (shared with Debug Mode)