diff options
author | Luís Marques <luismarques@lowrisc.org> | 2019-10-22 17:56:54 +0100 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2019-10-22 09:56:53 -0700 |
commit | 99d6d0a93f9c83b63343a00693d5085e3949fe1a (patch) | |
tree | 2be05e20bf3956c1578bd32055c6195117087b85 /pk/pk.h | |
parent | 78e61baf432bd2d796c5b1e0498af363967322f4 (diff) | |
download | riscv-pk-99d6d0a93f9c83b63343a00693d5085e3949fe1a.zip riscv-pk-99d6d0a93f9c83b63343a00693d5085e3949fe1a.tar.gz riscv-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.h | 58 |
1 files changed, 58 insertions, 0 deletions
@@ -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 |