diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core.c | 85 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 3 | ||||
| -rw-r--r-- | src/emu/x64run0f.c | 2 | ||||
| -rw-r--r-- | src/include/debug.h | 1 | ||||
| -rw-r--r-- | src/include/my_cpuid.h | 1 | ||||
| -rw-r--r-- | src/tools/my_cpuid.c | 7 | ||||
| -rw-r--r-- | src/tools/rcfile.c | 4 |
7 files changed, 66 insertions, 37 deletions
diff --git a/src/core.c b/src/core.c index 2c583226..9d6b4042 100644 --- a/src/core.c +++ b/src/core.c @@ -65,6 +65,7 @@ int box64_mmap32 = 0; #endif int box64_ignoreint3 = 0; int box64_rdtsc = 0; +int box64_rdtsc_1ghz = 0; uint8_t box64_rdtsc_shift = 0; #ifdef DYNAREC int box64_dynarec = 1; @@ -504,6 +505,45 @@ HWCAP2_ECV } #endif +void computeRDTSC() +{ + int hardware = 0; + box64_rdtsc_shift = 0; + #if defined(ARM64) || defined(RV64) + hardware = 1; + box64_rdtsc = 0; // allow hardxare counter + #else + box64_rdtsc = 1; + printf_log(LOG_INFO, "Will use time-based emulation for rdtsc, even if hardware counter are available\n"); + #endif + uint64_t freq = ReadTSCFrequency(NULL); + if(freq<(box64_rdtsc_1ghz)?1000000000LL:1000000) { + box64_rdtsc = 1; + if(hardware) printf_log(LOG_INFO, "Hardware counter to slow (%d kHz), not using it\n", freq/1000); + hardware = 0; + freq = ReadTSCFrequency(NULL); + } + uint64_t efreq = freq; + while(efreq<2000000000) { // minium 2GHz + ++box64_rdtsc_shift; + efreq = freq<<box64_rdtsc_shift; + } + printf_log(LOG_INFO, "Will use %s counter measured at ", box64_rdtsc?"Software":"Hardware"); + int ghz = freq>=1000000000LL; + if(ghz) freq/=100000000LL; else freq/=100000; + if(ghz) printf_log(LOG_INFO, "%d.%d GHz", freq/10, freq%10); + if(!ghz && (freq>=1000)) printf_log(LOG_INFO, "%d MHz", freq/10); + if(!ghz && (freq<1000)) printf_log(LOG_INFO, "%d.%d MHz", freq/10, freq%10); + if(box64_rdtsc_shift) { + printf_log(LOG_INFO, " emulating "); + ghz = efreq>=1000000000LL; + if(ghz) efreq/=100000000LL; else efreq/=100000; + if(ghz) printf_log(LOG_INFO, "%d.%d GHz", efreq/10, efreq%10); + if(!ghz && (efreq>=1000)) printf_log(LOG_INFO, "%d MHz", efreq/10); + if(!ghz && (efreq<1000)) printf_log(LOG_INFO, "%d.%d MHz", efreq/10, efreq%10); + } + printf_log(LOG_INFO, "\n"); +} EXPORTDYN void LoadLogEnv() @@ -1005,6 +1045,15 @@ void LoadLogEnv() printf_log(LOG_INFO, "Will expose AVX2 capabilities\n"); } } + p = getenv("BOX64_RDTSC_1GHZ"); + if(p) { + if(strlen(p)==1) { + if(p[0]>='0' && p[0]<='0'+1) + box64_rdtsc_1ghz = p[0]-'0'; + } + if(!box64_rdtsc_1ghz) + printf_log(LOG_INFO, "Will require a hardware counter of 1GHz minimum or will fallback to software\n"); + } p = getenv("BOX64_FIX_64BIT_INODES"); if(p) { if(strlen(p)==1) { @@ -1087,41 +1136,7 @@ void LoadLogEnv() const char* cpuname = getCpuName(); printf_log(LOG_INFO, " PageSize:%zd Running on %s with %d Cores\n", box64_pagesize, cpuname, ncpu); // grab and calibrate hardware counter - int hardware = 0; - #if defined(ARM64) || defined(RV64) - hardware = 1; - box64_rdtsc = 0; // allow hardxare counter - #else - box64_rdtsc = 1; - printf_log(LOG_INFO, "Will use time-based emulation for rdtsc, even if hardware counter are available\n"); - #endif - uint64_t freq = ReadTSCFrequency(NULL); - if(freq<1000000) { - box64_rdtsc = 1; - if(hardware) printf_log(LOG_INFO, "Hardware counter to slow (%d kHz), not using it\n", freq/1000); - hardware = 0; - freq = ReadTSCFrequency(NULL); - } - uint64_t efreq = freq; - while(efreq<2000000000) { // minium 2GHz - ++box64_rdtsc_shift; - efreq = freq<<box64_rdtsc_shift; - } - printf_log(LOG_INFO, "Will use %s counter measured at ", box64_rdtsc?"Software":"Hardware"); - int ghz = freq>=1000000000LL; - if(ghz) freq/=100000000LL; else freq/=100000; - if(ghz) printf_log(LOG_INFO, "%d.%d GHz", freq/10, freq%10); - if(!ghz && (freq>=1000)) printf_log(LOG_INFO, "%d MHz", freq/10); - if(!ghz && (freq<1000)) printf_log(LOG_INFO, "%d.%d MHz", freq/10, freq%10); - if(box64_rdtsc_shift) { - printf_log(LOG_INFO, " emulating "); - ghz = efreq>=1000000000LL; - if(ghz) efreq/=100000000LL; else efreq/=100000; - if(ghz) printf_log(LOG_INFO, "%d.%d GHz", efreq/10, efreq%10); - if(!ghz && (efreq>=1000)) printf_log(LOG_INFO, "%d MHz", efreq/10); - if(!ghz && (efreq<1000)) printf_log(LOG_INFO, "%d.%d MHz", efreq/10, efreq%10); - } - printf_log(LOG_INFO, "\n"); + computeRDTSC(); } EXPORTDYN diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 596c9fd1..3fe4d540 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -101,7 +101,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } LSRx(xRDX, x1, 32); MOVw_REG(xRAX, x1); // wipe upper part - MOVw_REG(xRCX, xZR); // IA32_TSC, 0 for now + CALL_(helper_getcpu, x1, x3); + MOVw_REG(xRCX, x1); // IA32_TSC, 0 for now break; default: DEFAULT; diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c index 8fc5e645..2a2c78cb 100644 --- a/src/emu/x64run0f.c +++ b/src/emu/x64run0f.c @@ -118,7 +118,7 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) tmp64u<<=box64_rdtsc_shift; R_RAX = tmp64u & 0xffffffff; R_RDX = tmp64u >> 32; - R_RCX = 0; // should be low of IA32_TSC + R_RCX = helper_getcpu(emu); #ifdef TEST_INTERPRETER test->notest = 1; #endif diff --git a/src/include/debug.h b/src/include/debug.h index be48b59e..4af3b0cb 100644 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -14,6 +14,7 @@ extern int box64_maxcpu; extern int box64_mmap32; extern int box64_ignoreint3; extern int box64_rdtsc; +extern int box64_rdtsc_1ghz; extern uint8_t box64_rdtsc_shift; #ifdef DYNAREC extern int box64_dynarec_dump; diff --git a/src/include/my_cpuid.h b/src/include/my_cpuid.h index 53792ea0..a8c4dcec 100644 --- a/src/include/my_cpuid.h +++ b/src/include/my_cpuid.h @@ -4,5 +4,6 @@ typedef struct x64emu_s x64emu_t; void my_cpuid(x64emu_t* emu, uint32_t tmp32u); +uint32_t helper_getcpu(x64emu_t* emu); // get the numa/cpu id actually running #endif //__MY_CPUID_H__ \ No newline at end of file diff --git a/src/tools/my_cpuid.c b/src/tools/my_cpuid.c index 06d810aa..00859cc8 100644 --- a/src/tools/my_cpuid.c +++ b/src/tools/my_cpuid.c @@ -468,3 +468,10 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) R_EDX = 0; } } + +uint32_t helper_getcpu(x64emu_t* emu) { + uint32_t cpu, node; + if(!getcpu(&cpu, &node)) + return (node&0xff)<<12 | (cpu&0xff); + return 0; +} \ No newline at end of file diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index 2b45dd06..cd1316f4 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -99,6 +99,7 @@ ENTRYBOOL(BOX64_CRASHHANDLER, box64_dummy_crashhandler) \ ENTRYBOOL(BOX64_NOPULSE, box64_nopulse) \ ENTRYBOOL(BOX64_NOGTK, box64_nogtk) \ ENTRYBOOL(BOX64_NOVULKAN, box64_novulkan) \ +ENTRYBOOL(BOX64_RDTSC_1GHZ, box64_rdtsc_1ghz) \ ENTRYBOOL(BOX64_SSE42, box64_sse42) \ ENTRYINT(BOX64_AVX, new_avx, 0, 2, 2) \ ENTRYBOOL(BOX64_FUTEX_WAITV, box64_futex_waitv) \ @@ -489,6 +490,7 @@ extern char* ftrace_name; void openFTrace(const char* newtrace); void addNewEnvVar(const char* s); void AddNewLibs(const char* libs); +void computeRDTSC(); #ifdef DYNAREC void GatherDynarecExtensions(); #endif @@ -568,6 +570,8 @@ void ApplyParams(const char* name) box64_avx = 1; box64_avx2 = 1; } } + if(param->is_box64_rdtsc_1ghz_present) + computeRDTSC(); #ifdef DYNAREC if(param->is_box64_dynarec_jvm_present && !param->is_box64_jvm_present) box64_jvm = box64_dynarec_jvm; |