diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-02-28 17:10:30 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-28 10:10:30 +0100 |
| commit | 6a4a58185e3f3d62aea51211e6a3d98dafe318b2 (patch) | |
| tree | 81ff10885d77863acfb55558ffbcf372e8c8fbc6 /src | |
| parent | 6cffabacb38499ca1b12269f7989fe0bb78418f0 (diff) | |
| download | box64-6a4a58185e3f3d62aea51211e6a3d98dafe318b2.tar.gz box64-6a4a58185e3f3d62aea51211e6a3d98dafe318b2.zip | |
[RV64_INTERP] Added TSC freq support (#1293)
* [RV64_INTERP] Added TSC freq support * Simplify
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64emu.c | 80 | ||||
| -rw-r--r-- | src/main.c | 2 | ||||
| -rw-r--r-- | src/tools/rcfile.c | 2 |
3 files changed, 67 insertions, 17 deletions
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index fc737242..18e997b3 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -579,21 +579,75 @@ void EmuCall(x64emu_t* emu, uintptr_t addr) } } +#if defined(RV64) +static size_t readBinarySizeFromFile(const char* fname) +{ + if (access(fname, R_OK) != 0) return -1; + FILE* fp = fopen(fname, "r"); + if (fp == NULL) return -1; + + char b[sizeof(uint64_t)] = { 0 }, tmp; + ssize_t n = fread(b, 1, sizeof(b), fp); + if (n <= 0) return -1; + + for (ssize_t i = 0; i < n / 2; i++) { + tmp = b[n - i - 1]; + b[n - i - 1] = b[i]; + b[i] = tmp; + } + return *(uint64_t*)b; +} + +static inline uint64_t readCycleCounter() +{ + uint64_t val; + asm volatile("rdtime %0" + : "=r"(val)); + return val; +} + +static inline uint64_t readFreq() +{ + static size_t val = -1; + if (val != -1) return val; + + val = readBinarySizeFromFile("/sys/firmware/devicetree/base/cpus/timebase-frequency"); + if (val != -1) return val; + + // fallback to rdtime + sleep + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 50000000; // 50 milliseconds + uint64_t cycles = readCycleCounter(); + nanosleep(&ts, NULL); + // round to MHz + val = (size_t)round(((double)(readCycleCounter() - cycles) * 20) / 1e6) * 1e6; + return (uint64_t)val; +} +#elif defined(ARM64) +static inline uint64_t readCycleCounter() +{ + uint64_t val; + asm volatile("mrs %0, cntvct_el0" + : "=r"(val)); + return val; +} +static inline uint64_t readFreq() +{ + uint64_t val; + asm volatile("mrs %0, cntfrq_el0" + : "=r"(val)); + return val; +} +#endif + uint64_t ReadTSC(x64emu_t* emu) { (void)emu; // Hardware counter, per architecture #if defined(ARM64) || defined(RV64) - if(!box64_rdtsc) { - uint64_t val; -#ifdef ARM64 - asm volatile("mrs %0, cntvct_el0" : "=r" (val)); -#else // RV64 - asm volatile("rdtime %0" : "=r" (val)); -#endif - return val; - } + if (!box64_rdtsc) return readCycleCounter(); #endif // fall back to gettime... #if !defined(NOGETCLOCK) @@ -611,12 +665,8 @@ uint64_t ReadTSCFrequency(x64emu_t* emu) { (void)emu; // Hardware counter, per architecture -#ifdef ARM64 - if(!box64_rdtsc) { - uint64_t val; - asm volatile("mrs %0, cntfrq_el0" : "=r" (val)); - return val; - } +#if defined(ARM64) || defined(RV64) + if (!box64_rdtsc) return readFreq(); #endif // fall back to get time #if !defined(NOGETCLOCK) diff --git a/src/main.c b/src/main.c index 8cecf8ac..14d86798 100644 --- a/src/main.c +++ b/src/main.c @@ -1007,7 +1007,7 @@ void LoadLogEnv() box64_rdtsc = p[0]-'0'; } if(box64_rdtsc==2) { - #if defined(ARM64) + #if defined(ARM64) || defined(RV64) box64_rdtsc = 0; // allow hardxare counter uint64_t freq = ReadTSCFrequency(NULL); printf_log(LOG_INFO, "Hardware counter measured at %d Mhz, ", freq/1000); diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index 9c44336c..9980e07b 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -577,7 +577,7 @@ void ApplyParams(const char* name) printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_BASH", param->bash); } if(param->is_box64_rdtsc_present && (box64_rdtsc==2)) { - #if defined(ARM64) + #if defined(ARM64) || defined(RV64) box64_rdtsc = 0; // allow hardxware counter uint64_t freq = ReadTSCFrequency(NULL); printf_log(LOG_INFO, "Applying RDTSC: Hardware counter measured at %d Mhz, ", freq/1000); |