diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-02-28 03:44:34 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-27 20:44:34 +0100 |
| commit | d658c47cd02823bee50adebf8580537031ef7026 (patch) | |
| tree | 13dde73cbf719499a32c874112b4b66fae587059 /src | |
| parent | 21b06ace43adb3bc8b88eea8d0e1db79110d4e9c (diff) | |
| download | box64-d658c47cd02823bee50adebf8580537031ef7026.tar.gz box64-d658c47cd02823bee50adebf8580537031ef7026.zip | |
[RV64_DYNAREC] Fixed RDTSC handling (#1291)
* [LIBWRAP] Fixed a typo in the clocksource wrapping * [RV64_DYNAREC] Added hardware timer support for RDTSC * [INTERP] Optmize RV64 ReadTSC using rdtime * [RV64_DYNAREC] Added 0F 01 F9 RDTSCP opcode * Fixed typo * Fixed another typo
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 60 | ||||
| -rw-r--r-- | src/emu/x64emu.c | 6 | ||||
| -rw-r--r-- | src/wrapped/wrappedlibc.c | 17 |
3 files changed, 63 insertions, 20 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 83ee96c9..8b9eb63c 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -61,19 +61,46 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni switch (opcode) { case 0x01: - INST_NAME("FAKE xgetbv"); - nextop = F8; - addr = fakeed(dyn, addr, ninst, nextop); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state - GETIP(ip); - STORE_XEMU_CALL(x3); - CALL(native_ud, -1); - LOAD_XEMU_CALL(); - jump_to_epilog(dyn, 0, xRIP, ninst); - *need_epilog = 0; - *ok = 0; - break; + // TODO:, /0 is SGDT. While 0F 01 D0 is XGETBV, etc... + nextop = F8; + if(MODREG) { + switch(nextop) { + case 0xD0: + INST_NAME("FAKE xgetbv"); + nextop = F8; + addr = fakeed(dyn, addr, ninst, nextop); + SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + GETIP(ip); + STORE_XEMU_CALL(x3); + CALL(native_ud, -1); + LOAD_XEMU_CALL(); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; + break; + case 0xF9: + INST_NAME("RDTSCP"); + NOTEST(x1); + if (box64_rdtsc) { + CALL(ReadTSC, x3); // will return the u64 in x3 + } else { + CSRRS(x3, xZR, 0xC01); // RDTIME + } + SRLI(xRDX, x3, 32); + AND(xRAX, x3, xMASK); // wipe upper part + MV(xRCX, xZR); // IA32_TSC, 0 for now + break; + default: + DEFAULT; + } + } else { + switch((nextop>>3)&7) { + default: + DEFAULT; + } + } + break; case 0x05: INST_NAME("SYSCALL"); NOTEST(x1); @@ -380,10 +407,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0x31: INST_NAME("RDTSC"); NOTEST(x1); - MESSAGE(LOG_DUMP, "Need Optimization\n"); - CALL(ReadTSC, x3); // will return the u64 in x3 + if (box64_rdtsc) { + CALL(ReadTSC, x3); // will return the u64 in x3 + } else { + CSRRS(x3, xZR, 0xC01); // RDTIME + } SRLI(xRDX, x3, 32); - AND(xRAX, x3, 32); // wipe upper part + AND(xRAX, x3, xMASK); // wipe upper part break; case 0x38: // SSE3 diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index 4d8bf629..fc737242 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -584,10 +584,14 @@ uint64_t ReadTSC(x64emu_t* emu) (void)emu; // Hardware counter, per architecture -#ifdef ARM64 +#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; } #endif diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 77d9ff45..c8f23d0c 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -1626,7 +1626,7 @@ void CreateCPUPresentFile(int fd) void CreateClocksourceFile(int fd) { size_t dummy; - write(fd, "tsc", strlen("tsc")); + write(fd, "tsc\n", strlen("tsc\n")); } #ifdef ANDROID @@ -1690,7 +1690,7 @@ EXPORT int32_t my_open(x64emu_t* emu, void* pathname, int32_t flags, uint32_t mo // special case to say tsc as current clocksource int tmp = shm_open(TMP_CLOCKSOURCE, O_RDWR | O_CREAT, S_IRWXU); if(tmp<0) return open(pathname, flags, mode); // error fallback - shm_unlink(TMP_CPUINFO); // remove the shm file, but it will still exist because it's currently in use + shm_unlink(TMP_CLOCKSOURCE); // remove the shm file, but it will still exist because it's currently in use CreateClocksourceFile(tmp); lseek(tmp, 0, SEEK_SET); return tmp; @@ -1782,6 +1782,15 @@ EXPORT int32_t my_open64(x64emu_t* emu, void* pathname, int32_t flags, uint32_t lseek(tmp, 0, SEEK_SET); return tmp; } + if(!strcmp((const char*)pathname, "/sys/bus/clocksource/devices/clocksource0/current_clocksource")) { + // special case to say tsc as current clocksource + int tmp = shm_open(TMP_CLOCKSOURCE, O_RDWR | O_CREAT, S_IRWXU); + if(tmp<0) return open64(pathname, flags, mode); // error fallback + shm_unlink(TMP_CLOCKSOURCE); // remove the shm file, but it will still exist because it's currently in use + CreateClocksourceFile(tmp); + lseek(tmp, 0, SEEK_SET); + return tmp; + } #endif return open64(pathname, flags, mode); } @@ -1817,10 +1826,10 @@ EXPORT FILE* my_fopen64(x64emu_t* emu, const char* path, const char* mode) return fdopen(tmp, mode); } if(strcmp(path, "/sys/bus/clocksource/devices/clocksource0/current_clocksource")==0) { - // special case for cpuinfo + // special case to say tsc as current clocksource int tmp = shm_open(TMP_CLOCKSOURCE, O_RDWR | O_CREAT, S_IRWXU); if(tmp<0) return fopen64(path, mode); // error fallback - shm_unlink(TMP_CPUINFO); // remove the shm file, but it will still exist because it's currently in use + shm_unlink(TMP_CLOCKSOURCE); // remove the shm file, but it will still exist because it's currently in use CreateClocksourceFile(tmp); lseek(tmp, 0, SEEK_SET); return fdopen(tmp, mode); |