aboutsummaryrefslogtreecommitdiff
path: root/pk/pk.h
diff options
context:
space:
mode:
authorLuís Marques <luismarques@lowrisc.org>2019-10-22 17:56:54 +0100
committerAndrew Waterman <andrew@sifive.com>2019-10-22 09:56:53 -0700
commit99d6d0a93f9c83b63343a00693d5085e3949fe1a (patch)
tree2be05e20bf3956c1578bd32055c6195117087b85 /pk/pk.h
parent78e61baf432bd2d796c5b1e0498af363967322f4 (diff)
downloadpk-99d6d0a93f9c83b63343a00693d5085e3949fe1a.zip
pk-99d6d0a93f9c83b63343a00693d5085e3949fe1a.tar.gz
pk-99d6d0a93f9c83b63343a00693d5085e3949fe1a.tar.bz2
Make performance counters always 64 bits wide (#178)
This prevents the counters from easily overflowing for a 32-bit pk.
Diffstat (limited to 'pk/pk.h')
-rw-r--r--pk/pk.h58
1 files changed, 58 insertions, 0 deletions
diff --git a/pk/pk.h b/pk/pk.h
index 1167f6e..a55ab6c 100644
--- a/pk/pk.h
+++ b/pk/pk.h
@@ -41,6 +41,64 @@ static inline int insn_len(long insn)
return (insn & 0x3) < 0x3 ? 2 : 4;
}
+#if __riscv_xlen == 32
+
+static inline uint64_t rdtime64()
+{
+ uint32_t time;
+ uint32_t timeh1;
+ uint32_t timeh2;
+
+ do
+ {
+ timeh1 = read_csr(timeh);
+ time = read_csr(time);
+ timeh2 = read_csr(timeh);
+ } while(timeh1 != timeh2);
+
+ return (((uint64_t) timeh1) << 32) | time;
+}
+
+static inline uint64_t rdcycle64()
+{
+ uint32_t cycle;
+ uint32_t cycleh1;
+ uint32_t cycleh2;
+
+ do
+ {
+ cycleh1 = read_csr(cycleh);
+ cycle = read_csr(cycle);
+ cycleh2 = read_csr(cycleh);
+ } while(cycleh1 != cycleh2);
+
+ return (((uint64_t) cycleh1) << 32) | cycle;
+}
+
+static inline uint64_t rdinstret64()
+{
+ uint32_t instret;
+ uint32_t instreth1;
+ uint32_t instreth2;
+
+ do
+ {
+ instreth1 = read_csr(instreth);
+ instret = read_csr(instret);
+ instreth2 = read_csr(instreth);
+ } while(instreth1 != instreth2);
+
+ return (((uint64_t) instreth1) << 32) | instret;
+}
+
+#else
+
+#define rdtime64 rdtime
+#define rdcycle64 rdcycle
+#define rdinstret64 rdinstret
+
+#endif
+
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
#ifdef __cplusplus